Unpod Python SDK
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.
Installation
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"
What's Inside
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.
Quick Example
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
# Create an embedded voice agent directly from a prompt (no runner/publish step)
embedded = await client.agent.voice.create(
name="support-line",
voice_profile="VP_openai_alloy",
prompt="You are a concise, helpful support assistant.",
)
# 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.
Documentation
| 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
Development
git clone https://github.com/unpod-ai/unpod-python-sdk
cd unpod-python-sdk
uv sync --extra dev
uv run pytest
License
Metadata
Release files for unpod 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unpod-0.2.1.tar.gz | 217.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unpod-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 308.3 kB
Release files / unpod-0.2.1.tar.gz
| Download URL | unpod-0.2.1.tar.gz |
|---|---|
| Size | 217.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3d7e398f3148cb6bd0ab348aa19f3413a299d51a1a2c8ca676e318595918861f
|
|
BLAKE2b-256 checksum How to use checksums |
b5fb8c6201744f9e3607828fdf3568b98e3b6bc756aadbce057e2b0bd86be65a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.12
|
Release files / unpod-0.2.1-py3-none-any.whl
| Download URL | unpod-0.2.1-py3-none-any.whl |
|---|---|
| Size | 90.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ec623ba331bc2df2af392c9c6479525895e797acd258aee503fc6ee487b6506f
|
|
BLAKE2b-256 checksum How to use checksums |
1d7d68199742c8673ba14aed3438ddecd362f1b91281846f26d959abcbc8244d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.12
|