An outbound call can fail in two places: the API can refuse to create it, or the call is created and the dial fails. The first gives you an HTTP error from POST /v2/create-phone-call. The second gives you a call with call_status: "not_connected" and a disconnection_reason.
Checks before the dial#
POST /v2/create-phone-call runs these checks in order. The first one that fails decides the response.
| # | Check | Error |
|---|---|---|
| 1 | Per-IP and per-key rate limits | 429 |
| 2 | API key scope (calls), IP allowlist |
403 |
| 3 | Account state: overdue invoice, or verification needed | 402, error_code invoice_overdue or verification_needed |
| 4 | Credit balance above zero and monthly budget not reached | 402, error_code credit_exhausted or budget_reached |
| 5 | to_number is valid E.164 (unless ignore_e164_validation) |
400 to_number ... is not a valid E.164 number |
| 6 | Business verification approved, when the deployment requires it | 403 Business verification (KYC) is ... |
| 7 | from_number is a number in this workspace |
404 from_number ... is not a number in this workspace |
| 8 | custom_sip_headers are valid after rendering variables |
400 |
| 9 | Credit balance (again, just before dialling) | 402 Insufficient credit balance. Add credits to place calls. |
| 10 | Internal do-not-call list, when honor_internal_dnc is true |
400 ... is on the do-not-call list |
| 11 | to_number is in the number's allowed_outbound_country_list |
400 ... is not in allowed_outbound_country_list (AU, NZ) |
| 12 | An agent: override_agent_id, or the number's outbound agents |
400 Phone number ... has no outbound agent; set outbound_agents or pass override_agent_id |
| 13 | A free concurrency slot, leaving reserved inbound slots free | 429 |
| 14 | A CPS token for the number within 5 seconds | 429 |
idempotency_key deduplicates retries for 1 hour: the same key returns the original call, and a key still being processed returns 409.
Read the message in the error body. It names the field and value that failed.
Why a created call never connected#
After the checks pass, the call is created and dialled on the number's outbound trunk. The dial uses ring_duration_ms (default 30 seconds) as the ringing timeout. Failures map from the SIP response:
| SIP response | disconnection_reason |
Usual cause |
|---|---|---|
| 486, 600 | dial_busy |
The line is busy |
| 480, 408, 487, or timeout | dial_no_answer |
Nobody answered in time |
| 400, 404, 410, 484, 485, 604 | invalid_destination |
Wrong or incomplete number |
| 401, 403, 407 | telephony_provider_permission_denied |
Trunk credentials, or the carrier does not allow this destination or caller ID |
| 502, 503, 504 | telephony_provider_unavailable |
Carrier problem |
| 603 | user_declined |
The callee rejected |
| 608 | marked_as_spam |
The carrier or callee's network flagged the call |
| other | dial_failed |
See the SIP trace |
| no trunk | sip_routing_error |
The number has no outbound trunk |
Common fixes#
sip_routing_error#
The number has no outbound SIP trunk. Numbers bought through Tried are provisioned with one. For imported numbers, check the termination_uri and credentials. In a self-hosted deployment, the operator can set LIVEKIT_SIP_OUTBOUND_TRUNK_ID.
telephony_provider_permission_denied#
- Check
sip_trunk_auth_usernameandsip_trunk_auth_passwordon imported numbers. - Check that your carrier allows calls to the destination country.
- Check that the caller ID (
from_number) is a number your carrier lets you present.
marked_as_spam and low answer rates#
- Call during business hours. Batch calls have
call_time_windowfor this. - Keep volume per number reasonable; spread campaigns across numbers.
- Carrier attestation (STIR/SHAKEN) and branded caller ID registration are deployment steps that improve answer rates.
dial_no_answer#
Raise ring_duration_ms (5,000 to 300,000 ms) if calls ring out too soon. Use voicemail settings to handle machines that answer.
429 responses#
- Concurrency: raise the workspace limit or turn on burst. Reserved inbound slots are not available to outbound calls. See Limits and concurrency.
- CPS: set a higher
cps_limiton the number if your carrier allows it (defaults: 4 for Telnyx numbers, 10 for your own trunk), or spread calls across numbers.
Batch calls#
Batch dials go through the same checks, except that concurrency is managed by the batch: each tick dials only as many tasks as there are free slots minus the batch's reserved_concurrency. A dial refused for lack of credit is recorded as a not_connected call with no_valid_payment. Each dial attempt is billed $0.01.
Outbound and batch calls are also blocked while the account state is Verification Needed. See Business verification.
Read the SIP trace#
GET /v2/get-call-sip-trace/:call_id returns the livekit-sip log lines for the call when the operator has set TRIED_SIP_LOG_PATH. Look for the final response code to the INVITE.