API reference

Outbound calls.

POST /v1/calls queues an outbound phone call and returns a session immediately. The call is dispatched asynchronously — the response tells you the call was accepted, not that it connected.

Dispatch a call

Three fields are required: to, from, and agent_config. Both numbers are E.164, and from must be a DID on your connected provider.

curl -X POST https://api.rexa.ai/v1/calls \
  -H "Authorization: Bearer vk_live_..." \
  -H "Idempotency-Key: 8f14e45f-ceea-467a-9c3b-1f2a0d4e77aa" \
  -H "Content-Type: application/json" \
  -d '{
    "to":   "+14155552671",
    "from": "+15555551000",
    "agent_config": {
      "prompt": "Confirm the appointment tomorrow at 3pm.",
      "voice_id": "<id from GET /v1/voices>"
    },
    "language": "en",
    "test_mode": true
  }'

A successful dispatch returns 202 Accepted with the session:

HTTP/1.1 202 Accepted

{
  "id": "019eb8c6-8515-7b97-9143-c947f2f175f2",
  "type": "phone_call",
  "status": "queued",
  "from_number": "+15555551000",
  "to_number": "+14155552671",
  "room_url": null,
  "duration_seconds": null,
  "language": "en",
  "end_reason": null,
  "created_at": "2026-08-08T14:31:02.881Z",
  "updated_at": "2026-08-08T14:31:02.881Z"
}

Request fields

FieldTypeNotes
tostring, requiredDestination E.164 phone number.
fromstring, requiredOrigin E.164 number. Must be a DID on your connected provider.
agent_config.promptstringSystem prompt that defines what the agent says and does.
agent_config.voice_idstringVoice id from GET /v1/voices.
languagestring, default "en"ISO 639-1 code, e.g. hi, es, ar. When it differs from English the worker translates prompt, hello and voicemail text before dispatch.
transfer_numberstring, nullableE.164 number for live transfer mid-conversation. Requires the agent to have transfer capability enabled.
test_modeboolean, default falseDispatches against the test pool and does not deduct production credits.
webhook_endpoint_idstring, nullableDeliver lifecycle events for this call to a specific endpoint.
metadataobjectArbitrary key/values echoed back on the session and webhook payloads.

Idempotency

Send an Idempotency-Key header on every dispatch. Retrying with the same key returns the original session instead of placing a second call. This matters more here than on a typical API: a duplicate request does not just write a duplicate row, it rings a real person twice.

Track the call to completion

The dispatch response is always status: "queued". Poll the session, or subscribe to webhooks and let the events come to you — which is the better choice at any volume.

curl https://api.rexa.ai/v1/sessions/019eb8c6-8515-7b97-9143-c947f2f175f2 \
  -H "Authorization: Bearer vk_live_..."

status is one of queued, dispatching, in_progress, completed, failed, no_answer, voicemail or expired. Note that completed means the call ended normally, not that it achieved your goal — read end_reason and your own outcome fields for that.

Errors

StatusMeaning
400Validation error — a required field is missing or malformed.
401Unauthorized — missing, malformed, or revoked API key.
402Insufficient credits — the balance cannot cover the hold for this call. Top up and retry.
429Rate limited — back off and retry.

Next

  • Quickstart — first call in five minutes.
  • WebRTC rooms — the same agent in a browser, no phone number.
  • Webhooks — receive lifecycle, transcript and outcome events.
  • Outbound calling — campaigns, retry rules and calling windows.