> ## 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.

# Phone Numbers

> Get numbers directly from Unpod or bring your own, then attach them to your Speech Pipes.

## Overview

A [Number](/get-started/core-concepts#number) is the phone number callers
dial; it rides on a [trunk](/speech-stack/trunks) and routes to whatever
Speech Pipe it is attached to. Phone numbers in Unpod come from two sources:

* **Unpod Numbers** - provision numbers directly through the Unpod platform (no external carrier account needed)
* **BYON (Bring Your Own Number)** - port or route numbers you already own from any provider

Once a number is in your account, you attach it to a Speech Pipe. All inbound calls to that number are routed to the Speech Pipe's `AgentRunner`.

<Note>
  Support for Twilio, Telnyx, and Plivo numbers is coming soon - you will be able to import numbers from these providers directly into Unpod.
</Note>

***

## Number Sources

| Source     | Description                                        |
| ---------- | -------------------------------------------------- |
| **Unpod**  | Provision numbers directly from the Unpod platform |
| **BYON**   | Bring numbers from your existing provider          |
| **Twilio** | Coming soon                                        |
| **Telnyx** | Coming soon                                        |
| **Plivo**  | Coming soon                                        |

***

## Getting Numbers from Unpod

Numbers provisioned through Unpod are immediately available in your account. You can browse and acquire them from the dashboard under **Dev Platform -> Numbers**.

Once provisioned, list them via the SDK:

```python theme={null}
import asyncio
from unpod import AsyncClient

async def main():
    async with AsyncClient(api_key="sk_...") as client:
        numbers = await client.numbers.list()
        for n in numbers:
            print(n.number_id, n.number, n.status, n.pipe_id or "unattached")

asyncio.run(main())
```

***

## Bringing Your Own Number (BYON)

If you already have numbers with a carrier, configure them as a BYON trunk in the Unpod dashboard:

1. Go to **Dev Platform -> Telephony** and click **Add Trunk -> BYO SIP**.
2. Provide your carrier's SIP server details:
   * **SIP domain** - e.g. `sip.your-carrier.com`
   * **Credentials** - auth username and password
3. At your carrier, set inbound routing to point at the Unpod SIP endpoint shown in the dashboard.
4. Run `await client.numbers.sync()` (or click **Sync** on the trunk) so Unpod discovers the numbers on the trunk.
5. Your numbers appear in Unpod and can be attached to Speech Pipes.

<Note>
  Prefer the SDK? Register the same trunk with `client.trunks.create(...)`, then
  `client.numbers.sync()`. The field names match the dashboard - `sip_domain`,
  `auth_username`, `auth_password`. See [Trunks](/speech-stack/trunks).
</Note>

***

## Listing Numbers

```python theme={null}
import asyncio
from unpod import AsyncClient

async def main():
    async with AsyncClient(api_key="sk_...") as client:
        # All numbers
        numbers = await client.numbers.list()

        # Filter by status or country
        active = await client.numbers.list(status="active")
        us_numbers = await client.numbers.list(country="US")
        byon = await client.numbers.list(trunk_type="byo")

        for n in numbers:
            print(n.number_id, n.number, n.status, n.pipe_id or "unattached")

asyncio.run(main())
```

### Number fields

| Field        | Type          | Description                             |
| ------------ | ------------- | --------------------------------------- |
| `number_id`  | `str`         | Unique number ID (`num_...`)            |
| `number`     | `str`         | E.164 format, e.g. `+14155550100`       |
| `status`     | `str`         | `active`, `inactive`, `pending`         |
| `trunk_type` | `str`         | `unpod` or `byo`                        |
| `pipe_id`    | `str \| None` | Attached Speech Pipe, or `None` if free |
| `country`    | `str`         | ISO 3166-1 alpha-2 country code         |

***

## Attaching a Number to a Speech Pipe

A number can be attached to exactly one Speech Pipe at a time. Inbound calls to that number are routed to the Speech Pipe's configured runners.

```python theme={null}
import asyncio
from unpod import AsyncClient

async def main():
    async with AsyncClient(api_key="sk_...") as client:
        number = await client.numbers.attach(
            number_id="num_...",
            pipe_id="pipe_...",
        )
        print("Attached:", number.number, "-> pipe", number.pipe_id)

asyncio.run(main())
```

***

## Detaching a Number

```python theme={null}
import asyncio
from unpod import AsyncClient

async def main():
    async with AsyncClient(api_key="sk_...") as client:
        number = await client.numbers.detach("num_...")
        print("Detached:", number.number)

asyncio.run(main())
```

***

## Common Patterns

### Find the first free number and attach it

```python theme={null}
import asyncio
from unpod import AsyncClient

async def attach_first_free(pipe_id: str) -> None:
    async with AsyncClient(api_key="sk_...") as client:
        numbers = await client.numbers.list(status="active")
        free = [n for n in numbers if n.pipe_id is None]
        if not free:
            raise RuntimeError("No free numbers available")
        await client.numbers.attach(free[0].number_id, pipe_id)
        print("Attached", free[0].number)

asyncio.run(attach_first_free("pipe_..."))
```

### Rotate numbers across Speech Pipes

```python theme={null}
import asyncio
from unpod import AsyncClient

async def rotate(numbers: list[str], pipes: list[str]) -> None:
    async with AsyncClient(api_key="sk_...") as client:
        for num_id, pipe_id in zip(numbers, pipes):
            await client.numbers.attach(num_id, pipe_id)
            print(f"{num_id} -> {pipe_id}")

asyncio.run(rotate(["num_a", "num_b"], ["pipe_x", "pipe_y"]))
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Voice Profiles" icon="waveform" href="/speech-stack/voice-profiles">
    Choose the voice profile for your Speech Pipe.
  </Card>

  <Card title="Speech Pipe" icon="bot" href="/speech-stack/pipes">
    Create and configure your Speech Pipe via the SDK.
  </Card>
</CardGroup>
