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

# Connect a SIP-trunk number

> Connect a phone number from any carrier over SIP trunking, and choose the assistants that answer it and dial from it.

Connects a number you own at a carrier to Verbeo over SIP trunking: Verbeo sets up the trunks that carry the number's inbound and outbound calls, then stores the number. It works with any carrier that gives you a SIP trunk — for Twilio Elastic SIP Trunking, [Import a phone number from Twilio](/guides/import-twilio-number) covers the carrier side.

<Note>
  Inbound calls arrive once your carrier sends the number's calls to Verbeo's origination URI, `sip:1mq55afrqof.sip.livekit.cloud`. That is set at the carrier, not through this API.
</Note>

## Body

<ParamField body="phone_number" type="string" required>
  The number in E.164 format — a `+`, the country code, the number: `+14155550123`. Spaces, dashes and brackets are accepted and removed. A number without its country code, or one that is not a real number, is rejected.
</ParamField>

<ParamField body="termination_uri" type="string" required>
  The host your carrier takes outbound calls on, optionally with a port: `acme.pstn.twilio.com` or `sip.example.com:5061`. No `sip:` or `https://` in front. Up to 253 characters.
</ParamField>

<ParamField body="transport" type="string" default="tcp">
  `tcp`, `udp`, `tls` or `auto`.
</ParamField>

<ParamField body="sip_username" type="string">
  The trunk's user name, if your carrier authenticates outbound calls with credentials. Up to 128 characters. Send it together with `sip_password`, or send neither.
</ParamField>

<ParamField body="sip_password" type="string">
  The trunk's password, stored as you send it. Up to 128 characters. Write-only: no endpoint returns it.
</ParamField>

<ParamField body="nickname" type="string">
  Your label for the number, up to 100 characters.
</ParamField>

<ParamField body="inbound_agent_id" type="string">
  UUID of the assistant that answers calls to this number. Omit it and nobody answers until you [set one](/api-reference/phone-numbers/update).
</ParamField>

<ParamField body="outbound_agent_id" type="string">
  UUID of the assistant that places calls from this number when a call names none.
</ParamField>

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.verbeo.ai/v1/phone-number/sip" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "phone_number": "+14155550123",
      "termination_uri": "acme.pstn.twilio.com",
      "sip_username": "verbeo",
      "sip_password": "a-strong-password",
      "nickname": "Main line",
      "inbound_agent_id": "550e8400-e29b-41d4-a716-446655440000"
    }'
  ```

  ```javascript Node.js theme={null}
  const res = await fetch("https://api.verbeo.ai/v1/phone-number/sip", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.VERBEO_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      phone_number: "+14155550123",
      termination_uri: "acme.pstn.twilio.com",
      sip_username: "verbeo",
      sip_password: process.env.SIP_TRUNK_PASSWORD,
      nickname: "Main line",
      inbound_agent_id: "550e8400-e29b-41d4-a716-446655440000",
    }),
  });
  const { data: number } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post(
      "https://api.verbeo.ai/v1/phone-number/sip",
      headers={"Authorization": f"Bearer {os.environ['VERBEO_API_KEY']}"},
      json={
          "phone_number": "+14155550123",
          "termination_uri": "acme.pstn.twilio.com",
          "sip_username": "verbeo",
          "sip_password": os.environ["SIP_TRUNK_PASSWORD"],
          "nickname": "Main line",
          "inbound_agent_id": "550e8400-e29b-41d4-a716-446655440000",
      },
  )
  number = res.json()["data"]
  ```
</CodeGroup>

## Response

`201 Created` with [the phone number object](/api-reference/phone-numbers/overview#the-phone-number-object). `provider` is `livekit_sip`.

```json theme={null}
{
  "success": true,
  "data": {
    "id": "7d9f3b52-4c1e-4a8e-9b1a-2f6c0d4e8a11",
    "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
    "phone_number": "+14155550123",
    "nickname": "Main line",
    "provider": "livekit_sip",
    "is_active": true,
    "max_cps": 1,
    "inbound_agent_id": "550e8400-e29b-41d4-a716-446655440000",
    "outbound_agent_id": null,
    "inbound_webhook_url": null,
    "created_at": "2026-01-15T10:30:00.123456+00:00",
    "updated_at": "2026-01-15T10:30:00.123456+00:00",
    "inbound_agent_name": "Customer Support",
    "outbound_agent_name": null
  }
}
```

## Errors

| Code | Status | When |
| - | - | - |
| `VALIDATION_FAILED` | 422 | A missing or malformed field — the message names it, e.g. `termination_uri: must be a hostname such as example.pstn.twilio.com, optionally with :port`. Also a user name without a password (or the reverse), and an assistant id that is not an assistant of your workspace. |
| `CONFLICT` | 409 | The number is already connected to Verbeo, in your workspace or another. |
| `BAD_GATEWAY` | 502 | The trunk could not be created. The message carries the reason. |

Nothing is left behind when a request fails — a trunk that was created is removed again, so the same request can be sent once more.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.