Skip to main content

Outbound Call Dispatch

The Outbound Call Dispatch API queues one or more outbound calls for a published voice agent. Dispatch is asynchronous: the API returns 202 Accepted immediately with a batch identifier, and you poll a status endpoint to track each call as it dials, completes, or fails.

When to Use This​

  • Place outbound calls programmatically from your backend, CRM, or scheduler.
  • Dial a list of numbers in one request and track them as a single batch.
  • Retry safely with an idempotency key so duplicate requests don't dispatch twice.

Prerequisites​

  • A published voice agent with an active outbound FROM number configured under Call Configuration → Outbound Settings. Drafts and unpublished agents cannot be dispatched.
  • An API Key with the Voice Agent scope. If the key uses a specific Agent Access list, the target agent_id must be on that list.

Authentication​

Every request must include the api-key header — see API Keys for how to generate and manage tokens.

api-key: sk_<your-secret>

A missing, invalid, disabled, expired, scope-mismatched, or agent-denied key fails with 401/403 and is recorded in Request Logs with a matching error code.

Create a dispatch​

POST /voice/outbound/dispatch

Headers​

HeaderRequiredDescription
api-keyYesYour API key secret (must have Voice Agent scope)
Content-TypeYesapplication/json
Idempotency-KeyNoFree-form string. Repeating the same key returns the original dispatch_id instead of creating a new batch. See Idempotency below.

Body​

FieldTypeRequiredDescription
agent_idstringYesUUID of the published voice agent to dispatch from
destination_phonenumberstring or array of stringsYesOne or more destination numbers in E.164 format (e.g., +14155551234). Up to 500 numbers per request by default.
agent_overridesobjectNoPer-batch overrides for the agent's saved configuration

Agent overrides​

Use agent_overrides to change agent behavior for a single dispatch. Any explicitly provided property overrides the existing agent setting. Each key is optional, send only the keys you want to change.

KeyTypeDescription
languagesarrayLanguages the agent can speak, as language codes (e.g., en, hi)
timezonestringIANA timezone used for the call (e.g., Asia/Calcutta)
greetingobjectFirst message and speaking behavior
llmobjectModel, provider, system instructions, and generation settings
voiceobjectVoice provider, voice ID, and speech generation settings
transcriberobjectSpeech-to-text model, provider, and transcription settings

Example request with overrides​

curl -X POST https://<your-dronahq-host>/voice/outbound/dispatch \
-H "api-key: sk_your-generated-secret-here" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "<voice-agent-uuid>",
"destination_phonenumber": ["+91XXXXXXX210"],
"agent_overrides": {
"languages": ["en"],
"timezone": "Asia/Calcutta",
"greeting": {
"firstMessage": "Hello! I am Parijit from GreatTrips, how may I help you today?",
"agentSpeaksFirst": true,
"speakingBehaviourType": "custom"
},
"llm": {
"model": "gpt-4o",
"provider": "openai",
"system_instructions": "<your system prompt>",
"promptCache": {
"enabled": true
},
"config": {
"temperature": 0.7,
"max_tokens": 4000,
"recursion_limit": 25
}
},
"voice": {
"model": "eleven_turbo_v2_5",
"voiceId": "inputyourvoiceid007",
"provider": "elevenlabs",
"generation_config": {
"speed": 1.1,
"style": 0.8,
"stability": 0.6,
"similarity_boost": 0.8,
"use_speaker_boost": true,
"apply_text_normalization": "auto",
"ambiance": {
"backgroundSound": "off",
"backgroundSoundUrl": null,
"backgroundSoundVolume": 0,
"backgroundNoisingEnabled": false
},
"chunkPlan": {
"enabled": false,
"bufferPlan": {
"type": "fixed",
"bufferSeconds": 0.1
},
"minCharacters": 30,
"punctuationBoundaries": [".", "!", "?", ",", ";", ":"]
},
"formatPlan": {
"enabled": false,
"replacements": [],
"numToDigitCutoff": 2
}
}
},
"transcriber": {
"model": "nova-3",
"provider": "deepgram",
"generation_config": {
"keyterm": [],
"numerals": false,
"profanityFilter": false,
"confidenceThreshold": 0.6,
"smartEndpointingEnabled": true,
"backgroundDenoisingEnabled": false
}
}
}
}'

greeting​

FieldTypeDescription
firstMessagestringWhat the agent says when the call connects
agentSpeaksFirstbooleanIf true, the agent speaks before the caller
speakingBehaviourTypestringHow the greeting is delivered (e.g., custom)

llm​

FieldTypeDescription
modelstringModel name (e.g., gpt-4o)
providerstringModel provider (e.g., openai)
system_instructionsstringThe agent's system prompt
promptCache.enabledbooleanEnables prompt caching
configobjecttemperature, max_tokens, and recursion_limit
FieldTypeDescription
modelstringText-to-speech model (e.g., eleven_turbo_v2_5)
providerstringVoice provider (e.g., elevenlabs)
voiceIdstringVoice identifier from the provider
generation_configobjectSpeech settings: speed, style, stability, similarity_boost, use_speaker_boost, apply_text_normalization, ambiance, chunkPlan, formatPlan
FieldTypeDescription
modelstringSpeech-to-text model (e.g., nova-3)
providerstringTranscription provider (e.g., deepgram)
generation_configobjectkeyterm, numerals, profanityFilter, confidenceThreshold, smartEndpointingEnabled, backgroundDenoisingEnabled

Response — 202 Accepted​

FieldTypeDescription
dispatch_idstringUUID for this batch; use it with the status endpoint below
acceptedintegerCount of numbers accepted into the batch
status_urlstringRelative URL to poll for batch status
{
"dispatch_id": "f0c1a3f2-9e1c-4b21-9b8b-5a9c0f0a1e3a",
"accepted": 2,
"status_url": "/voice/outbound/dispatch/f0c1a3f2-9e1c-4b21-9b8b-5a9c0f0a1e3a"
}

Get batch status​

GET /voice/outbound/dispatch/{dispatch_id}

Returns the current state of every call in the batch.

Headers​

HeaderRequiredDescription
api-keyYesSame key requirements as create — must have Voice Agent scope and access to the batch's agent_id

Example response — 200 OK​

{
"dispatch_id": "f0c1a3f2-9e1c-4b21-9b8b-5a9c0f0a1e3a",
"agent_id": "a1d3...",
"created_at": "2026-06-23T10:14:02Z",
"total": 2,
"queued": 0,
"dialing": 1,
"completed": 1,
"failed": 0,
"retrying": 0,
"calls": [
{
"index": 0,
"phone_number": "+14155551234",
"status": "completed",
"attempts": 1,
"error_code": null,
"error_message": null,
"started_at": "2026-06-23T10:14:05Z",
"completed_at": "2026-06-23T10:15:22Z"
},
{
"index": 1,
"phone_number": "+919876543210",
"status": "dialing",
"attempts": 1,
"error_code": null,
"error_message": null,
"started_at": "2026-06-23T10:14:05Z",
"completed_at": null
}
]
}

Call status values​

StatusMeaning
queuedWaiting in the dispatcher queue, not yet dialed
dialingProvider has been asked to place the call
completedCall connected and ended normally
failedCall failed permanently; error_code and error_message describe why
retryingCall failed with a retriable error and will be retried (subject to the retry budget)

Idempotency​

Send Idempotency-Key: <your-string> on the create request to make retries safe. If you re-send the same Idempotency-Key, the API returns the original batch's dispatch_id and accepted count instead of dispatching a second time.

Use any stable string your system can regenerate on retry — a campaign-batch ID, a job ID from your scheduler, or a UUID you store before the call.

Limits​

LimitDefaultNotes
Numbers per request500Requests exceeding this fail with 400.
Concurrent calls per worker2Beyond this, calls stay in queued until a slot frees.
Retry attempts per call3Only applies to retriable failures (see below).

Defaults are operator-configurable; check with your administrator if you need them tuned.

Errors​

API errors (entire request fails)​

HTTP statusCauseFix
400Too many numbers in one requestSplit into batches of ≤ 500
400Agent is not published, or has no outbound FROM numberPublish the agent and pick an outbound number in Call Configuration → Outbound Settings
400A number isn't valid E.164Use +<country><number>, digits only
401 / 403Auth failure on the API keySee the error-code chip in Request Logs (missing_token, invalid_token, disabled, expired, scope_denied, agent_denied)
404agent_id not found, or dispatch_id not found on the status endpointDouble-check the UUID; the batch may have aged out

Per-call error codes​

When a single call inside a batch fails, the call's error_code is one of:

CodeRetriable?Meaning
INVALID_NUMBERNoNumber was rejected by the carrier as malformed or unreachable
PROVIDER_REJECTEDNoTelephony provider refused to place the call (geo block, balance, etc.)
PROVIDER_UNAVAILABLEYesProvider was temporarily unreachable
NO_ANSWERNoCall rang out without being picked up
BUSYYesRecipient line was busy
AGENT_FAILED_TO_JOINYesThe voice agent didn't join the room in time
LIVEKIT_ERRORYesUnderlying LiveKit session failed
TIMEOUTYesOperation exceeded its time budget
INTERNAL_ERRORYesUnexpected failure inside DronaHQ

Retriable codes are attempted again automatically up to the retry budget; non-retriable codes terminate the call as failed immediately.