Skip to main content

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.

Python Quickstart

Patter connects an AI agent to a real phone number in four lines of Python. This page walks you end-to-end: install, credentials, the four lines, and your first call.

Prerequisites

  • Python 3.11+
  • A Twilio or Telnyx account with a phone number you own
  • An AI provider key — OpenAI for the default Realtime engine, or any supported STT/TTS pair for pipeline mode

Step 1 — Install

pip install getpatter

Step 2 — Set environment variables

Each carrier and engine reads its credentials from the environment by default. The four-line quickstart below works as-is once these are set.
# Telephony — pick one carrier
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token

# Realtime engine (default)
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
VariablePurpose
TWILIO_ACCOUNT_SIDAccount SID from the Twilio console. Starts with AC.
TWILIO_AUTH_TOKENAuth token paired with the SID. Keep it secret.
OPENAI_API_KEYUsed by OpenAIRealtime, WhisperSTT, and OpenAITTS.
Using Telnyx instead? Swap the Twilio vars for TELNYX_API_KEY and TELNYX_CONNECTION_ID (plus optional TELNYX_PUBLIC_KEY for webhook signature verification) and use Telnyx() in place of Twilio(). See the Carrier page for all supported env vars.

Step 3 — The four-line quickstart

Create main.py:
main.py
from getpatter import Patter, Twilio, OpenAIRealtime

phone = Patter(carrier=Twilio(), phone_number="+15550001234")
agent = phone.agent(engine=OpenAIRealtime(), system_prompt="You are a receptionist.")
await phone.serve(agent, tunnel=True)
Want a custom greeting? Add first_message="...":
agent = phone.agent(
    engine=OpenAIRealtime(),
    system_prompt="You are a friendly receptionist for Acme Corp.",
    first_message="Hello! How can I help?",
)
What each line does:
  1. Import — the three primitives you need: the client, a carrier, and an engine. All three read credentials from environment variables by default, so no keys appear in source.
  2. Patter(...) — build the client and bind it to your phone number. Twilio() (or Telnyx()) carries the carrier credentials; swap it to change providers.
  3. phone.agent(...) — describe the agent: the engine (OpenAI Realtime by default), the system prompt, and the first message it speaks on answer.
  4. await phone.serve(agent, tunnel=True) — start the embedded server. tunnel=True spawns a Cloudflare tunnel and points your Twilio number at it automatically, so the agent is reachable from the PSTN without any additional DNS or firewall work.
tunnel=True is the dev shorthand. In production replace it with a stable webhook URL via the constructor:
phone = Patter(carrier=Twilio(), phone_number="+15550001234", webhook_url="api.prod.example.com")
...
await phone.serve(agent)
Or use a pre-provisioned tunnel object: Patter(..., tunnel=Static(hostname="agent.example.com")). See Tunneling.

Step 4 — Run it

python main.py
You’ll see the Patter banner, a Cloudflare tunnel URL, and a log line confirming the Twilio voice webhook was set to that URL.

Step 5 — Call the number

Pick up your phone, dial your Twilio number, and the agent will answer with "Hello! How can I help?". Start talking.
Since 0.6.2, Patter(...) persists per-call records (metadata.json, transcript.jsonl, events.jsonl) to the platform default data directory by default so the local dashboard’s call history survives process restarts. Pass persist=False to keep the old ephemeral-RAM-only behaviour, or persist="/custom/path" to choose a different location. See Call logging for the full layout.

Using a different engine

OpenAI Realtime is the default. To switch engines, pass a different instance:
from getpatter import Patter, Twilio, ElevenLabsConvAI

phone = Patter(carrier=Twilio(), phone_number="+15550001234")
agent = phone.agent(engine=ElevenLabsConvAI(), system_prompt="You are a helpful assistant.")
await phone.serve(agent, tunnel=True)
ElevenLabsConvAI() reads ELEVENLABS_API_KEY and ELEVENLABS_AGENT_ID from the environment. For the STT + LLM + TTS pipeline mode, pick each stage independently:
from getpatter import Patter, Twilio, DeepgramSTT, AnthropicLLM, ElevenLabsTTS

phone = Patter(carrier=Twilio(), phone_number="+15550001234")
agent = phone.agent(
    stt=DeepgramSTT(),                    # reads DEEPGRAM_API_KEY
    llm=AnthropicLLM(),                   # reads ANTHROPIC_API_KEY
    tts=ElevenLabsTTS(voice_id="rachel"), # reads ELEVENLABS_API_KEY
    system_prompt="You are a helpful assistant.",
    first_message="Hello!",
)
await phone.serve(agent, tunnel=True)
Swap AnthropicLLM() for OpenAILLM(), GroqLLM(), CerebrasLLM(), or GoogleLLM() — tool calling works across all five. Need fully custom LLM logic? Drop llm= and pass on_message=handler to serve() instead.

Non-English agents

OpenAI Realtime auto-detects the spoken language from the inbound audio and matches the language of your system_prompt. Writing the prompt in the target language is the primary control:
# Japanese — write the prompt in Japanese.
agent = phone.agent(
    engine=OpenAIRealtime(),
    system_prompt="あなたは丁寧な日本語のアシスタントです。",
    first_message="お電話ありがとうございます。ご用件をお伺いします。",
)
The language="ja" parameter on OpenAIRealtime only seeds the auto-generated fallback prompt ("Respond in {language}") when you don’t supply your own system_prompt. It does not configure the Realtime API session itself. For pipeline mode the STT needs the language code so it can pick the right acoustic model:
agent = phone.agent(
    stt=DeepgramSTT(language="ja"),        # required: Deepgram needs the JP model
    llm=AnthropicLLM(),                    # LLM responds in whatever language you prompt it in
    tts=ElevenLabsTTS(voice_id="..."),     # ElevenLabs auto-detects from text; pick a voice that supports JP
    system_prompt="あなたは丁寧な日本語のアシスタントです。",
)
E.164 formatting for international calls: outbound to= values must be E.164. Many regions drop the trunk-zero — Japanese numbers like 090-xxxx-xxxx are dialled as +81XXXXXXXXX (drop the leading 0).

What’s next

Configuration

Every constructor option in one place.

Agents

Customize voice, model, tools, and guardrails.

STT providers

Deepgram, Whisper, Cartesia, Soniox, Speechmatics, AssemblyAI.

TTS providers

ElevenLabs, OpenAI, Cartesia, Rime, LMNT.

Tools

Give your agent function-calling superpowers.