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

# Carrier

> Telephony providers: Twilio and Telnyx.

# Carrier

The carrier delivers the phone call to Patter. Patter supports **Twilio** and **Telnyx**. Both share DTMF, call transfer, AMD, status callbacks, and cost tracking; recording is Twilio-only.

You configure one carrier per `Patter` instance by passing an instance to the `carrier` field. Each carrier class falls back to environment variables when constructor arguments are omitted.

Both carriers are imported by name from the package barrel: `import { Twilio, Telnyx } from "getpatter"`.

## Twilio

```typescript theme={null}
import { Patter, Twilio } from "getpatter";

const phone = new Patter({
  carrier: new Twilio(),                              // reads env
  phoneNumber: "+15550001234",
});

// Or explicitly:
const phone = new Patter({
  carrier: new Twilio({ accountSid: "AC...", authToken: "..." }),
  phoneNumber: "+15550001234",
});
```

| Parameter    | Type     | Default | Description                                                                          |
| ------------ | -------- | ------- | ------------------------------------------------------------------------------------ |
| `accountSid` | `string` | —       | Twilio Account SID (starts with `AC`). Reads from `TWILIO_ACCOUNT_SID` when omitted. |
| `authToken`  | `string` | —       | Twilio Auth Token. Reads from `TWILIO_AUTH_TOKEN` when omitted.                      |

On `serve()`, Patter automatically sets the `voice_url` on the Twilio number to `https://<webhookUrl>/webhooks/twilio/voice` via the Twilio REST API — no manual Console configuration needed.

### How caller / callee reach the agent

Inbound Twilio calls deliver the caller and callee numbers via TwiML `<Parameter name="caller" value="..."/>` / `<Parameter name="callee" value="..."/>` children of `<Stream>` — Twilio surfaces these on the WS `start` frame as `start.customParameters`. Patter's `/webhooks/twilio/voice` route emits this TwiML automatically. If you construct the TwiML yourself, build it with `TwilioAdapter.generateStreamTwiml(streamUrl, { caller, callee })` so the values land on the WS `start` frame. Query-string parameters on the `<Stream url=...>` are stripped by Twilio before the WS handshake and will not work.

### Signature verification

The Auth Token is also used to verify every Twilio webhook with HMAC-SHA1 against the `X-Twilio-Signature` header. Requests with invalid signatures are rejected with HTTP 403.

## Telnyx

```typescript theme={null}
import { Patter, Telnyx } from "getpatter";

const phone = new Patter({
  carrier: new Telnyx(),                              // reads env
  phoneNumber: "+15550001234",
});

// Or explicitly:
const phone = new Patter({
  carrier: new Telnyx({
    apiKey: "KEY...",
    connectionId: "2000000000000000000",
    publicKey: "...",   // optional — enables Ed25519 signature verification
  }),
  phoneNumber: "+15550001234",
});
```

| Parameter      | Type     | Default | Description                                                                                                   |
| -------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| `apiKey`       | `string` | —       | Telnyx API v2 key. Reads from `TELNYX_API_KEY` when omitted.                                                  |
| `connectionId` | `string` | —       | Call Control Application ID. Reads from `TELNYX_CONNECTION_ID` when omitted.                                  |
| `publicKey`    | `string` | —       | Optional. Ed25519 public key for webhook signature verification. Reads from `TELNYX_PUBLIC_KEY` when omitted. |

### How caller / callee reach the agent

The Telnyx WS upgrade URL carries the metadata as query-string parameters: `wss://<webhookUrl>/ws/stream/<callControlId>?caller=<from>&callee=<to>`. Telnyx preserves the query string through the WebSocket handshake, so no equivalent of TwiML `<Parameter>` is needed.

### Signature verification

When `publicKey` is set (or `TELNYX_PUBLIC_KEY` is present), every Telnyx webhook is verified with Ed25519. Requests older than 5 minutes are rejected (replay protection).

## Webhook Endpoints

The embedded server exposes these endpoints regardless of carrier choice:

| Endpoint                          | Purpose                                                                    |
| --------------------------------- | -------------------------------------------------------------------------- |
| `POST /webhooks/twilio/voice`     | Incoming Twilio call → returns TwiML to start streaming.                   |
| `POST /webhooks/twilio/status`    | Call lifecycle status callbacks (initiated, ringing, answered, completed). |
| `POST /webhooks/twilio/recording` | Recording completion callbacks.                                            |
| `POST /webhooks/twilio/amd`       | Async AMD (answering machine detection) results.                           |
| `POST /webhooks/telnyx/voice`     | Incoming Telnyx call → returns Call Control commands.                      |

## What's Next

<CardGroup cols={2}>
  <Card title="STT" icon="microphone" href="/typescript-sdk/stt">Speech-to-text providers.</Card>
  <Card title="LLM" icon="brain" href="/typescript-sdk/llm">Language model providers.</Card>
  <Card title="TTS" icon="volume" href="/typescript-sdk/tts">Text-to-speech providers.</Card>
  <Card title="Tunneling" icon="cloud" href="/dev-tools/tunneling">Expose your local server publicly.</Card>
</CardGroup>
