Skip to main content

Documentation Index

Fetch the complete documentation index at: https://patter-06b046ce-feat-observability-otel-attrs-0-6-1.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

API Reference

Complete reference for the getpatter Python SDK.

Patter

The main SDK client class.

Constructor

Patter(
    carrier: Twilio | Telnyx | None = None,
    phone_number: str = "",
    webhook_url: str = "",
    tunnel: CloudflareTunnel | Static | bool | None = None,
    pricing: dict | None = None,
)
ParameterTypeDefaultDescription
carrierTwilio | Telnyx | NoneNoneTelephony carrier instance. Reads credentials from env vars when arguments are omitted.
phone_numberstr""Phone number in E.164 format.
webhook_urlstr""Public hostname, no scheme.
tunnelCloudflareTunnel | Static | bool | NoneNoneTunnel directive. True is shorthand for CloudflareTunnel().
pricingdict | NoneNoneOverride default provider pricing. See Metrics & Cost Tracking.

Methods

agent()

def agent(
    system_prompt: str,
    engine: OpenAIRealtime | ElevenLabsConvAI | None = None,
    stt: STTProvider | None = None,
    llm: LLMProvider | None = None,
    tts: TTSProvider | None = None,
    voice: str = "alloy",
    model: str = "gpt-4o-mini-realtime-preview",
    language: str = "en",
    first_message: str = "",
    tools: list[Tool] | None = None,
    variables: dict | None = None,
    guardrails: list[Guardrail] | None = None,
    hooks: PipelineHooks | None = None,
    text_transforms: list[Callable] | None = None,
    vad: VADProvider | None = None,
    audio_filter: AudioFilter | None = None,
    background_audio: BackgroundAudioPlayer | None = None,
    barge_in_threshold_ms: int = 300,
    aggressive_first_flush: bool = False,
    disable_phone_preamble: bool = False,
) -> Agent
Pass engine=OpenAIRealtime(...) or engine=ElevenLabsConvAI(...) for end-to-end engines; omit engine= and pass stt=/tts= for pipeline mode.
ParameterTypeDefaultDescription
system_promptstrrequiredAgent instructions.
engineOpenAIRealtime | ElevenLabsConvAI | NoneNoneEnd-to-end voice runtime. Omit for pipeline mode.
sttSTTProvider | NoneNoneSTT instance for pipeline mode (e.g. DeepgramSTT()).
llmLLMProvider | NoneNoneLLM provider instance for pipeline mode (e.g. AnthropicLLM()). Mutually exclusive with on_message on serve(). Ignored when engine is set.
ttsTTSProvider | NoneNoneTTS instance for pipeline mode (e.g. ElevenLabsTTS()).
voicestr"alloy"TTS voice name (when engine doesn’t carry it).
modelstr"gpt-4o-mini-realtime-preview"AI model ID (when engine doesn’t carry it).
languagestr"en"BCP-47 language code.
first_messagestr""Greeting spoken at call start.
toolslist[Tool] | NoneNoneTool(...) instances for function calling.
variablesdict | NoneNoneDynamic {placeholder} variable substitutions.
guardrailslist[Guardrail] | NoneNoneGuardrail(...) instances applied to LLM output.
hooksPipelineHooks | NoneNonePipeline hooks for STT/TTS interception.
text_transformslist[Callable] | NoneNoneText transformation functions (pipeline mode).
vadVADProvider | NoneNoneVoice activity detection provider (pipeline mode).
audio_filterAudioFilter | NoneNoneAudio preprocessing filter (pipeline mode).
background_audioBackgroundAudioPlayer | NoneNoneBackground audio player (pipeline mode).
barge_in_threshold_msint300Barge-in hang-over window (ms). Set to 0 to disable.
aggressive_first_flushboolFalseEmit the first clause on a soft punctuation boundary (,, em/en-dash) once buffer ≥40 chars. Saves 200–500 ms TTFA. Hard-disabled when language starts with "it". Pipeline mode only.
disable_phone_preambleboolFalseDisable the phone-friendly preamble Patter prepends to system_prompt (no markdown / emojis / lists, numbers spelled out, replies kept short). Default False keeps the preamble on.
Raises: ValueError if required credentials are missing or conflicting options are passed (e.g. both engine and stt/tts).

serve()

async def serve(
    agent: Agent,
    port: int = 8000,
    recording: bool = False,
    on_call_start: Callable[[dict], Awaitable[None]] | None = None,
    on_call_end: Callable[[dict], Awaitable[None]] | None = None,
    on_transcript: Callable[[dict], Awaitable[None]] | None = None,
    on_message: Callable[[dict], Awaitable[str]] | str | None = None,
    on_metrics: Callable[[dict], Awaitable[None]] | None = None,
    voicemail_message: str = "",
    dashboard: bool = True,
    dashboard_token: str = "",
    tunnel: bool = False,
) -> None
Start the embedded server. Blocks until stopped.

call()

async def call(
    to: str,
    first_message: str = "",
    from_number: str = "",
    agent: Agent | None = None,
    machine_detection: bool = False,
    on_machine: Callable[[dict], Awaitable[None]] | None = None,
    voicemail_message: str = "",
    ring_timeout: int | None = None,
) -> None
Make an outbound call.

test()

async def test(
    agent: Agent,
    on_message: Callable[[dict], Awaitable[str]] | None = None,
    on_call_start: Callable[[dict], Awaitable[None]] | None = None,
    on_call_end: Callable[[dict], Awaitable[None]] | None = None,
) -> None
Start an interactive terminal test session. Simulates a phone call without telephony, STT, or TTS — pure text input/output. See Test Mode.

disconnect()

async def disconnect() -> None
Disconnect from Patter. Stops the embedded server.

Carriers

from getpatter import Twilio, Telnyx                 # flat aliases
from getpatter.carriers import twilio, telnyx        # namespaced (twilio.Carrier, telnyx.Carrier)

Twilio

@dataclass(frozen=True)
class Twilio:
    account_sid: str = ""   # reads TWILIO_ACCOUNT_SID when empty
    auth_token: str = ""    # reads TWILIO_AUTH_TOKEN when empty

Telnyx

@dataclass(frozen=True)
class Telnyx:
    api_key: str = ""       # reads TELNYX_API_KEY when empty
    connection_id: str = "" # reads TELNYX_CONNECTION_ID when empty
    public_key: str = ""    # optional — reads TELNYX_PUBLIC_KEY when empty

Engines

from getpatter import OpenAIRealtime, ElevenLabsConvAI              # flat aliases
from getpatter.engines import openai, elevenlabs                     # namespaced

OpenAIRealtime

@dataclass(frozen=True)
class OpenAIRealtime:
    api_key: str = ""                                # reads OPENAI_API_KEY when empty
    voice: str = "alloy"
    model: str = "gpt-4o-mini-realtime-preview"

ElevenLabsConvAI

@dataclass(frozen=True)
class ElevenLabsConvAI:
    api_key: str = ""                                # reads ELEVENLABS_API_KEY when empty
    agent_id: str = ""                               # reads ELEVENLABS_AGENT_ID when empty
    voice: str = ""                                  # override agent's default voice

STT classes

from getpatter import DeepgramSTT, WhisperSTT, CartesiaSTT, AssemblyAISTT, SonioxSTT
from getpatter.stt import deepgram, whisper, cartesia, assemblyai, soniox, speechmatics
All classes accept api_key: str | None = None and fall back to the provider’s standard env var. See the STT page for full constructor signatures.

TTS classes

from getpatter import ElevenLabsTTS, ElevenLabsWebSocketTTS, OpenAITTS, CartesiaTTS, RimeTTS, LMNTTTS
from getpatter.tts import elevenlabs, elevenlabs_ws, openai, cartesia, rime, lmnt
All classes accept api_key: str | None = None and fall back to the provider’s standard env var. See the TTS page for full constructor signatures.

LLM providers

from getpatter import OpenAILLM, AnthropicLLM, GroqLLM, CerebrasLLM, GoogleLLM   # flat
from getpatter.llm import openai, anthropic, groq, cerebras, google              # namespaced
All classes accept api_key: str | None = None and fall back to the provider’s standard env var (GoogleLLM prefers GEMINI_API_KEY, falls back to GOOGLE_API_KEY). See the LLM page for full constructor signatures and tool-calling semantics. Pass an instance via phone.agent(llm=...) for pipeline mode. llm= is mutually exclusive with on_message on serve() and is ignored when engine= is set.

Tunnels

from getpatter.tunnels import CloudflareTunnel, Static, Ngrok
ClassBehavior
CloudflareTunnel()Auto-start a Cloudflare Quick Tunnel via the local cloudflared binary.
Static(hostname=...)Use an existing public hostname (user-managed tunnel, e.g. ngrok).
Ngrok(hostname=...)Use an existing ngrok hostname (you run ngrok http 8000 yourself). Same behavior as Static(hostname=...) with an ngrok-friendly name.
tunnel=True on Patter(...) is shorthand for tunnel=CloudflareTunnel().

Tools & Guardrails

from getpatter import Tool, Guardrail, tool, guardrail

Tool

@dataclass(frozen=True)
class Tool:
    name: str
    description: str = ""
    parameters: dict | None = None
    handler: Callable | None = None
    webhook_url: str = ""
Either handler or webhook_url must be provided. tool(...) is a factory that doubles as a decorator — see Tools.

Guardrail

@dataclass(frozen=True)
class Guardrail:
    name: str
    blocked_terms: list[str] | None = None
    check: Callable[[str], bool] | None = None
    replacement: str = "I'm sorry, I can't respond to that."
See Guardrails.

Data Classes

All data classes are frozen (immutable) dataclasses.

Agent

@dataclass(frozen=True)
class Agent:
    system_prompt: str
    voice: str = "alloy"
    model: str = "gpt-4o-mini-realtime-preview"
    language: str = "en"
    first_message: str = ""
    tools: list[dict] | None = None
    provider: str = "openai_realtime"
    stt: STTConfig | STTProvider | None = None
    tts: TTSConfig | TTSProvider | None = None
    variables: dict | None = None
    guardrails: list | None = None
    hooks: PipelineHooks | None = None
    text_transforms: list[Callable] | None = None
    vad: VADProvider | None = None
    audio_filter: AudioFilter | None = None
    background_audio: BackgroundAudioPlayer | None = None
    barge_in_threshold_ms: int = 300
    aggressive_first_flush: bool = False
    disable_phone_preamble: bool = False
provider is a closed string literal — only "openai_realtime", "elevenlabs_convai", or "pipeline" are valid. It is normally derived from engine / stt+tts and rarely set by hand.

CallEvent

@dataclass(frozen=True)
class CallEvent:
    call_id: str
    caller: str = ""
    callee: str = ""
    direction: str = ""

IncomingMessage

@dataclass(frozen=True)
class IncomingMessage:
    text: str
    call_id: str
    caller: str

STTConfig / TTSConfig

Internal config dataclasses produced when you pass an STT/TTS instance to phone.agent(). You rarely need to construct these directly.

CallControl

Passed as the second argument to on_message handlers. Allows dynamic call management:
class CallControl:
    call_id: str
    caller: str
    callee: str
    telephony_provider: str

    async def transfer(number: str) -> None: ...
    async def hangup() -> None: ...

CallMetrics / CostBreakdown / LatencyBreakdown / TurnMetrics

See Metrics & Cost Tracking.

Exceptions

PatterError
├── PatterConnectionError
│   └── RateLimitError
├── AuthenticationError
└── ProvisionError
from getpatter import (
    PatterError,
    PatterConnectionError,
    AuthenticationError,
    ProvisionError,
    RateLimitError,
    ErrorCode,
)
Every Patter exception carries a stable, machine-readable ErrorCode on its code attribute. Branch on the code instead of class-name strings:
from getpatter import ErrorCode, PatterError

try:
    await phone.serve(agent)
except PatterError as exc:
    if exc.code is ErrorCode.AUTH:
        ...
    elif exc.code is ErrorCode.RATE_LIMIT:
        ...

ErrorCode values

CodeRaised when
CONFIGInvalid constructor args, missing required env var, frozen-config violation.
CONNECTIONWebSocket connect failure, HTTP 5xx from a provider, network error.
AUTHProvider rejected our credentials (HTTP 401/403, invalid signature).
TIMEOUTProvider response, voicemail post, or other awaited operation timed out.
RATE_LIMITProvider returned HTTP 429.
WEBHOOK_VERIFICATIONTwilio / Telnyx webhook signature verification failed.
INPUT_VALIDATIONCaller passed a malformed phone number, tool arg, etc.
PROVIDER_ERRORGeneric catch-all for unexpected upstream provider failures.
PROVISIONPhone number provisioning, webhook configuration, or carrier setup failed.
INTERNALAssertion failed / unexpected internal state. Likely a Patter bug.
ErrorCode is a StrEnum — values compare equal to their string form, so exc.code == "AUTH" also works for backward-compatible callers.

Audio helpers

from getpatter import builtin_clip_path, select_sound_from_list, resample_24k_to_16k
HelperPurpose
builtin_clip_path(name: str) -> PathResolve the on-disk path for a built-in BuiltinAudioClip (hold music, dial tones, hangup chimes) so callers can preload or copy them.
select_sound_from_list(sounds, *, rng=None) -> strPick one entry from a list of sound paths/IDs deterministically (or randomly when rng is provided). Useful for randomised hold music.
resample_24k_to_16k(pcm: bytes) -> bytesOne-shot 24 kHz → 16 kHz PCM resampler. Mirrors the helper Patter uses internally for OpenAI TTS chunks; exported for callers who need to do the same conversion outside the streaming loop.

Top-level exports

from getpatter import (
    # Client
    Patter,

    # Carriers
    Twilio, Telnyx,
    TwilioAdapter, TelnyxAdapter,                  # advanced: direct adapter access

    # Engines
    OpenAIRealtime, ElevenLabsConvAI,

    # STT classes
    DeepgramSTT, WhisperSTT, OpenAITranscribeSTT,
    CartesiaSTT, AssemblyAISTT, SonioxSTT, SpeechmaticsSTT,

    # TTS classes
    ElevenLabsTTS, ElevenLabsWebSocketTTS, OpenAITTS, CartesiaTTS, RimeTTS, LMNTTTS,

    # LLM classes
    OpenAILLM, AnthropicLLM, GroqLLM, CerebrasLLM, GoogleLLM,

    # VAD (opt-in: pip install 'getpatter[silero]')
    SileroVAD,

    # Integrations
    PatterTool,                                    # phone-as-a-tool for external agents

    # Public primitives
    Tool, Guardrail, tool, guardrail,

    # Data classes
    Agent, CallControl, CallEvent, CallMetrics, CostBreakdown,
    LatencyBreakdown, IncomingMessage, TurnMetrics, PipelineHooks,
    HookContext, STTConfig, TTSConfig,

    # Observability
    init_tracing, is_tracing_enabled, start_span,
    SPAN_CALL, SPAN_STT, SPAN_LLM, SPAN_TTS, SPAN_TOOL,
    SPAN_ENDPOINT, SPAN_BARGEIN,
    EventBus, PatterEventType,

    # Services / utilities
    SentenceChunker, PipelineHookExecutor,
    filter_markdown, filter_emoji, filter_for_tts,
    FallbackLLMProvider, AllProvidersFailedError, PartialStreamError,
    ChatContext, ChatMessage,
    IVRActivity, TfidfLoopDetector, DtmfEvent, format_dtmf,
    ScheduleHandle, schedule_cron, schedule_once, schedule_interval,
    BackgroundAudioPlayer, BuiltinAudioClip, mix_pcm,
    builtin_clip_path, select_sound_from_list, resample_24k_to_16k,

    # LLM primitives (see python-sdk/llm)
    LLMChunk, DefaultToolExecutor,

    # Errors
    PatterError, PatterConnectionError, AuthenticationError,
    ProvisionError, RateLimitError, ErrorCode,
)

from getpatter.carriers import twilio, telnyx
from getpatter.engines import openai, elevenlabs
from getpatter.stt import deepgram, whisper, openai_transcribe, cartesia, assemblyai, soniox, speechmatics
from getpatter.tts import elevenlabs, openai, cartesia, rime, lmnt
from getpatter.llm import openai, anthropic, groq, cerebras, google
from getpatter.tunnels import CloudflareTunnel, Static, Ngrok