Campaigns

Running a voice agent against a list of contacts at scale

A campaign is how you run a workflow against many contacts automatically. Instead of triggering calls one by one via the API, you upload a list of phone numbers and Paladin dials them for you — respecting scheduling windows, concurrency limits, and retry rules.

How a campaign works#

mermaid
flowchart LR
    CSV[Contacts CSV] --> Upload[Upload to Paladin]
    Upload --> Campaign[Create Campaign]
    Campaign --> Schedule[Scheduling & Concurrency]
    Schedule --> Calls[Outbound Calls]
    Calls --> Runs[Run Records]
    Runs --> Results[Progress & Reports]
  1. Upload a contacts CSV — must have a phone_number column; any extra columns become initial_context for each call
  2. Create the campaign — link it to a workflow, set concurrency, time slots, and retry behaviour
  3. Start it — Paladin begins dialing contacts up to your concurrency limit
  4. Monitor progress — track processed, completed, failed, and pending counts in real time
  5. Pause and resume — stop and restart at any point without losing progress

The contacts CSV#

The CSV drives the campaign. Each row is one contact.

csv
phone_number,customer_name,account_id,plan
+14155550100,Jane Smith,acc_001,premium
+14155550101,Bob Jones,acc_002,basic

Columns beyond phone_number are automatically passed as initial_context to each call, making them available as template variables in your agent's prompt — so each call can feel personalised at scale.

Scheduling and concurrency#

Concurrency controls how many calls run simultaneously. It's capped by your telephony plan. Set it conservatively to start.

Time slots restrict when Paladin is allowed to dial — useful for respecting business hours or regulations:

json
{
  "timezone": "America/New_York",
  "time_slots": [
    { "day": "monday", "start": "09:00", "end": "17:00" },
    { "day": "tuesday", "start": "09:00", "end": "17:00" }
  ]
}

If no time slots are set, Paladin dials continuously once the campaign is started.

Retry behaviour#

Paladin can automatically retry contacts who didn't answer, were busy, or went to voicemail:

json
{
  "retry_config": {
    "max_attempts": 3,
    "retry_interval_minutes": 60
  }
}

Circuit breaker#

The circuit breaker automatically pauses a campaign when the call failure rate gets too high — protecting against wasted spend and telephony reputation issues caused by a misconfigured agent or a bad contact list.

When enabled, Paladin monitors the failure rate within a rolling time window. If it exceeds the threshold, the campaign is paused automatically and must be manually resumed after the issue is investigated.

SettingDefaultDescription
Failure Threshold (%)50Pause when the failure rate within the window exceeds this percentage
Window (seconds)120Rolling time window over which the failure rate is calculated
Min Calls in Window5Minimum number of calls required before the circuit breaker can trip — prevents false positives on small samples

A campaign paused by the circuit breaker behaves the same as a manually paused campaign — in-flight calls complete normally, and it can be resumed once the underlying issue is resolved.

Campaign lifecycle#

StatusMeaning
draftCreated but not started
runningActively dialing
pausedStopped; resumes from where it left off
completedAll contacts processed
failedEncountered a fatal error

You can pause and resume a campaign at any time. In-flight calls complete normally before a pause takes effect.

Results#

Each contact's call creates a run record with the full transcript, recording, and gathered context — same as a manually triggered call. Use the Get Campaign Runs endpoint to retrieve them all.

See the Campaigns API reference to get started.