Batch Calls

Place outbound calls to many recipients in a single API request

Batch calls let you dial a list of phone numbers through one of your voice agents in a single request. Each recipient can receive personalised variables (name, account number, appointment time, etc.) that your agent’s prompt references via {{key}} placeholders. Batches can run immediately or be scheduled up to 30 days in advance.

Create a batch call

Send a JSON body with the list of recipients. Each recipient needs a phone number in E.164 format. Any extra fields go into dynamic_vars and are injected as dynamic variables for that call.

$curl -X POST https://api.speechify.ai/v1/batch-calls \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Appointment reminders",
> "agent_id": "YOUR_AGENT_ID",
> "recipients": [
> {
> "phone": "+14155551234",
> "dynamic_vars": {
> "first_name": "Alice",
> "appointment_date": "May 5th at 2pm"
> }
> },
> {
> "phone": "+14155555678",
> "dynamic_vars": {
> "first_name": "Bob",
> "appointment_date": "May 6th at 10am"
> }
> }
> ]
> }'

The endpoint returns 202 Accepted. The batch starts dialing immediately in the background.

CSV upload (alternative)

You can also upload a CSV file via multipart/form-data. The CSV must have a phone column; all other columns become dynamic_vars.

1phone,first_name,appointment_date
2+14155551234,Alice,May 5th at 2pm
3+14155555678,Bob,May 6th at 10am
$curl -X POST https://api.speechify.ai/v1/batch-calls \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
> -F "name=Appointment reminders" \
> -F "agent_id=YOUR_AGENT_ID" \
> -F "csv_file=@recipients.csv"

Caller-ID override

By default each call uses the phone number bound to your agent. Pass phone_number_id to override the caller ID for the entire batch:

1{
2 "name": "Outreach campaign",
3 "agent_id": "YOUR_AGENT_ID",
4 "phone_number_id": "YOUR_PHONE_NUMBER_ID",
5 "recipients": [...]
6}

Schedule a batch

Set scheduled_at to an ISO 8601 timestamp (RFC 3339) to delay execution. The batch enters scheduled status and starts dialing at the specified time. You can schedule up to 30 days in advance.

$curl -X POST https://api.speechify.ai/v1/batch-calls \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Monday morning follow-ups",
> "agent_id": "YOUR_AGENT_ID",
> "scheduled_at": "2025-05-05T09:00:00Z",
> "recipients": [
> {"phone": "+14155551234", "dynamic_vars": {"first_name": "Alice"}}
> ]
> }'

Cancel a batch

Cancel a scheduled or pending batch before it starts dialing. Once a batch is running, it cannot be cancelled.

$curl -X POST https://api.speechify.ai/v1/batch-calls/BATCH_ID/cancel \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY"

Check batch status

Poll the detail endpoint to track progress. The response includes the parent batch and all recipients with their individual status.

$curl https://api.speechify.ai/v1/batch-calls/BATCH_ID \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY"

List all batches

Returns all batches in your workspace, newest first.

$curl https://api.speechify.ai/v1/batch-calls \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY"

Batch lifecycle

StatusMeaning
pendingCreated, waiting to start dialing
scheduledWill start at scheduled_at
runningActively placing calls
completedAll recipients processed
failedBatch-level error (e.g. invalid agent)
cancelledCancelled before dialing started

Each recipient has its own status: pendingdialingcompleted or failed.

Webhooks

If your agent has a webhook_url configured, a conversation.completed webhook fires for each call in the batch after it ends. The webhook payload includes the transcript, evaluations, and any data collection fields you configured. See Webhooks for the payload format and signature verification.

Limits

LimitValue
Recipients per batch1,000
CSV upload size5 MB
Schedule windowUp to 30 days in advance
scheduled_at minimumMust be in the future