Skip to main content
Dial any allowed number from one of your workspace numbers and the agent takes the call the moment the callee picks up. Outbound calls are ordinary agent sessions with 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

The request returns 201 as soon as the dial is dispatched:
This endpoint requires an API key; there is no anonymous variant. See the API reference for the full schema.

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 an Idempotency-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_finished webhook. It fires exactly once per outbound call, whether or not anyone picked up, before call.ended.
  • Poll: read GET /v1/agent/sessions/{session_id} until dial_status is set.
Two session fields carry the outcome: 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-readable reason 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.