On-demand calling is for voice campaigns.
Before You Start
1
Set up a voice campaign
The campaign needs an AI agent assigned on its Setup tab, and that agent needs at least one phone number bought in the Studio: on-demand calls come from the agent’s own numbers. It also needs a saved Schedule, because on-demand calls are only dialed inside the campaign’s Calling Hours. See Campaign Setup, Scheduling and Phone Numbers.
2
Copy the campaign ID
Open Manage → Campaigns → your campaign → On-Demand. The campaign ID is at the top with a copy button — that ID goes in the request path.Campaigns isn’t in the default sidebar for the Agent Builder role. Add it with Customize sidebar, or press Cmd/Ctrl+K and search for it. See Navigating Studio.
3
Create an API key
On that same On-Demand tab, click API reference, then Manage API Keys, and create a key. API Keys has no sidebar or search entry, so that button is the way in from Studio; you can also add
/manage/api-keys to your Studio address. The key is shown once — copy it then. See API Keys.The On-Demand Tab
Every campaign has an On-Demand tab, at Manage → Campaigns → your campaign. It holds:- The campaign ID, with a copy button.
- Refresh — reloads the on-demand activity and confirms with “On-demand activity refreshed”.
- API reference — a drawer with your API base URL as its own copyable field, plus ready-to-run curl and JavaScript snippets for all three endpoints, and a Manage API Keys button.
- A status card for the campaign’s on-demand run, once your first call has landed. It shows the run’s status, how many calls are in progress, when the run ended if it has, and a count for each problem outcome (for example blocked, failed, busy or no answer). Before that the tab reads “No on-demand calls yet” — the run is created for you by the first successful request, so there is nothing to set up.
Copy the base URL from the API reference drawer rather than assuming it — it differs between environments, and the drawer always shows the correct one for the Studio you are signed in to.
Place a Call
Request fields
How
scheduled_at is interpreted:
- With an offset or a
Z, it is a self-contained instant and is used as-is. - Without one, it is read in
scheduled_at_timezoneif you supplied that. - Without either, it is read in the timezone derived from the
postcode.
Response
dialing_status is pending for an immediate call and callback_requested for a scheduled one. Keep the request_id — it is the reference you can cancel by, and the only identifier you hold if you did not store contact_id.
Cancel a Call
A call can be cancelled while it is still waiting to be dialed. Either identifier works:already_cancelled telling you which of the two things happened:
already_cancelled: true. A contact can actually be cancelled while it is pending, queued for a retry (retry — for example waiting for the calling hours to open, or backing off after a busy or no answer), or scheduled for later (callback_requested). Once a dial is in progress or finished there is nothing to stop.
Responses and Errors
Requests are rate limited by IP address, at roughly 1,000 requests a minute. Systems that share one outbound IP address share that allowance. Go over it and you get a
429, and further requests can keep getting 429 for a few minutes, so back off before retrying.
Things to Design Around
There is no idempotency key
There is no idempotency key
A retried
POST places a second real call. Repeat submissions of the same phone number are accepted deliberately — each one is its own attempt with its own request_id — so de-duplicate on your side, and store the request_id you get back.48 hours is a hard ceiling
48 hours is a hard ceiling
Anything further out is rejected with a
400. There is no long-horizon scheduler behind this endpoint. To call someone next week, hold the request in your own system until it is inside the window.On-demand calls take concurrency first
On-demand calls take concurrency first
A campaign’s on-demand run can be dialing at the same time as a CSV run, and the on-demand run has first claim on the campaign’s
max_concurrent_calls budget. While on-demand traffic is flowing, the CSV run visibly dials fewer calls per tick — and nothing in the Studio explains the slowdown. Raise the campaign’s concurrency if both need to run hard at once.Pause and Stop don't reach the on-demand run
Pause and Stop don't reach the on-demand run
Pause, Resume and Stop on a campaign act on its CSV runs, not on the on-demand run. A paused campaign still accepts and dials on-demand calls. Only a stopped or failed campaign refuses new requests, and calls you already sent keep going. To halt those, cancel them from On-Demand activity.
The on-demand run always uses current settings
The on-demand run always uses current settings
A CSV run is frozen at launch: it keeps immutable snapshots of the settings, schedule and agent. The on-demand run is not. It re-reads the campaign’s dialing settings and schedule on every request, which is why its cards are labelled “current” rather than “snapshot”. Editing them therefore changes on-demand calling immediately, with no relaunch — convenient, but easy to do by accident.Caller IDs are the exception. On-demand calls come from the phone numbers of the agent the campaign had when its first on-demand call arrived. If you change the campaign’s agent later, the new agent handles the calls, but they still go out from the first agent’s numbers, and a contact who calls back reaches the first agent. Adding or removing numbers on that first agent does take effect on the next dial.
There is no status read-back
There is no status read-back
The response is fire-and-forget. There is no key-authenticated way to ask how a call went — outcomes live in the Studio, on the On-Demand activity list and in Call History.
Compliance Still Applies
Placing a call through the API skips the CSV, not the rules. Every compliance gate is evaluated again at dial time, exactly as it is for a CSV run:- The campaign’s own Calling Hours from its Schedule tab. A call requested outside them waits in the queue and is dialed when the window opens, and you can still cancel it while it waits.
- Legal calling hours for the contact’s resolved timezone, and TCPA restrictions — see Scheduling.
- Prior express written consent, and voice opt-out. A contact without
has_pewc: trueand apewc_date, or withis_voice_call_opted_out: true, is Blocked and never dialed. - DNC scrubbing, with its scrub fee — see Compliance & DNC.
- Frequency caps.
Where On-Demand Activity Shows Up
This keeps your CSV run reporting comparable across launches, with Compare as the one exception. When you need the on-demand picture, go to the tab.
Where to go next
API Keys
Create and revoke the keys this API authenticates with.
Campaign Setup
Assign the agent, check the numbers it calls from, and set the dialing settings on-demand calls will use.