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.
Local Mode (Self-Hosted)
Local mode runs an embedded server on your infrastructure. You bring your own telephony credentials (Twilio or Telnyx) and AI provider keys. No Patter backend required.When to Use Local Mode
- You need full control over your infrastructure
- You want to keep all data on your own servers
- You are testing and developing locally
- You need to comply with data residency requirements
Setup
1. Install the SDK
2. Expose your server
Telephony providers need a public URL to reach your local server. The easiest option is the built-in Cloudflare tunnel — passtunnel=True (or tunnel=CloudflareTunnel()) to serve() and Patter creates the tunnel and auto-configures the Twilio webhook for you (requires the cloudflared package, see Tunneling).
Alternatively, run ngrok and pass the hostname as webhook_url:
3. Initialize Patter
serve()
Theserve() method starts the embedded server and blocks until it is stopped. It handles inbound calls automatically.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
agent | Agent | required | The agent configuration to use for all calls. Create with phone.agent(). |
port | int | 8000 | TCP port to bind to (1-65535). |
recording | bool | False | Enable call recording via the Twilio Recordings API. |
on_call_start | Callable | None | None | Async callback fired when a call connects. |
on_call_end | Callable | None | None | Async callback fired when a call ends. |
on_transcript | Callable | None | None | Async callback fired for each utterance. |
on_message | Callable | None | None | Async callback for pipeline mode. Receives user text, returns agent response. |
voicemail_message | str | "" | Message to speak when AMD detects a machine on outbound calls. |
on_metrics | Callable | None | None | Async callback fired after each conversation turn with real-time cost and latency data. See Metrics & Cost Tracking. |
dashboard | bool | True | Serve a local metrics dashboard at http://localhost:{port}/dashboard. |
dashboard_token | str | "" | Bearer token for dashboard authentication. When set, all dashboard routes require this token. |
tunnel | bool | False | Start a cloudflared tunnel automatically. Requires cloudflared on PATH. Mutually exclusive with webhook_url. |
Making Outbound Calls
In local mode, usecall() to make outbound calls while the server is running.
Important: the server must be fully initialized before you call phone.call(). Use await phone.ready — it resolves once the tunnel is up, the embedded server is in listen state, and the carrier webhook is configured. This is the reliable replacement for asyncio.sleep() guesswork:
phone.ready rejects with the underlying exception if serve() fails before the server reaches listen state, so you get an immediate error instead of a hanging await.
Advanced — tunnel hostname only: if you only need the public URL (for example, to register a webhook manually) without waiting for the HTTP server to be in listen state, use await phone.tunnel_ready instead. It resolves earlier but a phone.call() placed immediately afterwards can race the WebSocket upgrade path and produce a dropped call on answer.
call() Parameters (Local Mode)
All keyword arguments are snake_case (e.g.machine_detection=, ring_timeout=, on_machine_detection=).
| Parameter | Type | Default | Description |
|---|---|---|---|
to | str | required | Phone number to call (E.164 format). |
agent | Agent | required | Agent instance to use for this call. |
first_message | str | "" | What the AI says when the callee answers. |
from_number | str | "" | Override the configured phone number. |
machine_detection | bool | True | Enable answering machine detection. Defaults on since 0.6.2 — on Twilio Patter uses MachineDetection=DetectMessageEnd + Async AMD so there is no answer-latency penalty on human pickups. Pass False to skip per-call AMD billing for known destinations. |
on_machine_detection | Callable[[MachineDetectionResult], Awaitable[None] | None] | None | None | Fires once when the carrier reports the AMD outcome (human or machine). |
voicemail_message | str | "" | Message to leave on voicemail. A non-empty value also implicitly enables machine_detection. |
ring_timeout | int | None | 25 | Ring timeout in seconds before treating the call as no-answer. Defaults to 25 s — production-recommended. Pass 60 for legacy carrier-default parity, or None to omit the parameter entirely (carrier picks its own default). |
EmbeddedServer
TheEmbeddedServer is the internal class that powers serve(). You typically do not interact with it directly, but it is useful to understand for advanced use cases.
| Property | Type | Description |
|---|---|---|
config | LocalConfig | Telephony and AI provider configuration. |
agent | Agent | The agent configuration. |
recording | bool | Whether call recording is enabled. |
voicemail_message | str | Voicemail message for AMD. |
Methods
| Method | Description |
|---|---|
start(port) | Start the server (blocking). |
stop() | Gracefully stop the server. |
LocalConfig
TheLocalConfig dataclass holds all provider credentials for local mode. It is created automatically from the Patter constructor — you don’t normally need to touch it directly.
| Field | Type | Description |
|---|---|---|
telephony_provider | str | "twilio" or "telnyx" (auto-detected from the carrier= instance). |
twilio_sid | str | Twilio Account SID (unpacked from Twilio(...)). |
twilio_token | str | Twilio Auth Token (unpacked from Twilio(...)). |
telnyx_key | str | Telnyx API key (unpacked from Telnyx(...)). |
telnyx_connection_id | str | Telnyx Call Control Application ID (unpacked from Telnyx(...)). |
telnyx_public_key | str | Telnyx Ed25519 public key for webhook signature verification (optional). |
openai_key | str | OpenAI API key (resolved from OpenAIRealtime(...) or OPENAI_API_KEY). |
elevenlabs_key | str | ElevenLabs API key. |
deepgram_key | str | Deepgram API key. |
cartesia_key, rime_key, lmnt_key, soniox_key, speechmatics_key, assemblyai_key | str | Provider-specific keys backfilled from the matching constructor or env var. |
phone_number | str | Phone number in E.164 format. |
webhook_url | str | Public hostname (no scheme). |
require_signature | bool | When True (default), inbound webhooks with missing credentials return HTTP 503 instead of silently accepting. Disable only for local mock-provider testing. |
persist_root | str | None | Resolved persistence path for the dashboard’s on-disk call history, or None to disable. Set by the persist= argument on Patter(...) (with PATTER_LOG_DIR env fallback). |
Disconnecting
Calldisconnect() to stop the embedded server gracefully:

