curl --request POST \
--url https://api.zeroruntime.ai/v1/batch-calls \
--header 'Authorization: <api-key>' \
--header 'Content-Type: multipart/form-data' \
--form file=@example-file \
--form 'name=October renewals' \
--form 'phoneNumber=+14155550100' \
--form 'description=Renewal reminders for gold and silver plans' \
--form phoneNumberId=6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90 \
--form routingRuleId=rr_2554md \
--form 'schedule={"date":"2026-10-14","time":"10:00","timezone":"Asia/Kolkata"}' \
--form 'retry={"retryOn":["not-answered","failed"],"retryDelays":[600,3600]}' \
--form 'webhook={"endpoint":"https://example.com/hooks/batch","events":["batchcall-started","batchcall-completed"]}'import requests
url = "https://api.zeroruntime.ai/v1/batch-calls"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"name": "October renewals",
"phoneNumber": "+14155550100",
"description": "Renewal reminders for gold and silver plans",
"phoneNumberId": "6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90",
"routingRuleId": "rr_2554md",
"schedule": "{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}",
"retry": "{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}",
"webhook": "{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}"
}
headers = {"Authorization": "<api-key>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('name', 'October renewals');
form.append('phoneNumber', '+14155550100');
form.append('description', 'Renewal reminders for gold and silver plans');
form.append('phoneNumberId', '6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90');
form.append('routingRuleId', 'rr_2554md');
form.append('schedule', '{"date":"2026-10-14","time":"10:00","timezone":"Asia/Kolkata"}');
form.append('retry', '{"retryOn":["not-answered","failed"],"retryDelays":[600,3600]}');
form.append('webhook', '{"endpoint":"https://example.com/hooks/batch","events":["batchcall-started","batchcall-completed"]}');
const options = {method: 'POST', headers: {Authorization: '<api-key>'}};
options.body = form;
fetch('https://api.zeroruntime.ai/v1/batch-calls', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zeroruntime.ai/v1/batch-calls",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.zeroruntime.ai/v1/batch-calls"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.zeroruntime.ai/v1/batch-calls")
.header("Authorization", "<api-key>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zeroruntime.ai/v1/batch-calls")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"batchId": "btcl_k3x9q2",
"batchName": "October renewals",
"description": "Renewal reminders for gold and silver plans",
"phoneNumberId": "6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90",
"phoneNumber": "+14155550100",
"routingRuleId": "rr_2554md",
"status": "parsing",
"timing": "scheduled",
"timezone": "Asia/Kolkata",
"scheduledDate": "2026-10-14",
"scheduledTime": "10:00",
"retry": {
"enabled": true,
"retryOn": [
"not-answered",
"failed"
],
"retryDelays": [
600,
3600
],
"maxAttempts": 2
},
"recordsUploaded": 0,
"parseError": null,
"file": {
"filename": "customers.csv",
"extension": ".csv",
"key": "batchcall/btcl_k3x9q2/1760261400000-customers.csv"
},
"timestamp": 1760416200,
"createdAt": "2026-10-12T09:30:00.000Z",
"updatedAt": "2026-10-12T09:30:00.000Z"
}{
"message": "schedule.time: must be HH:MM (24-hour)",
"errors": [
"schedule.time: must be HH:MM (24-hour)",
"retry.retryOn.0: Invalid enum value. Expected 'failed' | 'not-answered' | 'rejected' | 'missed' | 'abandoned', received 'busy'",
"webhook: Unrecognized key(s) in object: 'url'"
]
}{
"error": "<string>"
}{
"message": "Phone number not found"
}Create batch call
Uploads a spreadsheet of phone numbers, and your agent calls each one, right away or on a schedule. The batch starts by itself once the file is parsed. Follow it with Get batch call.
You need a number with an outbound gateway, and an outbound routing rule on it with the agentId of the agent that should make the calls.
curl --request POST \
--url https://api.zeroruntime.ai/v1/batch-calls \
--header 'Authorization: <api-key>' \
--header 'Content-Type: multipart/form-data' \
--form file=@example-file \
--form 'name=October renewals' \
--form 'phoneNumber=+14155550100' \
--form 'description=Renewal reminders for gold and silver plans' \
--form phoneNumberId=6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90 \
--form routingRuleId=rr_2554md \
--form 'schedule={"date":"2026-10-14","time":"10:00","timezone":"Asia/Kolkata"}' \
--form 'retry={"retryOn":["not-answered","failed"],"retryDelays":[600,3600]}' \
--form 'webhook={"endpoint":"https://example.com/hooks/batch","events":["batchcall-started","batchcall-completed"]}'import requests
url = "https://api.zeroruntime.ai/v1/batch-calls"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"name": "October renewals",
"phoneNumber": "+14155550100",
"description": "Renewal reminders for gold and silver plans",
"phoneNumberId": "6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90",
"routingRuleId": "rr_2554md",
"schedule": "{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}",
"retry": "{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}",
"webhook": "{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}"
}
headers = {"Authorization": "<api-key>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('name', 'October renewals');
form.append('phoneNumber', '+14155550100');
form.append('description', 'Renewal reminders for gold and silver plans');
form.append('phoneNumberId', '6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90');
form.append('routingRuleId', 'rr_2554md');
form.append('schedule', '{"date":"2026-10-14","time":"10:00","timezone":"Asia/Kolkata"}');
form.append('retry', '{"retryOn":["not-answered","failed"],"retryDelays":[600,3600]}');
form.append('webhook', '{"endpoint":"https://example.com/hooks/batch","events":["batchcall-started","batchcall-completed"]}');
const options = {method: 'POST', headers: {Authorization: '<api-key>'}};
options.body = form;
fetch('https://api.zeroruntime.ai/v1/batch-calls', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zeroruntime.ai/v1/batch-calls",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.zeroruntime.ai/v1/batch-calls"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.zeroruntime.ai/v1/batch-calls")
.header("Authorization", "<api-key>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zeroruntime.ai/v1/batch-calls")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nOctober renewals\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumber\"\r\n\r\n+14155550100\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nRenewal reminders for gold and silver plans\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"phoneNumberId\"\r\n\r\n6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"routingRuleId\"\r\n\r\nrr_2554md\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"schedule\"\r\n\r\n{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"retry\"\r\n\r\n{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook\"\r\n\r\n{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"batchId": "btcl_k3x9q2",
"batchName": "October renewals",
"description": "Renewal reminders for gold and silver plans",
"phoneNumberId": "6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90",
"phoneNumber": "+14155550100",
"routingRuleId": "rr_2554md",
"status": "parsing",
"timing": "scheduled",
"timezone": "Asia/Kolkata",
"scheduledDate": "2026-10-14",
"scheduledTime": "10:00",
"retry": {
"enabled": true,
"retryOn": [
"not-answered",
"failed"
],
"retryDelays": [
600,
3600
],
"maxAttempts": 2
},
"recordsUploaded": 0,
"parseError": null,
"file": {
"filename": "customers.csv",
"extension": ".csv",
"key": "batchcall/btcl_k3x9q2/1760261400000-customers.csv"
},
"timestamp": 1760416200,
"createdAt": "2026-10-12T09:30:00.000Z",
"updatedAt": "2026-10-12T09:30:00.000Z"
}{
"message": "schedule.time: must be HH:MM (24-hour)",
"errors": [
"schedule.time: must be HH:MM (24-hour)",
"retry.retryOn.0: Invalid enum value. Expected 'failed' | 'not-answered' | 'rejected' | 'missed' | 'abandoned', received 'busy'",
"webhook: Unrecognized key(s) in object: 'url'"
]
}{
"error": "<string>"
}{
"message": "Phone number not found"
}Authorizations
Your API token, sent raw (no Bearer prefix).
Body
.csv, .xls or .xlsx, at most 5 MB. The first row is the header and needs a phone_number column (E.164 with the +). Every other column is passed to the agent as metadata for that call.
phone_number,name,plan
+919876543210,Asha,gold
+14155550100,Tom,silver
A name for the batch. Returned as batchName.
256"October renewals"
The number to call from, in E.164 with the +. It must be on your account.
"+14155550100"
1000"Renewal reminders for gold and silver plans"
The same number by its id. You can send this instead of phoneNumber.
"6f1d2c3a-8b4e-4f7a-9c21-0d5e6b7a8c90"
The outbound routing rule that picks the agent. Leave it out when the number has exactly one outbound rule.
"rr_2554md"
JSON string. Leave it out to start calling as soon as the file is parsed.
date: required,YYYY-MM-DD.time: required,HH:MM(24-hour).timezone: IANA name, e.g.America/New_York. DefaultAsia/Calcutta.
"{\"date\":\"2026-10-14\",\"time\":\"10:00\",\"timezone\":\"Asia/Kolkata\"}"
JSON string. Sending it turns retries on; leave it out to call each number once.
retryOn: required. Any offailed,not-answered,rejected,missed,abandoned.retryDelays: required. Seconds before each retry, one per attempt, at most 5.
"{\"retryOn\":[\"not-answered\",\"failed\"],\"retryDelays\":[600,3600]}"
JSON string. Each event posts { batchId, batchName, status, recordsUploaded }.
endpoint: required. The URL that receives the events.events: required, at least one ofbatchcall-started,batchcall-completed.
"{\"endpoint\":\"https://example.com/hooks/batch\",\"events\":[\"batchcall-started\",\"batchcall-completed\"]}"
Response
Batch created and its file is being parsed. It starts by itself once parsing finishes.
"btcl_k3x9q2"
The name you sent.
"October renewals"
The number calls are made from.
That number in E.164.
"+14155550100"
The outbound routing rule in use.
"rr_2554md"
Without a schedule, a batch goes straight from parsing to running.
parsing: the file is being read. No calls yet.parse_failed: the file couldn't be used, andparseErrorsays why. Fix the file and create a new batch.scheduled: parsed, waiting for its start time.running: calls are being placed.cancelling: a cancel is in progress.cancelled: stopped before every number was called.completed: every number has been called, retries included.
parsing, parse_failed, scheduled, running, cancelling, cancelled, completed scheduled when you sent a schedule, otherwise immediate.
immediate, scheduled "Asia/Kolkata"
schedule.date.
"2026-10-14"
schedule.time.
"10:00"
Show child attributes
Show child attributes
Phone numbers read from the file. 0 until parsing finishes.
Why parsing failed. Set when status is parse_failed.
The uploaded file.
Show child attributes
Show child attributes
Start time as a Unix timestamp in seconds. For an immediate batch