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

# Ultravox (API)

> Place outbound Ultravox AI calls through your Unpod number over SIP - create the Unpod trunk, attach your number, then trigger the call from Ultravox.

The **programmatic** path: on the **Unpod side** create a SIP trunk and attach your number
to get a SIP endpoint + credentials; then call **Ultravox's Create Agent Call** endpoint
with those SIP details. Ultravox places the outbound call through your Unpod trunk. Prefer
clicks? See the [Dashboard guide](/telephony/integrations/ultravox/dashboard).

<Note>
  **Unpod Base URL:** `https://unpod.ai/api/v2/platform/`
  Every Unpod request needs `Authorization: Token <your-api-key>` and an `Org-Handle` header.
  See [Authentication](/api/get-started/authentication).
</Note>

## Prerequisites

* An Unpod **API Token** and **Org-Handle**, plus a number on a Bridge.
* An Ultravox **API key** and an **agent** (note its **Agent ID**).

## 1. Find your Unpod number

```bash cURL theme={null}
curl https://unpod.ai/api/v2/platform/telephony/numbers/ \
  -H "Authorization: Token $UNPOD_TOKEN" \
  -H "Org-Handle: $ORG_HANDLE"
```

```json Response (200) theme={null}
{
  "status_code": 200,
  "message": "Telephony numbers fetched successfully.",
  "data": [
    { "id": 501, "number": "+918071539111", "state": "ASSIGNED", "active": true }
  ]
}
```

<Card title="List Numbers reference" icon="hash" href="/telephony/numbers/list-numbers">
  Full request/response schema.
</Card>

## 2. Create the SIP trunk

Set `auth_username` / `auth_password` - these become the SIP credentials Ultravox
authenticates with when it dials into Unpod.

```bash cURL theme={null}
curl -X POST https://unpod.ai/api/v2/platform/telephony/trunks/ \
  -H "Authorization: Token $UNPOD_TOKEN" \
  -H "Org-Handle: $ORG_HANDLE" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ultravox trunk",
    "sip_url": "sip:sip-lb1.unpod.tel",
    "auth_username": "unpod_user_501",
    "auth_password": "<choose-a-password>",
    "transport": "udp",
    "port": "5060"
  }'
```

```json Response (201) theme={null}
{
  "status_code": 201,
  "message": "Trunk created successfully.",
  "data": { "id": 21, "name": "Ultravox trunk", "auth_username": "unpod_user_501", "active": true }
}
```

<Card title="Create Trunk reference" icon="plus-circle" href="/telephony/trunks/create-trunk">
  All request fields (`sip_url`, `auth_username`, `auth_password`, `transport`, `port`, `source_ips`).
</Card>

## 3. Attach your number to the trunk

Map the number from step 1 (its `id`) to the trunk from step 2 (its `id`). The response
returns the **origin endpoint** - the SIP domain Ultravox dials into.

```bash cURL theme={null}
curl -X POST https://unpod.ai/api/v2/platform/telephony/trunks/21/attach-numbers/ \
  -H "Authorization: Token $UNPOD_TOKEN" \
  -H "Org-Handle: $ORG_HANDLE" \
  -H "Content-Type: application/json" \
  -d '{ "number_ids": [501] }'
```

```json Response (201) theme={null}
{
  "status_code": 201,
  "message": "Numbers mapped to trunk.",
  "data": {
    "trunk_id": 21,
    "origin_endpoint": { "ingress": "sip:sip-lb1.unpod.tel", "dids": ["+918071539111"] }
  }
}
```

You now have everything Ultravox needs:

* **SIP domain** - host from `origin_endpoint.ingress` (e.g. `sip-lb1.unpod.tel`, drop the `sip:`).
* **`auth_username`** / **`auth_password`** - the creds you set in step 2.
* Your **number** (`+918071539111`) for caller ID.

<Card title="Attach Numbers reference" icon="link" href="/telephony/trunks/attach-numbers">
  Path params, request body, and the full origin-endpoint response.
</Card>

## 4. Place the call from Ultravox

This is **Ultravox's own API** (`api.ultravox.ai`, `X-API-Key` header). Point `to` at your
Unpod SIP domain and pass the Unpod credentials.

```bash cURL theme={null}
curl -X POST https://api.ultravox.ai/api/agents/YOUR_AGENT_ID/calls \
  -H "X-API-Key: YOUR_ULTRAVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "medium": {
      "sip": {
        "outgoing": {
          "to": "sip:+919999999999@sip-lb1.unpod.tel",
          "from": "+918071539111",
          "username": "unpod_user_501",
          "password": "<the-password-from-step-2>"
        }
      }
    },
    "firstSpeakerSettings": { "user": {} }
  }'
```

| Field                   | Value                                                 |
| ----------------------- | ----------------------------------------------------- |
| `to`                    | Destination as `sip:<number>@<your-unpod-sip-domain>` |
| `from`                  | Your Unpod number (caller ID)                         |
| `username` / `password` | Unpod `auth_username` / `auth_password` from step 2   |
| `firstSpeakerSettings`  | `{ "user": {} }` - callee speaks first (outbound)     |

Ultravox returns a `callId` and sends the SIP INVITE through Unpod. The agent joins when
the callee answers.

<Card title="Ultravox Create Agent Call" icon="arrow-up-right-from-square" href="https://docs.ultravox.ai/api-reference/agents/agents-calls-post">
  Full request body + response (this is Ultravox's API).
</Card>

## 5. Debug with SIP logs

If a call is rejected, pull Ultravox's SIP logs for that `callId`:

```bash cURL theme={null}
curl https://api.ultravox.ai/api/calls/CALL_ID/sip/logs \
  -H "X-API-Key: YOUR_ULTRAVOX_API_KEY"
```

<Card title="Ultravox SIP logs" icon="arrow-up-right-from-square" href="https://docs.ultravox.ai/api-reference/calls/calls-sip-logs-get">
  SIP log fields for debugging rejected calls (this is Ultravox's API).
</Card>

## Troubleshooting

| Status        | Meaning                 | Fix                                                              |
| ------------- | ----------------------- | ---------------------------------------------------------------- |
| `403`         | Auth rejected by Unpod  | Re-check `username` / `password` (Unpod trunk creds from step 2) |
| `407`         | Proxy auth required     | Ensure `username` / `password` are in `sip.outgoing`             |
| `480`         | Destination unavailable | Verify the `to` number; confirm your Unpod number is active      |
| `401` (Unpod) | Bad Unpod token         | Verify `Authorization: Token …` on Unpod calls                   |

<CardGroup cols={2}>
  <Card title="No-code version" icon="layout-dashboard" href="/telephony/integrations/ultravox/dashboard">
    The same flow, gathering creds in the UIs.
  </Card>

  <Card title="All platforms" icon="blocks" href="/telephony/integrations/overview">
    Back to the integrations overview.
  </Card>
</CardGroup>
