direction: "outbound": they appear in session history, they are stored and analyzed under the same per-agent settings as any other conversation, and they trigger the same webhooks plus one extra, phone_call.dial_finished, that reports how the dial attempt ended.
Phone numbers
Get a number that can place calls.
Webhooks
Get the dial outcome pushed to your backend.
Dynamic variables
Personalize the call with per-call values.
Place a call
1
Get a number that supports outbound
Any purchased number can place calls. An imported BYO number can too, once its termination is configured; the number object reports this as
supports_outbound. The number you dial from is the caller ID the callee sees.2
Publish your agent
Outbound calls run the agent’s published configuration, not the draft. Publish before dialing.
3
Create the phone call
201 as soon as the dial is dispatched:Request fields
The session’s time and timezone context resolves from the destination number when the agent has no fixed timezone configured, so “tomorrow morning” means the callee’s morning.
Retry safely with an Idempotency-Key
Outbound dials spend money and ring real phones, so put anIdempotency-Key header on every create. For 24 hours, repeating the same key with the same body returns the call already placed instead of dialing again. The same key with a different body is refused with 422 idempotency_key_reuse, and a retry that races an in-flight first attempt gets 409 idempotency_key_conflict; back off and retry the same request. If the create fails with an ambiguous network error, retry with the same key: you get the placed session back if the first attempt went through.
The dial outcome
Ringing is never billed; metering starts when the callee answers. A call that is never answered is not billed and not analyzed. You learn how the dial ended in either of two ways:- Push: subscribe to the
phone_call.dial_finishedwebhook. It fires exactly once per outbound call, whether or not anyone picked up, beforecall.ended. - Poll: read
GET /v1/agent/sessions/{session_id}untildial_statusis set.
On outbound sessions the attribution fields are person-centric:
caller_number is the human you dialed and dialed_number is your workspace number. Everything else about the session (transcript, recording, post-call analysis, call.ended and call.analyzed webhooks, hang-up via POST /v1/agent/sessions/{session_id}/end) works exactly as for inbound calls.
Allowed destinations
Calls from purchased numbers can reach US, Canada, and Japan numbers. Japanese destinations may keep the domestic trunk zero (+81080... is accepted and normalized to +8180...), and premium-rate segments (such as 0570 Navi Dial and 0990) are always refused. Calls from imported BYO numbers dial out through your own trunk, so the country allowlist does not apply; the destination only has to be valid E.164.
Numbers that live on the platform can never be dialed, so an agent cannot call another agent’s number.
Limits
Exceeding either returns
429 with a machine-readable reason (daily_limit_exceeded, concurrency_limit_exceeded). These are per-workspace defaults; contact support if you need more.
Errors
Unlike most Agents API errors, phone-call errors carry a machine-readablereason alongside the message:
502 and 503 follow the general guidance: retrying is safe, especially with an Idempotency-Key.
Going further
Webhooks
The
phone_call.dial_finished payload in full.Transfers
Hand an answered call to a human; consult legs dial from the same number.
Bring your own SIP numbers
Place calls through your own trunk with your number as caller ID.
Conversation history
Transcripts, recordings, and session listing filters.

