by PatterAI
Open-source voice-AI SDK. The Vapi/Retell alternative for builders who want to own the stack. Give your AI agent a phone number in 4 lines — Python and TypeScript, MIT licensed, Twilio + Telnyx.
# Add to your Claude Code skills
git clone https://github.com/PatterAI/PatterNo comments yet. Be the first to share your thoughts!
Patter is the open-source SDK that gives your AI agent a phone number. Point it at any function that returns a string, and Patter handles the rest: telephony, speech-to-text, text-to-speech, and real-time audio streaming. You build the agent — we connect it to the phone.
Set the env vars your carrier and engine need:
Twilio
export TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export TWILIO_AUTH_TOKEN=your_auth_token
export OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
Telnyx
export TELNYX_API_KEY=KEYxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export TELNYX_CONNECTION_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
pip install getpatter
from getpatter import Patter, Twilio, OpenAIRealtime
phone = Patter(carrier=Twilio(), phone_number="+15550001234")
agent = phone.agent(engine=OpenAIRealtime(), system_prompt="You are a friendly receptionist for Acme Corp.", first_message="Hello! How can I help?")
await phone.serve(agent, tunnel=True)
Or with Telnyx:
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 for Acme Corp.", first_message="Hello! How can I help?")
await phone.serve(agent, tunnel=True)
npm install getpatter
import { Patter, Twilio, OpenAIRealtime } from "getpatter";
const phone = new Patter({ carrier: new Twilio(), phoneNumber: "+15550001234" });
const agent = phone.agent({ engine: new OpenAIRealtime(), systemPrompt: "You are a friendly receptionist for Acme Corp.", firstMessage: "Hello! How can I help?" });
await phone.serve({ agent, tunnel: true });
Or with Telnyx:
import { Patter, Telnyx, OpenAIRealtime } from "getpatter";
const phone = new Patter({ carrier: new Telnyx(), phoneNumber: "+15550001234" });
const agent = phone.agent({ engine: new OpenAIRealtime(), systemPrompt: "You are a friendly receptionist for Acme Corp.", firstMessage: "Hello! How can I help?" });
await phone.serve({ agent, tunnel: true });
tunnel: true spawns a Cloudflare quick tunnel and points your Twilio number at it — great for dev / acceptance. For production outbound calls (especially on Twilio), replace it with ngrok or a static webhook_url to avoid WSS upgrade races on first call. See Tunneling for details.
Every carrier and provider reads its credentials from environment variables by default; see each SDK's README for the full catalog.
Patter is purpose-built for production voice over real telephony. Out of the box you get Twilio + Telnyx parity (DTMF, transfer, AMD, voicemail drop, recording), both architectures from one API — speech-to-speech (Realtime / ConvAI engines) and the sandwich pipeline (STT → LLM → TTS) — and production-grade barge-in / VAD / IVR primitives that work the same on every carrier. Observability is vendor-neutral OpenTelemetry tracing, plus a built-in dashboard and tunnel; no extra collector required. The 4-line quickstart above replaces ~50 lines of glue you'd otherwise write against a generic voice-agent toolkit, and the Python and TypeScript SDKs are identical — same surface, same hooks, same events — so cross-runtime teams ship the same agent twice without rewriting it.
| Feature | Method | Template |
|---|---|---|
| Inbound calls | phone.serve(agent) | patter-inbound-agent |
| Outbound calls + AMD | phone.call(to, machineDetection) | patter-outbound-calls |
| Tool calling (webhooks) | agent(tools=[...]) | patter-tool-calling |
| Custom STT + TTS | agent(provider="pipeline") | patter-custom-voice |
| Dynamic variables | agent(variables={...}) | patter-dynamic-variables |
| Custom LLM (any model) | serve(onMessage=handler) | patter-custom-llm |
| Dashboard + metrics | serve(dashboard=True) | patter-dashboard |
| Output guardrails | agent(guardrails=[...]) | docs |
| Call recording | serve(recording=True) | docs |
| Call transfer | transfer_call (auto-injected) | docs |
| Voicemail drop | call(voicemailMessage="...") | patter-outbound-calls |
| Test mode (no phone) | phone.test(agent) | docs |
| Built-in tunnel | Cloudflare (auto) | docs |
| Phone-as-a-tool (LangChain / OpenAI Assistants / Hermes) | PatterTool(phone, agent).execute(...) | docs |
From code to phone call — Your AI agent connects to real phone calls through the Patter SDK.
Each template is a self-contained repo — clone, add your .env, and run. Both Python and TypeScript included.
| Template | Description | Repo | |---|---|---| | Inbound Agent | Answer calls as a restaurant booking assistant | patter-inbound-agent | | Outbound Calls | Place calls with AMD and voicemail drop | patter-outbound-calls | | Tool Calling | CRM lookup + ticket creation via webhook tools | patter-tool-calling | | Custom Voice | Pipeline mode: Deepgram STT + ElevenLabs TTS | patter-custom-voice | | Dynamic Variables | Personalize prompts per caller using CRM data | patter-dynamic-variables | | Custom LLM | Bring your own model (Claude, Mistral, LLaMA) | patter-custom-llm | | Dashboard | Real-time monitoring with cost + latency tracking | patter-dashboard | | Production Setup | Everything enabled: tools, guardrails, recording, dashboard | patter-production |
# Example: clone and run the inbound agent template
git clone https://github.com/PatterAI/patter-inbound-agent
cd patter-inbound-agent
cp .env.example .env # fill in your keys
cd python && pip install -r requirements.txt && python main.py
| Variable | Required | Description |
|---|---|---|
| OPENAI_API_KEY | Yes (Realtime mode) | OpenAI API key with Realtime access |
| TWILIO_ACCOUNT_SID | Yes | Twilio account SID |
| TWILIO_AUTH_TOKEN | Yes | Twilio auth token |
| TWILIO_PHONE_NUMBER | Yes | Your Twilio phone number (E.164) |
| TELNYX_API_KEY | Yes (Telnyx) | Telnyx API key |
| TELNYX_CONNECTION_ID | Yes (Telnyx) | Telnyx Call Control Application connection ID |
| TELNYX_PHONE_NUMBER | Yes (Telnyx) | Your Telnyx phone number (E.164) |
| DEEPGRAM_API_KEY | Pipeline mode | Deepgram STT key |
| ELEVENLABS_API_KEY | Pipeline mode | ElevenLabs TTS key |
| ANTHROPIC_API_KEY | Custom LLM | For bringing your own model |
| WEBHOOK_URL | No | Public URL (auto-tunneled via Cloudflare if omitted) |