Skip to main content

HTTP status codes

CodeMeaningWhen you see it
200OKSuccessful GET / action (stop, schedule, etc.)
201CreatedPOST /v2/agent, POST /batches — resource created
400Bad RequestInvalid or missing parameter — check message in the response body
401UnauthorizedMissing or invalid API key — add Authorization: Bearer <key>
403ForbiddenValid key but insufficient permissions
404Not FoundResource ID doesn’t exist or belongs to another account
429Too Many RequestsRate limit hit — back off and retry with exponential backoff
500Internal Server ErrorUnexpected server error — also returned when scheduled_at uses the Z suffix (use +00:00 instead)

Error response shape

All 4xx/5xx responses return JSON:
{
  "error": 1001,
  "message": "agent_id is required"
}
The error integer is an internal code; message is human-readable. The message field is the most useful for debugging.

Execution status enum

Returned in GET /executions/{id} and webhook payloads as the status field.
StatusTypeDescription
scheduledIntermediateCall is scheduled for a future time
queuedIntermediateCall accepted and waiting to dial
rescheduledIntermediateCall was rescheduled (e.g. due to guardrails)
initiatedIntermediateDialing has started
ringingIntermediateRecipient’s phone is ringing
in-progressIntermediateCall answered, conversation active
call-disconnectedSoft terminalLine dropped — data still finalizing; completed follows
completedTerminal ✓Call finished; all fields populated
no-answerTerminalRecipient didn’t pick up
busyTerminalLine was busy
failedTerminalTelephony provider error
canceledTerminalCall canceled before answer
stoppedTerminalManually stopped via API
errorTerminalInternal error
balance-lowTerminalInsufficient wallet balance to place call
call-disconnected is not the final state. conversation_duration, total_cost, recording_url, and extracted_data are null or 0 at this point. Wait for completed (or any other terminal status above) before reading those fields.

Polling pattern

TERMINAL = {"completed","no-answer","busy","failed","canceled","stopped","error","balance-low"}

while True:
    data = get_execution(execution_id)
    if data["status"] in TERMINAL:
        break   # safe to read all fields now
    time.sleep(5)

Batch status enum

Returned by GET /batches/{batch_id} as the status field.
StatusDescription
createdBatch created, not yet scheduled
scheduledScheduled and waiting for start time
runningCalls are actively being placed
completedAll calls finished
stoppedManually stopped
failedError prevented execution

Per-call status in a batch

Each execution inside GET /batches/{batch_id}/executions has an individual status from the execution enum above. The batch’s execution_status field gives a summary count: { "completed": 5, "no-answer": 2, "running": 3 }.

Scheduling errors

ScenarioHTTPMessage
scheduled_at uses Z suffix500Internal server error
scheduled_at < 2 minutes ahead400”Scheduled time should be atleast 2 minutes in the future”
Invalid ISO 8601 format400Parsing error
Fix: always use a numeric offset: 2026-06-23T18:30:00+00:00.