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
| Field | Type | Notes |
|---|---|---|
| to | string, required | Destination E.164 phone number. |
| from | string, required | Origin E.164 number. Must be a DID on your connected provider. |
| agent_config.prompt | string | System prompt that defines what the agent says and does. |
| agent_config.voice_id | string | Voice id from GET /v1/voices. |
| language | string, 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_number | string, nullable | E.164 number for live transfer mid-conversation. Requires the agent to have transfer capability enabled. |
| test_mode | boolean, default false | Dispatches against the test pool and does not deduct production credits. |
| webhook_endpoint_id | string, nullable | Deliver lifecycle events for this call to a specific endpoint. |
| metadata | object | Arbitrary 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
| Status | Meaning |
|---|---|
| 400 | Validation error — a required field is missing or malformed. |
| 401 | Unauthorized — missing, malformed, or revoked API key. |
| 402 | Insufficient credits — the balance cannot cover the hold for this call. Top up and retry. |
| 429 | Rate 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.