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

# Configuration

> All Patter constructor parameters for local mode.

# Configuration

The `Patter` 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

```python theme={null}
from getpatter import Patter, Twilio

phone = Patter(carrier=Twilio(), phone_number="+15550001234")   # TWILIO_* from env
```

The carrier instance reads credentials from environment variables when you don't pass them explicitly. See [Carrier](/python-sdk/carrier) for the full list.

## Constructor parameters

| Parameter      | Type                                         | Default                             | Description                                                                                                                                                                                                                                                                                                                               |
| -------------- | -------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `carrier`      | `Twilio \| Telnyx \| None`                   | `None`                              | Telephony carrier instance. See [Carrier](/python-sdk/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](/dev-tools/tunneling) for ways to get one.                                                                                                                                                                                                       |
| `tunnel`       | `CloudflareTunnel \| Static \| bool \| None` | `None`                              | Tunnel directive. `True` is shorthand for `CloudflareTunnel()`. See [Tunneling](/dev-tools/tunneling).                                                                                                                                                                                                                                    |
| `pricing`      | `dict \| None`                               | `None`                              | Override default provider pricing estimates. See [Metrics & Cost Tracking](/python-sdk/metrics).                                                                                                                                                                                                                                          |
| `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](#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](#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). |

<Note>
  `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.
</Note>

<Note>
  `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.
</Note>

## Examples

### OpenAI Realtime on Twilio

```python theme={null}
from getpatter import Patter, Twilio, OpenAIRealtime

phone = Patter(carrier=Twilio(), phone_number="+15550001234")

agent = phone.agent(
    engine=OpenAIRealtime(voice="nova"),
    system_prompt="You are a friendly receptionist.",
    first_message="Thanks for calling!",
)
```

### OpenAI Realtime on Telnyx

```python theme={null}
from getpatter import Patter, Telnyx, OpenAIRealtime

phone = Patter(carrier=Telnyx(), phone_number="+15550001234")

agent = phone.agent(
    engine=OpenAIRealtime(),
    system_prompt="You are a friendly receptionist.",
)
```

### Pipeline mode

```python theme={null}
from getpatter import Patter, Twilio, DeepgramSTT, ElevenLabsTTS

phone = Patter(carrier=Twilio(), phone_number="+15550001234")

agent = phone.agent(
    stt=DeepgramSTT(endpointing_ms=80),
    tts=ElevenLabsTTS(voice_id="rachel"),
    system_prompt="You are a helpful assistant.",
)
```

## Validation

Local mode enforces the following when telephony credentials are present:

* `phone_number` is required
* Both `account_sid` and `auth_token` are required when using Twilio (either via `Twilio(...)` kwargs or `TWILIO_*` env vars)

```python theme={null}
# Raises ValueError — Twilio credentials missing from env and arguments.
phone = Patter(carrier=Twilio())
# ValueError: Twilio carrier requires account_sid and auth_token.
```

## Persistent dashboard history

By default the dashboard is an in-memory ring buffer — restart the process and the call list is empty. Pass `persist=` 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>`.                                                                                                                          |

When `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

```python theme={null}
from getpatter import Patter, Twilio, OpenAIRealtime

phone = Patter(
    carrier=Twilio(),
    phone_number="+15555550100",
    persist=True,                   # platform default location
)

agent = phone.agent(
    engine=OpenAIRealtime(),
    system_prompt="You are a friendly receptionist.",
)
```

### Custom path

```python theme={null}
phone = Patter(
    carrier=Twilio(),
    phone_number="+15555550100",
    persist="/var/log/patter",      # explicit path; ~ is expanded
)
```

### Env-var override (deployment-time)

Leave `persist` unset in code and let ops decide per environment:

```bash theme={null}
# Production: keep history under a managed volume
export PATTER_LOG_DIR=/var/log/patter

# Dev: platform default
export PATTER_LOG_DIR=auto

# CI: leave unset → no disk writes
```

```python theme={null}
phone = Patter(carrier=Twilio(), phone_number="+15555550100")
# `persist` defaults to None → reads PATTER_LOG_DIR
```

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

```python theme={null}
from getpatter.dashboard.store import MetricsStore

store = MetricsStore()
restored = store.hydrate("/var/log/patter")
print(f"Restored {restored} calls from disk")
```

`hydrate()` is idempotent — `call_id`s already in the store are skipped, and unparseable records are logged at debug level rather than aborting.

### Retention

```bash theme={null}
# Default: 30 days. Old day-directories are swept on ~2% of calls (no daemon).
export PATTER_LOG_RETENTION_DAYS=30

# Keep forever — opt out of automatic cleanup
export PATTER_LOG_RETENTION_DAYS=0
```

<Warning>
  Retention defaults to **30 days**. Phone numbers in `metadata.json` default to **full** (raw E.164) since 0.6.2 so the dashboard's reveal toggle has something to reconstruct from — set `PATTER_LOG_REDACT_PHONE=mask` for setups that ship logs off-host. Gate access to the log root regardless, since `transcript.jsonl` is never redacted and may contain customer PII spoken during the call.
</Warning>

See [Call logging](/python-sdk/call-logging) for the full layout, schema, and reading patterns.

## Loading from .env

```python theme={null}
import os
from dotenv import load_dotenv
from getpatter import Patter, Twilio, OpenAIRealtime

load_dotenv()

phone = Patter(
    carrier=Twilio(),                                 # reads TWILIO_* from env
    phone_number=os.environ["PHONE_NUMBER"],
    webhook_url=os.environ["WEBHOOK_URL"],
)

agent = phone.agent(
    engine=OpenAIRealtime(),                          # reads OPENAI_API_KEY
    system_prompt="You are a helpful assistant.",
)
```

<Warning>
  Never hardcode API keys, tokens, or secrets in your source code. Always use environment variables or a secret manager.
</Warning>
