> ## Documentation Index
> Fetch the complete documentation index at: https://docs.telzino.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Outbound Calls Overview

> Trigger AI agent calls to any phone number and receive the results via webhook

Outbound Calls let you place phone calls programmatically: your system makes one API request, a Telzino AI agent dials the number, holds the conversation, and the result — status, duration, AI summary, and transcript reference — is delivered back to you.

## How it works

<Steps>
  <Step title="Trigger the call">
    `POST /v1/agents/{agentId}/outbound-calls` with the destination number. You can include per-call context for the agent, opaque metadata, and a webhook URL for the result. The API responds immediately with `202 Accepted` and a call ID — the call is queued, not yet ringing.
  </Step>

  <Step title="The platform places the call">
    The dispatcher picks up your queued call (typically within a couple of seconds), assigns an agent worker, and dials the number. The agent speaks its greeting as soon as the callee answers — never while the phone is still ringing.
  </Step>

  <Step title="The agent has the conversation">
    The agent uses its full configuration: system prompt (plus your per-call `call_context`), voice, tools, integrations, and after-call webhooks — identical capabilities to inbound calls.
  </Step>

  <Step title="You receive the result">
    When the call reaches a terminal state, the result webhook fires (if you provided `callback_url`) and the call record is finalized with duration, AI summary, and a transcript reference. You can also poll the call at any time.
  </Step>
</Steps>

## Call lifecycle

Every outbound call moves through these statuses:

| Status                       | Meaning                                                                            |
| ---------------------------- | ---------------------------------------------------------------------------------- |
| `queued`                     | Accepted by the API, waiting for the dispatcher                                    |
| `dispatching` / `dispatched` | The platform is assigning the call to an agent worker                              |
| `dialing`                    | The phone is ringing                                                               |
| `in_progress`                | The callee answered; the conversation is live                                      |
| `completed`                  | The call ended normally — summary and transcript available                         |
| `no_answer`                  | Rang for \~45 seconds with no answer                                               |
| `busy`                       | The line was busy or the call was rejected                                         |
| `failed`                     | The call could not be placed (details in the `error` and `sip_status_code` fields) |

`completed`, `no_answer`, `busy`, and `failed` are terminal — the result webhook fires exactly when one of these is reached.

## The result webhook

If you pass a `callback_url` when triggering the call, Telzino POSTs the result to it on every terminal status:

```json theme={null}
{
  "outbound_call_id": "0fc6daf8-7251-4553-9488-867ba0b82d8e",
  "agent_id": "aadcdc82-0c96-4171-a812-6d68ae71c44c",
  "to_number": "+18134268216",
  "status": "completed",
  "answered_at": "2026-06-11T12:50:03.843960+00:00",
  "ended_at": "2026-06-11T12:54:15.354244+00:00",
  "duration": 251,
  "summary_text": "Appointment Confirmation\n\nThe agent confirmed the customer's appointment for tomorrow at 2pm...\n\n**Sentiment:** Positive",
  "transcript_id": "de79aee6-ae41-4003-a3f4-ba9d77b59bd8",
  "metadata": { "crm_id": "123" },
  "error": null,
  "sip_status_code": null
}
```

* `metadata` is your own payload from the trigger request, echoed back verbatim — use it to correlate the result with records in your system.
* `transcript_id` links to the full transcript, retrievable via the [Call Logs API](/api-reference/call-logs).
* For unanswered or failed calls, `summary_text` and `transcript_id` are `null` and `sip_status_code` carries the SIP failure code (e.g. `486` busy, `480` no answer).

<Warning>
  The result webhook must be an **HTTPS** URL and is delivered **once** (10-second timeout, no retries). Treat it as a notification: if your endpoint was down, poll [`GET /v1/agents/{agentId}/outbound-calls/{callId}`](/api-reference/outbound-calls/get) — the call record is always the source of truth.
</Warning>

## Good to know

<AccordionGroup>
  <Accordion title="Voicemail counts as an answered call">
    If voicemail or an auto-attendant picks up, the call is treated as answered (`in_progress` → `completed`) — the agent will speak to the recording. Answering-machine detection is on the roadmap; until then, factor this into your redial logic.
  </Accordion>

  <Accordion title="No automatic redial">
    The platform never retries `no_answer`, `busy`, or `failed` calls on its own. Your application decides whether and when to call again, using the webhook or polled status.
  </Accordion>

  <Accordion title="How the opening line is chosen">
    When the callee answers, the agent speaks the first match in this order:

    1. The `greeting` field from the trigger request — spoken verbatim.
    2. The agent's **Outbound Greeting** setting (dashboard agent settings, or `outboundGreetingMessage` via the Agents API) — spoken verbatim.
    3. If `call_context` was provided — an **AI-composed opener** that introduces the agent and states the reason for the call (e.g. *"Hi, this is Ava from Acme calling to confirm your appointment tomorrow at 2pm."*).
    4. Otherwise, the agent's inbound greeting message.

    The agent's `skip_greeting` voice setting suppresses all of these.
  </Accordion>

  <Accordion title="Per-call context vs. agent configuration">
    The agent's stored configuration (prompt, voice, tools) always applies. `call_context` is appended to the prompt for that one call only — ideal for "you're calling John to confirm his 2pm appointment" without creating a dedicated agent per purpose.
  </Accordion>
</AccordionGroup>

## Endpoints

| Endpoint                                                                                | Purpose                        |
| --------------------------------------------------------------------------------------- | ------------------------------ |
| [`POST /v1/agents/{agentId}/outbound-calls`](/api-reference/outbound-calls/create)      | Trigger an outbound call       |
| [`GET /v1/agents/{agentId}/outbound-calls/{callId}`](/api-reference/outbound-calls/get) | Get a call's status and result |
| [`GET /v1/agents/{agentId}/outbound-calls`](/api-reference/outbound-calls/list)         | List an agent's outbound calls |

Authentication works exactly like the rest of the API — see [Authentication](/api-reference/authentication).
