Skip to content
TriedDocs
Deploy

Batch calls

Upload a CSV and have an agent call every row, now or on a schedule, inside the hours and days you choose.

A batch call dials a list of numbers from one of your phone numbers. Each row becomes a call with its own dynamic variables. The scheduler places calls as concurrency allows, only inside your call time window, and stops when every row has been dialled or you stop the batch.

Use batch calls for appointment reminders, reactivation campaigns, surveys and any list where you know the numbers up front.

Create a batch in the dashboard#

Open Batch Call#

In the sidebar under Deploy, click Batch Call, then Create a batch call.

Name it and pick the number#

Enter Batch Call Name and choose From number. The hint under the field shows which agent will speak (Calls use ...), or warns This number has no outbound agent configured.

Upload recipients#

Under Recipients, drop a CSV or click Upload CSV. Click Template to download a sample file. The preview shows each column as a {{variable}}, counts valid rows, and highlights invalid numbers in red.

Choose when to send#

When to send is Send now or Schedule (pick a date and time). Set Reserved concurrency to keep slots free for other calls.

Optional limits#

Skip recipients on the do-not-call list is on by default. Turn on Call time window to only call between a start and end time, in a timezone, on selected days.

Send, schedule or save#

Click Send now or Schedule. Click Save as draft to create the batch without starting it.

Create a batch call dialog with a CSV preview, one invalid row skipped, and send options

CSV format#

  • The first row is the header.
  • The first column is the phone number. Its header name does not matter.
  • Every other column becomes a dynamic variable. Header names are lower-cased and anything other than letters, digits and _ becomes _ (so First Name becomes {{first_name}}).
  • Spaces, brackets and dashes in the phone number are removed. Australian numbers written as 0412345678 (10 digits starting 02, 03, 04, 07 or 08) are converted to +61412345678.
  • Rows whose number is not E.164 after that are skipped.

The downloadable template:

phone number,first_name,appointment_time
+61412345678,Sam,Tuesday 3pm
+61498765432,Priya,Wednesday 10am

Use the variables in the agent's prompt or begin message, for example Hi {{first_name}}, I'm calling about your appointment on {{appointment_time}}.

Create a batch with the API#

POST /create-batch-call takes the recipients as tasks. CSV parsing is a dashboard feature; the API expects the rows already parsed.

curl -X POST https://api.tried.com.au/create-batch-call \
  -H "Authorization: Bearer $TRIED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "October reactivation",
    "from_number": "+61255501234",
    "tasks": [
      { "to_number": "+61412345678", "retell_llm_dynamic_variables": { "first_name": "Sam" } },
      { "to_number": "+61498765432", "retell_llm_dynamic_variables": { "first_name": "Priya" } }
    ],
    "trigger_timestamp": 1792000000000,
    "reserved_concurrency": 2,
    "honor_internal_dnc": true,
    "call_time_window": {
      "windows": [{ "start": 540, "end": 1020 }],
      "timezone": "Australia/Sydney",
      "day": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
    }
  }'
Field Type Default Description
name string "Batch call" Shown in the batch list.
from_number string required A number in your workspace.
tasks BatchTask[] required, at least 1 One entry per recipient.
trigger_timestamp number (epoch ms) now When the batch may start.
reserved_concurrency integer, 0 or more 0 Slots the batch leaves free for other calls.
call_time_window object none (any time) Hours and days when calls may be placed.
draft boolean false Create without scheduling. Start it later with POST /start-batch-call/:id.
honor_internal_dnc boolean false Skip numbers whose contact is flagged do-not-call, checked when each task is dialled.

BatchTask fields:

Field Type Description
to_number string Destination in E.164.
retell_llm_dynamic_variables object Variables for this call. Default {}.
metadata object Stored on the call. Default {}.
override_agent_id string Use this agent for this row instead of the number's outbound agent.

Every task needs an agent: either the number has outbound_agents, or the task has override_agent_id. Otherwise the request returns 400.

Call time window#

Field Type Description
windows { start, end }[] Minutes after midnight, 0 to 1440. 540 to 1020 is 9:00 to 17:00. A window whose start is after its end wraps past midnight.
timezone string IANA timezone. Default Australia/Sydney.
day string[] Monday to Sunday. Omit to allow every day.

The dashboard offers one window with these timezones: Australia/Sydney, Australia/Melbourne, Australia/Brisbane, Australia/Adelaide, Australia/Perth, Pacific/Auckland, America/New_York, America/Chicago, America/Los_Angeles, Europe/London and UTC. The API accepts several windows and any IANA name.

How the scheduler dials#

A scheduler pass runs every 5 seconds (BATCH_TICK_MS). For each batch that is planned or ongoing and whose scheduled time has passed:

  1. If the current time is outside call_time_window, the batch waits.
  2. Free capacity is the workspace concurrency limit minus reserved_concurrency minus calls already in progress.
  3. Pending tasks are dialled in order, up to that capacity, through the same path as POST /v2/create-phone-call (including the number's calls-per-second limit and allowed outbound countries).
  4. When no pending tasks remain, the batch becomes sent.

A task that cannot be dialled is marked failed with the error. When the credit balance runs out, the task gets a not_connected call with disconnection_reason: "no_valid_payment" so the attempt shows in Call History.

Statuses and counters#

Status Meaning
draft Saved, not scheduled. Shown with a Start batch button.
planned Scheduled, waiting for its time, a window or a free slot.
ongoing At least one call has been placed and tasks remain.
sent Every task has been dialled.
stopped Stopped by you; remaining tasks were cancelled.

The batch list shows Recipients, Sent, Picked up and Successful, with a progress bar of sent over recipients.

  • Sent counts dial attempts.
  • Picked up counts calls that connected. The percentage is picked up over sent.
  • Successful counts calls whose post-call analysis set call_successful to true. The percentage is successful over picked up.
A batch call drawer with counters, schedule details, Stop batch and View calls in Call History

Click a row to open the drawer. View calls in Call History filters Call History to the batch. With the API, filter POST /v2/list-calls by filter_criteria.batch_call_id.

Start, stop and delete#

Action Dashboard API
Start a draft Start batch in the drawer POST /start-batch-call/:id returns { batch_call_id, status }. Only drafts can be started. A past scheduled time is moved to now.
Stop Stop batch, then confirm POST /stop-batch-call/:id cancels pending tasks and returns cancelled_tasks. Calls in progress finish normally.
Delete Delete batch DELETE /delete-batch-call/:id. Pending recipients are not called. Calls already placed stay in Call History, unlinked from the batch.
Inspect Drawer GET /get-batch-call/:id returns the batch and each task's status, call_id and error. GET /list-batch-calls lists all batches.

Cost#

Batch calls are billed at the same per-minute rate as other calls, plus $0.01 for every dial attempt (batch_dial).

Limits and gotchas#

  • Batch calls count against the workspace concurrency limit and leave reserved inbound slots free. See Concurrency.
  • Reserved concurrency in the dashboard accepts 0 to 50.
  • The call time window is evaluated in the window's timezone, not each recipient's own timezone. Split a list by region if recipients span timezones.
  • trigger_timestamp in the past starts the batch on the next scheduler pass.
  • Dialling needs LiveKit SIP. Needs keys