Connect your AI agent to a real phone number in minutes. Inbound calls, outbound dials, SMS and WhatsApp all arrive at one webhook as plain text. Use Python, Node, REST or MCP.
Unpod handles the phone and the speech. You receive text at your endpoint and reply with text. The prompt, tools and customer data stay on your side.
Our infra terminates phone and WebRTC audio, runs the speech layer, and exposes a text API. Our SDK is a thin client over that API โ drop it into any backend.
Phone calls, outbound dials and WebRTC sessions terminate inside Unpod. We deal with echo, jitter, codecs, barge-in, silence detection, streaming speech-to-text and text-to-speech. You never touch a raw audio frame.
A thin client over Unpod Infra. Read text events from a WebSocket, send text back. Wire it to LangChain, the OpenAI SDK, your own state machine or your own tools โ your conversation logic stays as simple or as complex as you need.
The full stack โ numbers, telephony, speech, messaging, webhooks โ is on GitHub. Run it on your own infrastructure and keep every byte of conversation data inside your zone.
Clone the repo, deploy with one Docker Compose. Run on your VPC, your bare metal, your air-gapped cluster โ no Unpod cloud dependency.
CPaaS primitives โ numbers, calls, messages, recording, webhooks โ exposed via SDK and MCP. Plug in Claude, OpenAI, your fine-tune, or your own logic.
Every transcript, recording and customer record stays inside your zone. Encrypted at rest by your KMS keys. Nothing crosses the wire to a third party.
Plug-in architecture for codecs, ASR / TTS providers, telephony carriers and storage. Ship a new voice provider in an afternoon, send it back upstream.
# Clone, configure, run โ your CPaaS in five lines. $ git clone https://github.com/essential-interfaces/unpod.git $ cd unpod && cp .env.example .env $ docker compose up -d $ unpod numbers buy --country IN --agent agt_123 # Your CPaaS is live on http://localhost:8080
No telecom plumbing. No separate SMS provider. One SDK, one webhook.
One API call. Pick a city or skip it and let us choose. +91 numbers are provisioned instantly across all major circles โ voice, SMS and WhatsApp on one number.
One API callVoice and messages arrive in the same event format. One handler covers both โ no separate pipelines for telephony and chat.
Single endpointCalls are transcribed in real time and sent to your webhook as text. Reply with text โ we handle the TTS, threading and silence detection.
Text in, text outYour agent is live with a real number. Inbound calls land in your handler, outbound dials and SMS go through the same SDK. Native MCP in Claude Code, Cursor, OpenClaw, Windsurf.
Live in productionReal things developers ship with Unpod โ from coding agents that take phone calls, to on-call pagers and 2FA inboxes.
Install the CLI on your server, point an Unpod number at it. Call the number, say "restart freeswitch" โ Claude Code does it. Cursor, Windsurf same way via MCP.
Give a long-running agent a real number so it can dial vendors, confirm orders and follow up โ without a human in the loop.
Answer inbound 24/7, qualify intent, book meetings, warm-transfer to a human with the full transcript handed over.
Pager-style escalation: your alerting AI dials the on-call engineer, reads the incident, escalates to the next person if no one picks up.
Trigger an outbound dial via one API call. Real-time text transcript streams back to your handler, sync to your CRM yourself.
Dedicated number for codes from Stripe, GitHub, banks. SMS arrives as text in the same webhook โ your agent reads and acts.
Handle inbound voice and SMS through one handler. Resolve routine queries, escalate complex issues with full call context.
Outbound dials to confirm bookings; rescheduling links go over SMS through the same SDK โ no separate provider.
Your existing agent stays where it lives โ LangChain, OpenAI SDK, your own Python loop. Unpod is the single endpoint that connects it to real-world voice, SMS and WhatsApp on a +91 number.
from unpod import Unpod
client = Unpod(api_key="up_...")
# Provision a +91 number for your agent
number = client.numbers.buy(country="IN", agent_id="agt_123")
# Place an outbound call โ your webhook gets every turn
call = client.calls.create(
agent_id="agt_123",
to_number="+9197XXXXXXXX",
webhook="https://api.yourapp.com/unpod"
)Drop a real phone number into any agent framework via SDK or MCP. Connect downstream to your CRM, helpdesk and channels โ no glue code, no separate SMS provider.
Numbers, webhooks, integration and security โ the things developers ask before shipping.
Join thousands of businesses that trust AI voice agents to handle their most important conversations. Free 14-day trial ยท no credit card ยท cancel anytime.