Local Mode (Self-Hosted)
Local mode runs an embedded server on your infrastructure. You bring your own telephony credentials (Twilio, Telnyx, or Plivo) 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
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=).
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.
Methods
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.
Disconnecting
Calldisconnect() to stop the embedded server gracefully:

