Skip to main content
Point a phone number at an agent and it picks up every inbound call. Phone calls are ordinary agent sessions: they appear in session history with caller attribution, they are stored and analyzed under the same per-agent settings as any other conversation, and they trigger the same webhooks.

Phone numbers

Get a number and manage its agent binding.

Conversation history

Review transcripts, tool calls, and recordings.

Webhooks

Get notified when calls end and analysis completes.

Set up inbound calling

1

Get a phone number

Add a number to your workspace; see Phone numbers. Numbers are stored and displayed in E.164 format (for example +15551234567).
2

Publish your agent

Calls connect to the agent’s published configuration, not the draft. Publish before pointing traffic at the number.
3

Bind the agent to the number

Bind in the console, or set agent_id on the number via the API:
The number-to-agent binding is resolved on each incoming call, so a rebind takes effect on the next call, useful for moving a number from a staging agent to a production agent.

Phone sessions in history

Every answered call becomes a session with source: "phone" and these attribution fields: List calls with the standard sessions endpoint. The caller_number filter is an exact match; bare numbers are automatically prefixed with +, so 15551234567 matches +15551234567:
You can combine caller_number with the other list filters (agent_id, status, created_after, created_before); see Conversation history for the full parameter list. The agent can read both numbers too, as {{system.caller_number}} and {{system.dialed_number}} in its system prompt, first message, and webhook tool requests. No variable needs to be passed; see System variables.
System prompt

Personalize calls before the agent answers

Inbound calls have no session-creation request to carry dynamic variables, so the agent has a dedicated hook instead: the inbound call webhook. When configured, the platform posts the caller’s number to your endpoint while the call is being set up, and the dynamic_variables you return fill the {{placeholders}} in the published prompt and first message before the agent speaks. They fill webhook tool requests too, so a lookup tool can send the caller’s record id without the agent repeating it.
First message
Set it on the agent’s Webhooks page in the console (Inbound call webhook) or through webhooks.conversation_init in the config API, then publish. A slow or failing endpoint never blocks the call: after the configured timeout (up to 8 seconds, default 5) the call connects and every placeholder takes its configured default value (Hi there, thanks for calling Acme.). Set a default for each placeholder the first message depends on, or set the agent’s on_missing to reject if the call must not connect without them. To have callers pick an option before the agent answers, the way a phone menu does, add a keypad menu. The choice fills a variable the same way.

Phone sessions behave like any session

Nothing about a phone call needs special handling downstream:
  • Transcript and tool timeline: GET /v1/agent/sessions/{session_id} returns the conversation, including tool calls and results, when the agent stores transcripts. See Conversation history.
  • Recording: GET /v1/agent/sessions/{session_id}/recording returns signed URLs, one track per speaker, when the session was recorded.
  • Post-call analysis: summaries, data fields, and evaluation criteria run on phone sessions like any other. See Post-call analysis.
  • Webhooks: call.ended and call.analyzed fire for phone sessions too. See Webhooks.
  • Hang up via API: end an in-progress call with POST /v1/agent/sessions/{session_id}/end.

Going further

Phone numbers

Number management and agent bindings.

Versions & publishing

Control which configuration answers your calls.

Post-call analysis

Extract structured data from every call.

Webhooks

React to call lifecycle events from your backend.