Configuration
ThePatter class is the main entry point for the SDK. Pass a carrier instance and a phone number — everything else flows through environment variables unless you override it.
Minimal config
Constructor parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
carrier | Twilio | Telnyx | None | None | Telephony carrier instance. See Carrier. Reads credentials from env vars when arguments are omitted. |
phone_number | str | "" | Your phone number in E.164 format (e.g., "+15550001234"). Required when a carrier is set. |
webhook_url | str | "" | Public hostname of this server, without scheme (e.g., "abc.ngrok.io"). See Tunneling for ways to get one. |
tunnel | CloudflareTunnel | Static | bool | None | None | Tunnel directive. True is shorthand for CloudflareTunnel(). See Tunneling. |
pricing | dict | None | None | Override default provider pricing estimates. See Metrics & Cost Tracking. |
persist | bool | str | None | None (=on, platform default path) | Persist the dashboard’s call history to disk so it survives process restarts. Defaults on since 0.6.2 — the dashboard’s hydrate path requires on-disk records to recover history across restarts. Pass False to keep the old ephemeral-RAM-only behaviour. See Persistent dashboard history below. |
Environment variables
Every credential resolves from an env var when the matching argument is omitted. See.env.example in the repo for a complete list.
| Env var | Used by |
|---|---|
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN | Twilio() |
TELNYX_API_KEY, TELNYX_CONNECTION_ID, TELNYX_PUBLIC_KEY (optional) | Telnyx() |
OPENAI_API_KEY | OpenAIRealtime(), OpenAITTS(), WhisperSTT() |
ELEVENLABS_API_KEY, ELEVENLABS_AGENT_ID | ElevenLabsTTS(), ElevenLabsConvAI() |
DEEPGRAM_API_KEY | DeepgramSTT() |
CARTESIA_API_KEY | CartesiaSTT(), CartesiaTTS() |
RIME_API_KEY | RimeTTS() |
LMNT_API_KEY | LMNTTTS() |
SONIOX_API_KEY | SonioxSTT() |
SPEECHMATICS_API_KEY | SpeechmaticsSTT() (Python only) |
ASSEMBLYAI_API_KEY | AssemblyAISTT() |
Runtime env vars
These tune SDK runtime behaviour (no credential lookup).| Env var | Default | Effect |
|---|---|---|
PATTER_LOG_DIR | unset | Persistent dashboard root (see Persistent dashboard history below). |
PATTER_LOG_RETENTION_DAYS | 30 | Days of disk history to retain. 0 disables cleanup. |
PATTER_LOG_REDACT_PHONE | full | One of full (store raw E.164), mask (last 4 digits), or hash_only (sha256:prefix). Changed from mask to full on 2026-05-21 so the dashboard’s reveal toggle has something to reconstruct from. |
PATTER_DASHBOARD_NOTIFY | enabled | Set to 0, false, no, or off (case-insensitive) to skip the fire-and-forget dashboard ingest POST. Use this when you embed Patter alongside your own FastAPI server on port 8000 to avoid 404 spam in your access log. |
PATTER_BIND_HOST | 127.0.0.1 | Host the embedded server binds to. Set to 0.0.0.0 when running inside a container whose port must be reachable from the host (e.g. docker run -p 8000:8000 — Docker’s port-mapping cannot forward to a 127.0.0.1 listener inside the container). |
PATTER_BIND_HOST defaults to loopback on purpose — exposing the embedded server on 0.0.0.0 outside a containerised deployment puts the dashboard and webhook routes on every interface. Pair PATTER_BIND_HOST=0.0.0.0 with the dashboard_token argument on serve() (or skip the dashboard) before going public.PATTER_DASHBOARD_NOTIFY only gates the standalone-dashboard ingest webhook. It does not disable the embedded dashboard you can serve from phone.serve(..., dashboard=True) — that route runs in-process and is unaffected.Examples
OpenAI Realtime on Twilio
OpenAI Realtime on Telnyx
Pipeline mode
Validation
Local mode enforces the following when telephony credentials are present:phone_numberis required- Both
account_sidandauth_tokenare required when using Twilio (either viaTwilio(...)kwargs orTWILIO_*env vars)
Persistent dashboard history
By default the dashboard is an in-memory ring buffer — restart the process and the call list is empty. Passpersist= to keep per-call records (metadata.json, transcript.jsonl, events.jsonl) on disk and rebuild the dashboard on the next startup. No external database required.
persist value | Behaviour |
|---|---|
omitted / None (default) | Reads PATTER_LOG_DIR if set; otherwise falls back to the platform default location. Persistence is on by default since 0.6.2 so the dashboard’s hydrate path recovers history across process restarts. |
False | Force-off. Disk writes are skipped even when PATTER_LOG_DIR is set. Use this for ephemeral RAM-only behaviour. |
True | Write under the platform default location (see below). Equivalent to PATTER_LOG_DIR=auto. |
"<path>" (string) | Write under the supplied path (~ is expanded). Equivalent to PATTER_LOG_DIR=<path>. |
persist is set explicitly the env var is ignored. When persist is None, PATTER_LOG_DIR continues to work as a deployment-time override.
Platform default location
| Platform | Default root |
|---|---|
| macOS | ~/Library/Application Support/patter |
| Linux | $XDG_DATA_HOME/patter (falls back to ~/.local/share/patter) |
| Windows | %LOCALAPPDATA%\patter |
Simplest opt-in
Custom path
Env-var override (deployment-time)
Leavepersist unset in code and let ops decide per environment:
Programmatic hydration on startup
phone.serve() calls MetricsStore.hydrate(log_root) automatically when persistence is enabled, so the dashboard repopulates from disk before the first call lands. You can call it directly if you build the store yourself:
hydrate() is idempotent — call_ids already in the store are skipped, and unparseable records are logged at debug level rather than aborting.

