create and give every call the same answer URL. When
someone picks up, Unpod fetches it and plays your message. Host the message as a static XML
file and you need no server to send the calls. Haven’t made a call yet? Start with the
Quick Start.
1. Write the message
Say it in a platform voice with<Speak>, or play a recording with <Play>:
voice and language to <Speak> with real values. A
made-up value can make the speech fail, and the call then ends right after it’s answered.
Save either one as blast.xml. The audio file is a public https MP3 or WAV, given as the
text of <Play>. <Hangup/> is optional: Unpod hangs up when the last verb finishes. For
every verb, see Answer URL & XML.
Host blast.xml anywhere public over https that serves it without a redirect, such as
object storage or a CDN: Unpod doesn’t follow redirects. See
Serve a static file.
2. Dial the list
Put one E.164 number per line innumbers.txt, then run:
create returns as soon as Unpod accepts the call; it doesn’t wait for the phone to ring.
The script dials one number a second, because Unpod accepts at most 60 create and
add_participant requests a minute per org (3,600 numbers take about an hour). On a 429
(that limit, or your org’s call cap) or a network error it backs off and tries again; any
other error is listed at the end and the rest are still dialed. gave up after retries
means the 429s (or network errors) didn’t stop: run the script again later to pick those
numbers up. Fix the list and
run the script again: thanks to the idempotency key reminder-nov:<number>, a
re-run within 24 h doesn’t dial the same number twice, unless Unpod restarts (keys live in
memory). Use a new campaign name for a new blast.
Leave out status_callback_url if you don’t need step 3.
3. Track results
Unpod posts each call’s events tostatus_callback_url, with your metadata on every one
as ev.metadata. Outbound events don’t carry the number in ev.to, so it comes back from
the "to" you put in metadata. Record the outcome on Hangup. Create your
webhook secret first: status callbacks
are signed with it.
app.py
python app.py and expose it as in the
Quick Start. Unpod retries an event
that doesn’t get a 2xx a few times over about a minute
(Delivery and retries), so the same
Hangup can arrive twice; writing the outcome by number makes that harmless.
If your server is down for the whole retry window (roughly 27-75 s), the event is dropped
and that number never gets an outcome. A number missing from results is either still on
a call or lost its Hangup: list the live calls with
calls.list() (every page, until
one comes back empty) and check again
later.
Normal Hangup only means the call was answered. A duration shorter than your message
means they didn’t hear all of it. A voicemail that picks up, or a <Speak> or <Play>
that Unpod skipped because the speech or the audio failed, also shows Normal Hangup.
A burst of calls can pass the check in create (202) and still hit your org’s limit
while dialing. Those calls never ring and end with Service Unavailable (503).
To retry the busy, unanswered and not-dialed numbers, put them in a new numbers.txt and
run step 2 with a new campaign name, such as reminder-nov-retry.
Limits
- The answer URL and
status_callback_urlmust be public https, orcreatereturns400 invalid_url. A non-https audio URL insideblast.xmlmakes the reply fail, and the call stays connected in silence. See Answer URL & XML. createandadd_participanttogether are limited to 60 requests a minute per org. Over it, Unpod returns429withdetailRequest was throttled. Expected available in N seconds.and dials nothing.PACEkeeps the script under it. Eachcreatereturns right away, so up to 60 new calls can be ringing each minute.- Unpod can also cap your org’s concurrent calls. At the cap,
createreturns429and dials nothing, and the script backs off and retries. A call accepted right at the cap can still end withService Unavailable. - A reply can be at most 64 KB, with up to 32 verbs and 4096 characters in each
<Speak>.
Next
Number Masking
Connect two people without showing their numbers.
Answer URL & XML
Every verb you can put in the message.
Webhooks
Verify events and read every field.