Skip to main content
The API Quickstart makes one call. This guide scales that to a campaign: upload a CSV of recipients (each with their own variables), schedule the batch, and pull back per-call results. It reuses the agent and execution concepts from the outbound quickstart, so start there if you haven’t.
You’ll need an agent_id (see the API Quickstart) and enough wallet balance for the number of rows in your CSV.

Prerequisites

  • export BOLNA_API_KEY="bn-xxxx" and export BOLNA_AGENT_ID="your-agent-id"
  • A CSV with a contact_number column (required). Any other columns become {variable} values your prompt and welcome message can use.
Reference CSV columns in the Agent Tab with {column_name} — e.g. a customer_name column lets your welcome message say “Hi ”.

The CSV

batch.csv
Only contact_number is mandatory; customer_name and appointment_day are example variables.
1

Create the batch

Upload the CSV with your agent_id as multipart/form-data.
Response
Save the batch_id.
2

Schedule the batch

A created batch doesn’t call anyone until it’s scheduled. Pass scheduled_at as an ISO 8601 timestamp with a numeric UTC offset (e.g. +00:00). Two API rules that aren’t obvious:
  • The time must be at least 2 minutes in the future, or you get a 400.
  • Use a numeric offset like +00:00 — the Z suffix is rejected with a 500.
  • Bolna rounds the start up to the next 10-minute mark, so a 12:02 request runs at 12:10.
Response
Outbound time-of-day restrictions still apply per recipient timezone. If a scheduled time falls outside the allowed window, calls are pushed to the next allowed slot. See Calling Guardrails.
3

Track progress

Poll the batch for its status, then list per-call executions once it’s running or done.
Each execution in the list is a standard execution objectstatus, transcript, total_cost, telephony_data, extracted_data, etc. — one per row in your CSV. The batch object tracks overall progress; status moves created → scheduled → running → completed.
GET /batches/{batch_id}
GET /batches/{batch_id}/executions (bare array)
The execution’s context_details.recipient_data echoes back the CSV columns for that row — confirming your {variables} reached the call. Per-call status starts at prepared before the call is placed, then becomes completed (or no-answer, busy, failed).

Run the whole flow as one script

The dependency-free bolna_batch_test.py script does all of the above — builds a sample CSV (or takes your own), creates the batch, schedules it, polls, and prints per-call results:

Managing batches

Next steps

Personalize each call

Use CSV columns as {variables} in your prompt and welcome message.

Receive results via webhook

Get each call’s payload pushed to you instead of polling.

Extract structured data

Auto-capture lead quality, outcomes, and more from every call.

Single calls

The outbound quickstart this builds on.