Campaigns
Create and manage bulk outbound calling campaigns
Campaigns automate bulk outbound dialling. Upload a contact list as a CSV, assign an agent, configure calling hours and concurrency, and the engine handles dialling, tracking outcomes, retrying failures, and generating reports.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /campaign/ | List all campaigns |
| POST | /campaign/create | Create a new campaign |
| GET | /campaign/{id} | Get campaign details and status |
| PATCH | /campaign/{id} | Update campaign settings |
| POST | /campaign/{id}/start | Start dialling |
| POST | /campaign/{id}/pause | Pause (in-flight calls complete) |
| POST | /campaign/{id}/resume | Resume a paused campaign |
| POST | /campaign/{id}/redial | Create a new campaign re-dialling unique uncontacted subscribers |
| GET | /campaign/{id}/progress | Real-time dialling progress and stats |
| GET | /campaign/{id}/runs | Paginated list of call sessions |
| GET | /campaign/{id}/source-download-url | Get presigned URL to download the original contact CSV |
| GET | /campaign/{id}/report | Download completed runs as CSV |
Create a Campaign
Creating a campaign involves two steps:
- Upload the contact CSV via presigned URL (see Section 19: File Uploads / Presigned URLs)
- Create the campaign referencing the uploaded file
/campaign/createRequest body — CreateCampaignRequest:
{
"name": "June Lead Outreach",
"workflow_id": 247,
"contacts_file_key": "campaigns/abc123/contacts.csv",
"max_concurrency": 5,
"calling_hours": {
"timezone": "America/New_York",
"slots": [
{ "day": "monday", "start": "09:00", "end": "17:00" },
{ "day": "tuesday", "start": "09:00", "end": "17:00" },
{ "day": "wednesday", "start": "09:00", "end": "17:00" },
{ "day": "thursday", "start": "09:00", "end": "17:00" },
{ "day": "friday", "start": "09:00", "end": "15:00" }
]
},
"retry_config": {
"enabled": true,
"max_retries": 2,
"retry_delay_seconds": 120,
"retry_on_busy": true,
"retry_on_no_answer": true,
"retry_on_voicemail": true
},
"telephony_configuration_id": null
}Request fields
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Required | Campaign display name |
workflow_id | integer | Required | ID of the voice agent to use |
contacts_file_key | string | Required | File key from the presigned upload (see Section 19) |
max_concurrency | integer | Required | Max simultaneous calls. Capped by org limit and phone number count. |
calling_hours | object | Optional | Restrict dialling to specific days and times. If omitted, calls may be placed at any time. |
retry_config | object | Optional | Retry logic for failed/unanswered contacts |
telephony_configuration_id | integer | Optional | Override telephony config. Defaults to org default. |
CSV format
The contact CSV must have a phone_number column (E.164 format). All other columns are passed as initial_context to the agent:
phone_number,name,company,notes
+14155552671,Jane Smith,Acme Corp,Interested in Enterprise
+14155552672,Bob Jones,Widget Inc,Needs follow-upAll column values are accessible in the agent via {{column_name}} template variables.
Update a Campaign
/campaign/{id}Request body — UpdateCampaignRequest (all fields optional):
{
"name": "Updated Name",
"max_concurrency": 10,
"calling_hours": { ... },
"retry_config": { ... }
}Only fields included in the request are updated.
Campaign Status Values
| Parameter | Type | Required | Description |
|---|---|---|---|
draft | Optional | Created, not yet started | |
running | Optional | Actively dialling contacts | |
paused | Optional | Temporarily stopped — resumable | |
completed | Optional | All contacts processed | |
failed | Optional | Fatal error during execution |
Campaign Progress
/campaign/{id}/progressResponse:
{
"total_contacts": 500,
"dialled": 312,
"answered": 245,
"completed": 238,
"failed": 7,
"pending": 188,
"in_progress": 5,
"status": "running"
}Redial
/campaign/{id}/redialRequest body — RedialCampaignRequest:
{
"name": "June Outreach — Redial",
"redial_statuses": ["no_answer", "busy", "voicemail"]
}Creates a new campaign targeting only contacts from the original campaign that match the specified statuses and haven't been successfully reached.
Download Source CSV
/campaign/{id}/source-download-urlReturns a presigned S3 URL to download the original contact CSV that was uploaded when the campaign was created. The URL expires after a short time (typically 15 minutes).
Download Report CSV
/campaign/{id}/reportQuery parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | datetime | Optional | ISO 8601 start filter |
end_date | datetime | Optional | ISO 8601 end filter |
Returns a CSV with one row per call session: contact, outcome, duration, transcript summary, extracted data.
List Call Sessions
/campaign/{id}/runsQuery parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | Optional | Page number |
limit | integer | Optional | Results per page |
filters | string | Optional | JSON-encoded filter |
sort_by | string | Optional | Sort field |
sort_order | string | Optional | "asc" or "desc" |