Developer SDK for Unpod voice infrastructure — management, connectivity, and adapters for building voice agents that talk over real phone calls, browsers, and WebRTC.
Single architectural commitment: the wire between Unpod infrastructure and your code carries text, not audio. You bring the Agent Runner; Unpod brings the voice.
pip install unpod
# With superdialog integration (recommended)
pip install "unpod[dialog]"
# With LangChain adapter
pip install "unpod[langchain]"
# With MCP adapter
pip install "unpod[mcp]"Or with uv: uv add unpod (extras: uv add "unpod[dialog]").
To install the latest unreleased code from source:
pip install "unpod @ git+https://github.com/unpod-ai/unpod-python-sdk"unpod
├── Management SDK (REST) numbers, voice profiles, speech pipes, calls,
│ sessions, trunks, recordings, transcripts, api keys
├── Connectivity SDK (WSS) AgentRunner, Session, CallContext, hooks
└── Adapters superdialog, LangChain, OpenAI, Anthropic, HTTP, MCP
- Management SDK — CRUD against the Unpod Control Plane: manage numbers (sync/attach/release), browse voice profiles, bind Speech Pipes, trigger and inspect calls.
- Connectivity SDK — runtime for live calls: a long-lived
AgentRunnerreceives plain-text turns over WSS and dispatches them to your agent, regardless of transport (phone, browser, WebRTC). - Adapters — plug any dialog logic into a call:
superdialogdialog machines, LangChain runnables, your own HTTP endpoint, or an MCP server.
Configure once — the Quickstart
explains why the REST base is the bare host (pipes/calls/numbers spell
the full /api/v2/platform/speech/... prefix inside their own request paths, so
the derived https://<host>/platform base would double it):
export UNPOD_BASE_URL="https://api.unpod.ai" # one knob for the rest
export UNPOD_SERVICE_BASE_URL="https://api.unpod.ai" # bare host: pipes/calls/numbers
export UNPOD_PLATFORM_TOKEN="..." # org-scoped REST auth
export UNPOD_ORG_HANDLE="your-org"
export UNPOD_API_KEY="sk_..." # AgentRunner (Bearer)from unpod import AsyncClient, AgentRunner, CallContext
client = AsyncClient() # picks up the env above; token auth wins over UNPOD_API_KEY
# Management: pick a voice, bind a Speech Pipe to your agent
profiles = await client.voice_profiles.list(language="en")
pipe = await client.pipes.create(
name="support-line",
voice_profile=profiles[0].id, # a catalog name works too
agent_id="my-voice-agent",
)
# Connectivity: handle every live call with your own logic
async def entrypoint(ctx: CallContext) -> None:
await ctx.session.say("Hi! How can I help you today?")
await ctx.session.run()
AgentRunner(entrypoint=entrypoint, agent_id="my-voice-agent").start()voice_profiles and client.telephony.* read the org-scoped platform plane, so
they need UNPOD_PLATFORM_TOKEN + UNPOD_ORG_HANDLE — a Bearer UNPOD_API_KEY
alone cannot reach them.
| Guide | What it covers |
|---|---|
| Overview | What Unpod owns vs what you own, the three layers |
| Quickstart | Install to a dispatched call, transcribed from a live run |
| Run your agent | Where the runner process lives (local vs Publish), the identity trio, reconnection and failover, the four call_end reasons |
| Management SDK | REST client API reference |
| Connectivity SDK | AgentRunner, Session, hooks, controls |
| Adapters | The DialogAdapter protocol led by the stream() hot path, the six bundled adapters, and how to write your own |
| Deployment | The three shipped ways an agent reaches traffic — LLM endpoint, voice agent, phone number |
| Browser quickstart | Testing an agent in the browser with no phone number, via examples/browser_playground/ |
The old Architecture guide was archived on 2026-07-30 — package structure and data flow are now in Overview, concurrency and multi-replica in Run your agent and Connectivity SDK. It is kept, with a banner listing what did not survive a code check, at docs/archive/05-architecture.md.
Full index, including the archive:
docs/README.md.
Full platform documentation: docs.unpod.ai
git clone https://github.com/unpod-ai/unpod-python-sdk
cd unpod-python-sdk
uv sync --extra dev
uv run pytest