Skip to main content
Go from zero to a live call: first you call a phone, then a phone calls you.
Preview. Call control is in preview. Ask the Unpod team to switch on the Call API for your org; until then every call returns 403 call_api_disabled. Coming from Plivo? See Migrate from Plivo.

Make your first call

1

Credentials

Export UNPOD_BASE_URL, UNPOD_PLATFORM_TOKEN and UNPOD_ORG_HANDLE as shown in Credentials.
2

Install

Python 3.12+ (unpod 0.6.2 requires it). cURL needs nothing.
3

Get a number

Add one from the dashboard (Get a Number) or run this once to attach an unassigned pool number:
attach_type="human_call" routes the number for call control, with no AI agent. A number already attached to an AI agent can also be the from of an outbound call; human_call matters for inbound calls, where it decides that your app answers instead of the agent.
Dial from a number whose connection_state is not NOT_LINKED (for example PENDING_VERIFY or LINKED). See it with the overview request from the credentials check. A 403 forbidden: from is not a number available to this organization means the number isn’t ready yet; a 400 from_not_owned means it isn’t one of your org’s numbers.
4

Call someone and speak

Set FROM to your Unpod number and TO to a phone you can answer, both in E.164. Pick up when it rings.
speak works once the call is talking - no server needed.
5

What you get back

After hangup, GET /sbc/v1/calls/{id} returns the recording summary instead of a state:
That url is a path inside Unpod. To download the audio, see Recording.
No ring? Check that to is E.164 (+ and country code), that the from number isn’t NOT_LINKED, and that ring_timeout gives the phone long enough.

Receive your first call

When someone calls your number, Unpod posts the call to your answer URL and runs the XML you reply with.
Inbound configuration needs the Call API switched on for your org: until then set_did (or the PUT in step 4) returns 403 call_api_disabled. Ask the Unpod team to switch it on.
1

Get your webhook secret

One signing key for all call events in your org. Create it once with rotate() (org owner or editor) - the only call that returns it in full - and store it as UNPOD_WEBHOOK_SECRET:
Rotating invalidates the previous secret, so any server already verifying with it stops working.
If pushed_to_sbc comes back false, Unpod retries the update in the background. Until it lands, events aren’t signed with the new secret and your server answers 401, so wait a minute before the test call.
2

Run a server

app.py
Run it with python app.py. It rejects unsigned requests, greets new calls and returns 200 for every other event.
3

Expose it

Install ngrok and add your authtoken first. Unpod only calls public https URLs. In a second terminal:
Copy the https forwarding URL, e.g. https://abc123.ngrok.app.
4

Point your number at it

Run this in another terminal (the server and ngrok hold the first two), with UNPOD_BASE_URL, UNPOD_PLATFORM_TOKEN and UNPOD_ORG_HANDLE exported:
set_did sets the config for one number. In the URL, + becomes %2B.
5

Call your number

Call your Unpod number from any phone. You hear “Hello! Thanks for calling.” and the call ends. For the full picture, see Incoming Calls.

Next

Multiple Participants

Bridge two people on one call.

Answer URL & XML

Reply to inbound calls with XML or JSON verbs.

Incoming Calls

Route inbound calls to your app or an Unpod agent.

Call Blasting

Call many numbers at once.