DocsDeveloper HubBatch Calls API
Create, execute, schedule and monitor batch calls

Batch calls with the API

Create a recipient list, execute it now or schedule it, and monitor the batch. All requests use the headers in API authentication. The API reference includes both /batch/* and /batch-calls routes.

Create a batch

Shell
curl --fail-with-body -X POST "$TUNK_BASE_URL/batch/create" \
  -H "X-Api-Key: $TUNK_API_KEY" \
  -H "X-Workspace-Id: $TUNK_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'Content-Type: application/json' \
  -d '{
    "batch_name": "Follow-up calls",
    "agent_id": "123e4567-e89b-42d3-a456-426614174000",
    "recipients": [
      {"phone_number": "+14155552671", "variables": {"customer_name": "Alex"}}
    ]
  }'

Use data.batch_id in subsequent requests. Without schedule_time, creation saves the batch and recipients without dispatching calls. A batch starts in draft. The JSON list supports 1–10,000 recipients; batch_name (or name) must contain at least three characters. Numbers must include the country code. DND-blocked recipients cannot be called.

Upload a CSV instead

csv
phone_number,customer_name
+14155552671,Alex
Shell
curl --fail-with-body -X POST "$TUNK_BASE_URL/batch/create" \
  -H "X-Api-Key: $TUNK_API_KEY" \
  -H "X-Workspace-Id: $TUNK_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F 'agent_id=123e4567-e89b-42d3-a456-426614174000' \
  -F 'batch_name=Follow-up calls' \
  -F 'file=@recipients.csv'

Let curl set the multipart boundary. See the reference for optional concurrency and execution-window fields.

Execute now

This queues real phone calls to the saved recipients.

Shell
curl --fail-with-body -X POST "$TUNK_BASE_URL/batch/run/<batch-uuid>" \
  -H "X-Api-Key: $TUNK_API_KEY" \
  -H "X-Workspace-Id: $TUNK_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'Content-Type: application/json' -d '{}'

The API returns 202 Accepted with status: "scheduled", schedule_id, schedule_time, end_time and timezone. This means the schedule was queued, not that all calls are finished. Scheduler and call workers must be available in the deployed environment.

Schedule for later

Use future ISO 8601 timestamps with Z or an explicit offset. Replace these example dates before sending.

JSON
{
  "schedule_time": "2030-01-15T09:00:00+05:30",
  "end_time": "2030-01-15T18:00:00+05:30",
  "timezone": "Asia/Kolkata"
}

Send that body to POST /batch/run/{batch_id}. Alternatively, add schedule_time to the create request to create and schedule in one operation. Do not run the same batch again after creating it with a schedule. Use the resume endpoint for a paused campaign.

Monitor and control

OperationEndpoint
List batchesGET /batch-calls?page=1&limit=20
Get a batchGET /batch-calls/{id}
List batch callsGET /batch/calls/{batch_id}?page=1&limit=20
PausePOST /batch/pause/{batch_id}
ResumePOST /batch/resume/{batch_id}
TerminatePOST /batch/terminate/{batch_id}
Retry selected call statusesPOST /batch/retry
Export call logs as ExcelPOST /batch/export/{batch_id}
Delete batch and logsDELETE /batch/{batch_id}

Retry Failed Calls (POST /batch/retry)

Create a new targeted batch campaign from failed or unanswered calls of existing batches:

Shell
curl -X POST "$TUNK_BASE_URL/batch/retry" \
  -H "X-Api-Key: $TUNK_API_KEY" \
  -H "X-Workspace-Id: $TUNK_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "123e4567-e89b-42d3-a456-426614174000",
    "batch_ids": ["9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"],
    "batch_name": "Retry Unanswered Leads",
    "include_status": ["failed", "no_answer", "busy"]
  }'

Export Call Logs as Excel (POST /batch/export/{batch_id})

Shell
curl -X POST "$TUNK_BASE_URL/batch/export/<batch_id>" \
  -H "X-Api-Key: $TUNK_API_KEY" \
  -H "X-Workspace-Id: $TUNK_WORKSPACE_ID" \
  --output "batch-<batch_id>.xlsx"

Pause and terminate do not mean that an already connected phone call has hung up. Inspect individual call records. call.completed webhooks are per call; there is no batch.completed subscription. A batch stuck in progress requires checking the scheduler, workers, provider callbacks and terminal call records, not merely repeating the run request.

Need help? Reach out on our support portal.