Call endpoints

GET /api/calls

Paginated calls, scoped to the active workspace. page (default 1), pageSize (default 50, max 200).

Parameter Type Filter

search

string

targetPhoneNumber, partial

campaignId

uuid

Exact campaign

agentId

uuid

AI agent

callerPhone

string

Source number, partial

contactName

string

Partial

disposition

string

Exact, e.g. Qualified_Lead

statuses

csv

Call statuses, e.g. ended,dialing

channelType

string

phone_call, web_call, nooks_call

hubspotSyncStatus

string

synced, failed, skipped

inVoicemail

yes/no/all

Voicemail detection

callScreeningDetected

boolean

aiSuspicionDetected

boolean

interestedInDailyPayments

boolean

meetsMonthlyThreshold

boolean

isDecisionMaker

boolean

callbackRequested

boolean

hasRecording

true

recordingUrl IS NOT NULL

dateFrom, dateTo

YYYY-MM-DD

createdAt, anchored to America/New_York

{
  "data": [
    {
      "id": "uuid",
      "campaign_id": "uuid",
      "campaign_name": "Campaign Name",
      "target_id": "uuid",
      "agent_id": "uuid",
      "ai_agent_id": "agent_xxx",
      "ai_agent_name": "Single Prompt Brian",
      "agent_version": 3,
      "target_phone_number": "+1234567890",
      "caller_phone": "+1987654321",
      "contact_name": "John Doe",
      "provider_call_id": "retell_call_id",
      "status": "ended",
      "duration_ms": 120000,
      "duration_sec": 120,
      "disposition": "Interested",
      "recording_url": "https://…",
      "transcript": "…",
      "in_voicemail": false,
      "call_screening_detected": false,
      "ai_suspicion_detected": false,
      "is_decision_maker": true,
      "callback_requested": false,
      "meets_monthly_threshold": true,
      "interested_in_daily_payments": false,
      "hubspot_sync_status": "synced",
      "analysis_saved": true,
      "score": null,
      "start_timestamp": "2026-01-15T12:30:00.000Z",
      "end_timestamp": "2026-01-15T12:32:00.000Z",
      "created_at": "2026-01-15T12:30:00.000Z",
      "updated_at": "2026-01-15T12:32:05.000Z"
    }
  ],
  "total": 1000,
  "page": 1,
  "pageSize": 50
}

Fields worth knowing:

Field Meaning

ai_agent_id, ai_agent_name

The Retell caller agent identifier and display name

agent_id

The AiAgent UUID — a different value from ai_agent_id

agent_version

Version number of the AiAgentVersion that spoke

analysis_saved

true when at least one CallAiAgentAnalysisResult exists

caller_phone

The outbound source number, masked in the UI where configured

score

Operator-set 1–10 rating, not the AI score

Timestamps are UTC; the UI renders them in Eastern Time.

GET /api/calls/{id}

A single call with every field plus campaign and target context.

PATCH /api/calls/{id}

Updates operator-editable fields — notes and score.

GET /api/calls/{id}/history

Other calls to the same target phone number across all campaigns, excluding the current call. When targetPhoneNumber is missing it falls back to the same target within the same campaign.

{
  "data": [
    {
      "id": "uuid",
      "campaign_id": "uuid",
      "campaign_name": "Campaign Name",
      "target_id": "uuid",
      "target_phone_number": "+1234567890",
      "status": "ended",
      "disposition": "Interested",
      "duration_seconds": 120,
      "score": null,
      "in_voicemail": false,
      "start_timestamp": "2026-01-01T00:00:00.000Z",
      "created_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "total": 2,
  "page": 1,
  "pageSize": 50
}

Grouping by phone number rather than by campaign is deliberate: an operator needs to know every time that number has been called, whoever called it.

POST /api/calls/{id}/analyze

Re-runs AI analysis for one call via CallAnalysisService.runAndSave. See Call analysis.

Batch re-analysis

GET /api/calls/batch-analyze

Preview count for the re-analyze dialog.

Parameters

campaign_id, status, date_from, date_to, hubspot_sync_status — all optional; all disables a filter.

Response

{ "count": 42 }

POST /api/calls/batch-analyze

Starts batchCallAnalysisWorkflow fire-and-forget and returns immediately.

{
  "campaign_id": "uuid-or-null",
  "status": "ended",
  "date_from": "2026-01-01",
  "date_to": "2026-01-31",
  "hubspot_sync_status": "synced"
}
{
  "message": "Batch call analysis workflow started",
  "filters": { "campaign_id": "uuid", "status": "ended", "date_from": "2026-01-01", "date_to": "2026-01-31", "hubspot_sync_status": "synced" }
}

The preview and the run share buildBatchAnalysisWhere, so the count cannot disagree with the set that is processed.