Campaigns

Campaigns reach a list of recipients with one of your AI agents over voice, SMS, or WhatsApp, at a carrier-safe rate, with automatic retries for no-answer/busy voice calls. You create a campaign, upload recipients, then start it — Voicebip paces the dispatch per carrier and records the outcome of every recipient. This guide leads with voice; SMS and WhatsApp use the same flow with a different config.

The lifecycle is: draft → running ⇄ paused → completed | cancelled.

1. Create a campaign

A new campaign starts in draft. config carries the per-call template (caller-id, optional webhook, optional call window). retry_policy is optional — omit it for no retries.

$curl -X POST "https://api.voicebip.com/v1/campaigns" \
> -H "Authorization: Bearer pk_live_your_key" \
> -H "Content-Type: application/json" \
> -d '{
> "channel": "voice",
> "agent_id": "agt_abc123",
> "config": {
> "from_number": "+2348001234567",
> "call_window_start": "09:00",
> "call_window_end": "18:00",
> "call_window_timezone": "Africa/Lagos"
> },
> "retry_policy": {
> "max_attempts": 3,
> "backoff_seconds": 300,
> "backoff_multiplier": 2.0
> }
> }'

Response (201):

1{
2 "id": "camp_abc123",
3 "channel": "voice",
4 "agent_id": "agt_abc123",
5 "status": "draft",
6 "config": { "from_number": "+2348001234567", "...": "..." },
7 "retry_policy": { "max_attempts": 3, "backoff_seconds": 300, "backoff_multiplier": 2.0 },
8 "counters": { "total": 0, "queued": 0, "dispatched": 0, "succeeded": 0, "failed": 0 },
9 "created_at": "2026-06-11T12:00:00Z"
10}

Retry policy

FieldDefaultMeaning
max_attempts3Total dial attempts per recipient (including the first).
backoff_seconds300Base wait before the first retry.
backoff_multiplier2.0Exponential factor: wait = backoff_seconds × multiplier^(attempt-1), capped at 6 hours.

Only transient failures (no_answer, busy) are retried. completed and hard failed outcomes are terminal. Omit retry_policy entirely to disable retries — every recipient is dialed once.

2. Add recipients

Upload recipients in bulk (up to 10,000 per request). Invalid E.164 numbers and in-campaign duplicates are skipped, not fatal — the response reports the counts. params are optional per-recipient template variables.

$curl -X POST "https://api.voicebip.com/v1/campaigns/camp_abc123/targets" \
> -H "Authorization: Bearer pk_live_your_key" \
> -H "Content-Type: application/json" \
> -d '{
> "targets": [
> { "to_address": "+2348031234567", "params": { "first_name": "Ada" } },
> { "to_address": "+2348039876543", "params": { "first_name": "Bola" } }
> ]
> }'

Response (200):

1{ "added": 2, "skipped_duplicate": 0, "rejected_invalid": 0 }

3. Start, pause, resume, cancel

$# Begin paced dialing (draft → running)
$curl -X POST "https://api.voicebip.com/v1/campaigns/camp_abc123/start" \
> -H "Authorization: Bearer pk_live_your_key"
$
$# Halt new dials; in-flight calls finish (running → paused)
$curl -X POST "https://api.voicebip.com/v1/campaigns/camp_abc123/pause" \
> -H "Authorization: Bearer pk_live_your_key"
$
$# Re-seed the remaining recipients (paused → running)
$curl -X POST "https://api.voicebip.com/v1/campaigns/camp_abc123/resume" \
> -H "Authorization: Bearer pk_live_your_key"
$
$# Stop and discard the backlog (any non-terminal status → cancelled)
$curl -X POST "https://api.voicebip.com/v1/campaigns/camp_abc123/cancel" \
> -H "Authorization: Bearer pk_live_your_key"

A campaign auto-completes (running → completed) once every recipient has a terminal outcome and no retries remain.

4. Track progress

Poll the campaign for live counters, or list per-recipient outcomes.

$# Campaign-level progress
$curl "https://api.voicebip.com/v1/campaigns/camp_abc123" \
> -H "Authorization: Bearer pk_live_your_key"
1{
2 "id": "camp_abc123",
3 "status": "running",
4 "counters": { "total": 500, "queued": 120, "dispatched": 3, "succeeded": 340, "failed": 37 }
5}

total = queued + dispatched + succeeded + failed always holds:

  • queued — waiting to be dialed (first attempt or a scheduled retry).
  • dispatched — currently in flight, awaiting outcome.
  • succeeded — call completed.
  • failed — hard failure, or a transient failure that exhausted its retries.
$# Per-recipient outcomes (filter by disposition, paginate)
$curl "https://api.voicebip.com/v1/campaigns/camp_abc123/targets?disposition=no_answer" \
> -H "Authorization: Bearer pk_live_your_key"
1{
2 "targets": [
3 {
4 "id": "tgt_xyz789",
5 "to_address": "+2348031234567",
6 "disposition": "no_answer",
7 "attempt_count": 2,
8 "next_attempt_at": "2026-06-11T12:10:00Z",
9 "last_exec_id": "call_def456"
10 }
11 ],
12 "next_page_token": ""
13}

Every campaign-dialed call also appears in GET /v1/calls with its campaign_id set, so transcripts and recordings flow through the usual call APIs.

5. SMS and WhatsApp campaigns

Campaigns aren’t voice-only. Set channel to sms or whatsapp and Voicebip paces the sends the same way it paces dials — per carrier for SMS, per sender + template-category for WhatsApp. The lifecycle, target upload, tracking, and pagination are identical to voice; only config changes per channel.

Channelconfig fieldsPaced byNotes
voicefrom_number, optional call-windowper-carrier concurrencyretries apply (no_answer/busy).
smsfrom_number, bodyper-carrier throughputone campaign = one message body; per-recipient override via target params.body.
whatsappfrom_number, phone_number_id, template_name, language_code, category, optional parametersper-sender daily conversation capWhatsApp campaigns are template campaigns; category is marketing/utility/authentication. Per-recipient template variables via target params.parameters.

SMS campaign:

$curl -X POST "https://api.voicebip.com/v1/campaigns" \
> -H "Authorization: Bearer pk_live_your_key" \
> -H "Content-Type: application/json" \
> -d '{
> "channel": "sms",
> "agent_id": "agt_abc123",
> "config": { "from_number": "+2348001234567", "body": "Hi {{first_name}}, your order shipped." }
> }'

WhatsApp campaign (one approved template, one sender, one category):

$curl -X POST "https://api.voicebip.com/v1/campaigns" \
> -H "Authorization: Bearer pk_live_your_key" \
> -H "Content-Type: application/json" \
> -d '{
> "channel": "whatsapp",
> "agent_id": "agt_abc123",
> "config": {
> "from_number": "+2348001234567",
> "phone_number_id": "1234567890",
> "template_name": "order_update",
> "language_code": "en",
> "category": "utility"
> }
> }'

Recipients who have opted out are suppressed automatically — per-category or blanket for WhatsApp, blanket for SMS — and recorded with disposition opted_out; they are never submitted to the carrier. A messaging recipient is marked sent once the provider accepts the submit; WhatsApp then upgrades that to delivered / read as Meta reports status, visible on the target’s disposition.

Notes

  • Pacing and the per-carrier concurrency cap are managed by Voicebip — you don’t set a dial rate; the platform stays within carrier limits.
  • config, schedule, and retry_policy are free-form JSON objects. The voice, sms, and whatsapp channels are supported for campaigns; automatic retries apply to the voice channel today.
  • List endpoints use opaque-cursor pagination (next_page_token).