Create Outbound Call

Beta
Place an outbound call from an agent to a phone number. LiveKit originates the SIP INVITE through the outbound trunk bound to the agent's workspace; the agent is dispatched into the call automatically. The response is returned as soon as LiveKit accepts the INVITE. Poll `GET /v1/agents/conversations/{conversation_id}` for status transitions: `pending` → `active` (answered) → `completed`. This is also how a Phone number whose brain is your own webhook dials out: when the caller ID resolves to a number carrying a relay binding, every turn on the call is answered by your endpoint instead of an LLM, and `call.started`'s reply is the opening line spoken to the callee. Everything else is unchanged - same gates, same conversation, same transcript, same recording. Pass the agent the webhook bind provisioned (it is returned on the number) and, for a workspace with several numbers, `caller_id_number`. Requires a Twilio or BYOC trunk. LiveKit-native numbers are inbound-only. International (non-NANP) destinations on a Speechify-billed number require a payment that has COLLECTED on the workspace - a subscription charge or a card top-up, with no invoice past due - and are otherwise refused with `402 funded_balance_required`; trial / granted credit and a card merely on file do not satisfy it, and the refusal message names which condition is missing. Domestic (`+1`) calls are unaffected, as are calls placed from a number you imported from your own carrier. If the payment status cannot be resolved the call is refused with a retriable `503`, never the 402.

Authentication

AuthorizationBearer

Enter your API key with the Bearer prefix, e.g. ‘Bearer sk_…’.

Headers

Speechify-VersionstringOptional
Idempotency-KeystringOptional<=255 characters
A client-generated key (an opaque string, max 255 chars) that makes a side-effect POST safe to retry: the server runs the operation exactly once and replays the first response (its status and body) for 24 hours. Reusing a key with a different request body, or while the first request is still in flight, returns `409 idempotency_conflict`. A replayed response carries the `Idempotent-Replayed: true` header.

Request

This endpoint expects an object.
agent_idstringRequired
ID of the agent that handles the answered call.
tostringRequired

Destination phone number in E.164 format (e.g. +12025559876).

caller_id_numberstringOptional

The number shown to the callee as caller ID, in E.164 format. Defaults to the first outbound-capable number in the workspace. Useful for multi-number campaigns where you want to rotate caller IDs.

languagestringOptional

Starts the call in one of the agent’s configured languages (the default language or an additional_languages entry, matched by primary subtag) - e.g. a batch campaign dialing a per-row locale. Omit for the agent’s default language; an unconfigured language is rejected with 400.

dtmf_prefixstringOptional

DTMF digits dialed automatically after the call is answered, before the agent begins speaking. Use this for IVR navigation (e.g. 1ww2 presses 1, waits two seconds, presses 2). w is a half-second pause; W is a one-second pause.

dynamic_variablesmap from strings to anyOptional

Per-call variable overrides merged on top of the agent’s stored defaults. Keys must not use the reserved system__ prefix. Useful for injecting per-call context (customer name, order ID) into the agent prompt.

ringing_timeout_msintegerOptional

How long to wait for the callee to answer before abandoning, in milliseconds. Defaults to 30000 (30s). Capped at 80000 (80s).

amdobjectOptional

Optional per-call override for the AMD routing config. When set, wholesale-replaces the agent’s stored AMD shape for this single call (PATCH-replace, not merge). Unlocks the batch-campaign pattern: one agent dialling many recipients with per-row tailored voicemail messages via the existing dynamic_variables substitution. Validation rules match the agent-update boundary.

Response headers

Speechify-Request-IdstringOptional
Unique identifier for this request, present on every response (2xx and non-2xx alike). If the caller sends a `Speechify-Request-Id` request header the server echoes it back (sanitized and length-capped) so one logical request can be traced end-to-end; otherwise the server generates a fresh value. Log it on every response and quote it in support requests - it is the stable handle that ties your observation to Speechify's server-side logs, and it matches the `request_id` field in the error envelope. The legacy alias `X-Request-ID` carries the same value and is still accepted on requests, until 2027-07-24. Prefer the un-prefixed name (RFC 6648).
RateLimit-Limit-Callsinteger

Active-call concurrency budget: the per-workspace cap on simultaneously-active voice calls (the voice analog of a token axis). Sent on successful call-start responses (web session, outbound call).

RateLimit-Remaining-Callsinteger

Active-call concurrency budget: free active-call slots after this call reserved one. 0 on a 429 that rejected for concurrency exhaustion (concurrency_limit_reached).

Response

The outbound call was accepted by LiveKit.
conversation_idstringformat: "^conv_[0-9a-hjkmnp-tv-z]{26}$"
ID of the conversation created for this call. Use to poll status.

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
403
Forbidden Error
404
Not Found Error
409
Conflict Error
502
Bad Gateway Error
503
Service Unavailable Error