Campaign
Create and manage outbound calling and messaging campaigns. Campaigns automate bulk outreach by dialing a list of destinations and connecting answered calls to a flow or agent.
API Reference: Campaign endpoints
Overview
Note
AI Context
Complexity: High – Campaigns coordinate multiple resources (outdials, outplans, queues, flows). Set up all dependencies before creating a campaign.
Cost: Chargeable. Running a campaign makes outbound calls/messages, each of which incurs per-minute or per-message charges.
Async: Yes.
POST /campaignscreates the campaign instopstatus. SetstatustorunningviaPUT /campaigns/{id}to start dialing. PollGET /campaigns/{id}to monitor campaign state and progress.
VoIPBIN’s Campaign API provides a comprehensive platform for managing large-scale outbound communication campaigns. Whether you need to make thousands of calls, send bulk SMS, or deliver email notifications, the Campaign API orchestrates the entire process with intelligent dialing strategies and automatic retry handling.
With the Campaign API you can:
Execute mass outbound calling campaigns
Send bulk SMS and email notifications
Configure intelligent retry strategies
Monitor campaign progress in real-time
Integrate with agent queues for live connections
How Campaigns Work
A campaign coordinates multiple resources to execute outbound communications efficiently.
Campaign Architecture
+-----------------------------------------------------------------------+
| Campaign System |
+-----------------------------------------------------------------------+
+-------------------+
| Campaign |
| (orchestrator) |
+--------+----------+
|
| controls
v
+--------+----------+--------+----------+--------+----------+
| | | |
v v v v
+----------+ +----------+ +----------+ +----------+
| Outdial | | Outplan | | Queue | | Flow |
| (who) | | (how) | | (agents)| | (what) |
+----------+ +----------+ +----------+ +----------+
| | | |
v v v v
+---------+ +---------+ +---------+ +---------+
| Targets | | Retry | | Agent | | Actions |
| to dial | | rules | | pool | | to run |
+---------+ +---------+ +---------+ +---------+
Key Components
Campaign: The orchestrator that manages the entire outbound operation
Outdial: Contains the list of target destinations (phone numbers, emails)
Outplan: Defines the dialing strategy (timing, retries, intervals)
Queue: Groups agents who handle answered calls
Flow: Specifies actions to take when calls connect
Note
AI Implementation Hint
A campaign requires all four dependencies (outdial, outplan, queue, flow) to be created before the campaign itself. The outdial_id, outplan_id, queue_id, and flow_id must reference existing resources. Creating a campaign with missing or invalid dependency IDs will result in failures when the campaign starts dialing.
Campaign Lifecycle
Campaigns progress through predictable states.
Campaign States
POST /campaigns (status: stop)
|
v
+------------+
| stop |<-----------------+
+-----+------+ |
| |
| start | stop
v |
+------------+ |
| running |------------------+
+-----+------+
|
| all targets completed
v
+------------+
| finished |
+------------+
State Descriptions
State |
What’s happening |
|---|---|
stop |
Campaign created but not active; no dialing occurring |
running |
Campaign actively dialing targets based on outplan |
finished |
All targets attempted; campaign completed |
Dialing Process
The campaign dialer processes targets according to the outplan strategy.
Dialing Flow
Campaign Running
|
v
+-------------------+
| Get next target |
| from outdial |
+--------+----------+
|
v
+-------------------+
| Apply outplan |
| (timing, rules) |
+--------+----------+
|
v
+-------------------+ Success +-------------------+
| Dial target |---------------->| Execute flow |
| | | (connect to agent)|
+--------+----------+ +-------------------+
|
| Failed (busy, no answer, etc.)
v
+-------------------+ Yes +-------------------+
| Retry available? |---------------->| Schedule retry |
| | | per outplan |
+--------+----------+ +-------------------+
|
| No retries left
v
+-------------------+
| Mark as failed |
| Move to next |
+-------------------+
5W1H Framework
The campaign system follows the 5W1H principle for clarity.
+-----------------------------------------------------------------------+
| 5W1H Campaign Framework |
+-----------------------------------------------------------------------+
+-----------+------------------+----------------------------------------+
| Question | Component | Purpose |
+===========+==================+========================================+
| WHY/WHAT | Campaign + Flow | Purpose of calling and actions |
| | | to take after connection |
+-----------+------------------+----------------------------------------+
| WHO | Queue + Agents | People who handle answered calls |
+-----------+------------------+----------------------------------------+
| WHERE | Outdial | Target destinations to reach |
+-----------+------------------+----------------------------------------+
| HOW/WHEN | Outplan | Dialing strategy and timing |
+-----------+------------------+----------------------------------------+
Creating a Campaign
Create a campaign by defining its components.
Create Campaign Example
$ curl -X POST 'https://api.voipbin.net/v1.0/campaigns?token=<token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Customer Survey Q1",
"detail": "Quarterly satisfaction survey",
"type": "call",
"service_level": 80,
"end_handle": "stop",
"outdial_id": "<outdial-id>",
"outplan_id": "<outplan-id>",
"queue_id": "<queue-id>",
"flow_id": "<flow-id>",
"source": "+15551234567"
}'
Start Campaign
$ curl -X PUT 'https://api.voipbin.net/v1.0/campaigns/<campaign-id>?token=<token>' \
--header 'Content-Type: application/json' \
--data '{
"status": "running"
}'
Campaign Types
VoIPBIN supports different campaign types for various communication needs.
Type |
Description |
|---|---|
call |
Voice calls to phone numbers, with optional agent connection |
message |
SMS/MMS messages to mobile numbers |
Email campaigns to addresses |
Call Campaign Flow
Campaign dials target
|
v
+-------------------+
| Target answers |
+--------+----------+
|
v
+-------------------+
| Execute flow |
| (IVR, AI, etc.) |
+--------+----------+
|
v
+-------------------+
| Connect to agent |
| from queue |
+-------------------+
Common Scenarios
Scenario 1: Telemarketing Campaign
Outbound sales calls with agent connection.
Setup:
1. Outdial: 10,000 customer phone numbers
2. Outplan: Business hours, max 3 retries
3. Queue: Sales team (20 agents)
4. Flow: Play intro -> Connect to agent
Execution:
+--------------------------------------------+
| Campaign dials customer |
| -> Customer answers |
| -> Flow plays: "Special offer from..." |
| -> Press 1 to speak with representative |
| -> Connected to sales agent |
+--------------------------------------------+
Scenario 2: Appointment Reminders
Automated reminder calls with AI.
Setup:
1. Outdial: Tomorrow's appointments
2. Outplan: Call 24 hours before, retry once
3. Flow: AI confirms appointment details
Execution:
+--------------------------------------------+
| Campaign dials patient |
| -> AI: "This is a reminder for your |
| appointment tomorrow at 2pm." |
| -> AI: "Press 1 to confirm, 2 to cancel" |
| -> Response saved via set_variables |
+--------------------------------------------+
Scenario 3: Emergency Notifications
High-priority mass notifications.
Setup:
1. Outdial: All affected customers
2. Outplan: Immediate, aggressive retry (5x)
3. Flow: Play recorded message
Execution:
+--------------------------------------------+
| Campaign dials all targets simultaneously |
| -> Play: "Important service notification" |
| -> Retry unanswered every 15 minutes |
| -> Mark as reached when answered |
+--------------------------------------------+
Best Practices
1. Target List Management
Validate phone numbers before adding to outdial
Remove duplicates and invalid entries
Segment targets for better campaign control
Update lists based on previous campaign results
2. Dialing Strategy
Match outplan to campaign type (sales vs. notification)
Respect time zones and business hours
Set appropriate retry counts (3-5 for sales, 1-2 for reminders)
Use progressive intervals between retries
3. Agent Coordination
Ensure enough agents before starting campaign
Monitor queue wait times during campaign
Plan for peak call volume periods
Have backup agents available
4. Compliance
Honor do-not-call lists
Follow local regulations (TCPA, GDPR)
Provide opt-out options
Keep accurate calling records
Troubleshooting
Campaign Issues
Symptom |
Solution |
|---|---|
Campaign not dialing |
Check status is “running”; verify outdial has targets; check outplan timing settings |
Low answer rate |
Review calling times; check source number reputation; verify target number quality |
High abandon rate |
Add more agents to queue; reduce dial rate; check flow execution time |
Agent Issues
Symptom |
Solution |
|---|---|
Agents not receiving calls |
Check agent status is available; verify queue assignment; check queue routing |
Long wait times |
Add more agents; reduce concurrent dial rate; optimize flow execution |
Target Issues
Symptom |
Solution |
|---|---|
Many failed calls |
Validate phone numbers; check carrier routing; review dial timeout settings |
Retries not happening |
Check outplan max_try_count; verify retry interval settings |
Campaign
Campaign
{
"id": "<string>",
"type": "<string>",
"name": "<string>",
"detail": "<string>",
"status": "<string>",
"service_level": <number>,
"end_handle": "<string>",
"actions": [
...
],
"outplan_id": "<string>",
"outdial_id": "<string>",
"queue_id": "<string>",
"next_campaign_id": "<string>",
"tm_create": "<string>",
"tm_update": "<string>",
"tm_delete": "<string>"
}
id(UUID): The campaign’s unique identifier. Returned when creating viaPOST /campaignsor listing viaGET /campaigns.type(enum string): Campaign’s type. See Type.name(String): Human-readable name for the campaign.detail(String): Detailed description of the campaign.status(enum string): Campaign’s current status. See Status.service_level(Integer): Campaign’s service level percentage. Controls the dialing rate relative to available agents. See Service Level.end_handle(enum string): What happens when the outdial target list is exhausted. See End Handle.actions(Array of Object): List of flow actions executed when a target answers. Each action follows the Action structure.outplan_id(UUID): The outplan controlling dialing strategy. Obtained from theidfield ofGET /outplans. Set to00000000-0000-0000-0000-000000000000if not assigned.outdial_id(UUID): The outdial containing target destinations. Obtained from theidfield ofGET /outdials. Set to00000000-0000-0000-0000-000000000000if not assigned.queue_id(UUID): The queue for routing answered calls to agents. Obtained from theidfield ofGET /queues. Set to00000000-0000-0000-0000-000000000000if not assigned.next_campaign_id(UUID): The campaign to chain after this one finishes. Obtained from theidfield ofGET /campaigns. Set to00000000-0000-0000-0000-000000000000if not assigned.tm_create(string, ISO 8601): Timestamp when the campaign was created.tm_update(string, ISO 8601): Timestamp of the last update to any campaign property.tm_delete(string, ISO 8601): Timestamp when the campaign was deleted. Set to9999-01-01 00:00:00.000000if not deleted.
Note
AI Implementation Hint
A tm_delete value of 9999-01-01 00:00:00.000000 means the resource has not been deleted. This is a sentinel value, not a real timestamp. When filtering active resources, check for this value.
Example
{
"id": "183c0d5c-691e-42f3-af2b-9bffc2740f83",
"type": "call",
"name": "test campaign",
"detail": "test campaign detail",
"status": "stop",
"service_level": 100,
"end_handle": "stop",
"actions": [
{
"id": "00000000-0000-0000-0000-000000000000",
"next_id": "00000000-0000-0000-0000-000000000000",
"type": "talk",
"option": {
"text": "Hello. This is outbound campaign's test calling. Please wait until the agent answer the call. Thank you.",
"language": "en-US"
}
}
],
"outplan_id": "d5fb7357-7ddb-4f2d-87b5-8ccbfd6c039e",
"outdial_id": "40bea034-1d17-474d-a5de-da00d0861c69",
"queue_id": "99bf739a-932f-433c-b1bf-103d33d7e9bb",
"next_campaign_id": "00000000-0000-0000-0000-000000000000",
"tm_create": "2022-04-28 02:16:39.712142",
"tm_update": "2022-04-30 17:53:51.685259",
"tm_delete": "9999-01-01 00:00:00.000000"
}
Type
Campaign’s type. Determines how the campaign communicates with targets.
Type |
Description |
|---|---|
call |
The campaign will make a voice call to each target destination and execute the configured flow actions upon answer. |
flow |
The campaign will execute the configured flow actions directed at each target destination without an explicit voice call setup. |
Status
Campaign’s current operational status. Use PUT /campaigns/{id} with {"status": "run"} to start and {"status": "stop"} to stop the campaign.
Type |
Description |
|---|---|
stop |
The campaign is stopped. No dialing is occurring. This is the initial state after creation. |
stopping |
The campaign is transitioning to stopped. Active calls are being terminated before the campaign fully stops. This is a transient state. |
run |
The campaign is actively running. It will create new calls or flow executions based on the outplan and outdial configuration. |
Service level
The service level controls the amount of campaigncalls. It affects the campaign’s campaigncall creation.
The campaign creates a new campaigncall when the following condition is met:
Available agent > Current dialing campaign calls * Service level / 100
This is valid only if the campaign has a valid queue_id.
End handle
Determines what the campaign does when all targets in the outdial have been attempted.
Type |
Description |
|---|---|
stop |
The campaign will transition to stopped status when the outdial has no more targets to dial. This is the typical setting for one-time campaigns. |
continue |
The campaign will remain in running status after all outdial targets have been attempted. Useful for campaigns where new targets may be added to the outdial dynamically. |
Campaigncall
Campaigncall
{
"id": "<string>",
"campaign_id": "<string>",
"outplan_id": "<string>",
"outdial_id": "<string>",
"outdial_target_id": "<string>",
"queue_id": "<string>",
"activeflow_id": "<string>",
"reference_type": "<string>",
"reference_id": "<string>",
"status": "<string>",
"result": "<string>",
"source": {
...
},
"destination": {
...
},
"destination_index": <number>,
"try_count": <number>,
"tm_create": "2022-04-29 07:01:45.808944",
"tm_update": "2022-04-29 07:02:48.304704"
}
id(UUID): The campaigncall’s unique identifier. Returned when listing viaGET /campaigncalls.campaign_id(UUID): The parent campaign. Obtained from theidfield ofGET /campaigns.outplan_id(UUID): The outplan used for this dial attempt. Obtained from theidfield ofGET /outplans.outdial_id(UUID): The outdial containing the target. Obtained from theidfield ofGET /outdials.outdial_target_id(UUID): The specific outdialtarget being dialed. Obtained from theidfield ofGET /outdials/{id}/targets.queue_id(UUID): The queue for routing the answered call. Obtained from theidfield ofGET /queues.activeflow_id(UUID): The activeflow executing the call actions. Obtained from theidfield ofGET /activeflows.reference_type(enum string): The type of resource this campaigncall is linked to. See Reference Type.reference_id(UUID): The ID of the referenced resource (e.g., the call ID whenreference_typeiscall).status(enum string): The campaigncall’s current status. See Status.result(enum string): The campaigncall’s outcome after completion. See Result.source(Object): Source address used for the dial attempt. See Address.destination(Object): Destination address being dialed. See Address.destination_index(Integer): Index of the destination within the outdialtarget (0-4), corresponding todestination_0throughdestination_4.try_count(Integer): The current attempt number for this destination.tm_create(string, ISO 8601): Timestamp when the campaigncall was created.tm_update(string, ISO 8601): Timestamp of the last update to the campaigncall.
Example
{
"id": "56347901-5bb9-422d-add5-5a2ca47fa737",
"campaign_id": "183c0d5c-691e-42f3-af2b-9bffc2740f83",
"outplan_id": "d5fb7357-7ddb-4f2d-87b5-8ccbfd6c039e",
"outdial_id": "40bea034-1d17-474d-a5de-da00d0861c69",
"outdial_target_id": "f50b169d-ce02-4bc9-a6e7-bb632c71e450",
"queue_id": "99bf739a-932f-433c-b1bf-103d33d7e9bb",
"activeflow_id": "02aad54d-270e-43c7-82c5-bf42502c8bc6",
"reference_type": "call",
"reference_id": "a69189aa-7295-4c3a-b51f-df1dbbded5f6",
"status": "done",
"result": "success",
"source": {
"type": "tel",
"target": "+15559876543",
"target_name": "",
"name": "",
"detail": ""
},
"destination": {
"type": "tel",
"target": "+15559876543",
"target_name": "",
"name": "",
"detail": ""
},
"destination_index": 0,
"try_count": 1,
"tm_create": "2022-04-29 07:01:45.808944",
"tm_update": "2022-04-29 07:02:48.304704"
}
Reference type
The type of resource this campaigncall is associated with. The reference_id field contains the ID of this resource.
Type |
Description |
|---|---|
none |
No associated resource. The campaigncall has not yet created a reference. |
call |
The campaigncall is associated with a voice call. The |
Status
The campaigncall’s current operational status. This is a read-only field managed by the system.
Type |
Description |
|---|---|
dialing |
The campaigncall is dialing the target. The call has not been answered yet. |
progressing |
The campaigncall is in progress. The target has answered and the flow actions are executing. |
done |
The campaigncall has completed. The call has been hung up. Check the |
Result
The campaigncall’s outcome, calculated from the final status of the referenced resource (call, SMS, etc.).
For example, if the call ended with no_answer, the result is calculated as fail.
Type |
Description |
|---|---|
“” |
No result yet. The campaigncall is still in progress ( |
success |
The campaigncall ended successfully. The outdialtarget’s status is set to |
fail |
The campaigncall ended unsuccessfully. The outdialtarget’s status is set to |
Note
AI Implementation Hint
Only a normal call hangup reason maps to success. All other hangup reasons (busy, no_answer, failed, etc.) map to fail. A fail result triggers a retry if the outdialtarget has not exceeded its max_try_count for the current destination index.
The call hangup reason - result mapping table.
Call hangup reason |
Calculated result |
|---|---|
normal |
success |
All others |
fail |
Tutorial
Before working with campaigns, you need:
An authentication token. Obtain one via
POST /auth/loginor use an access key fromGET /accesskeys.An outdial ID (UUID) with at least one target. Create an outdial via
POST /outdialsand add targets viaPOST /outdials/{id}/targets.An outplan ID (UUID) defining the dialing strategy. Create one via
POST /outplans.A queue ID (UUID) with agents assigned (for call-type campaigns that connect to agents). Create one via
POST /queues.(Optional) A flow ID (UUID) defining call actions. Create one via
POST /flows, or define inlineactionsin the campaign creation request.
Note
AI Implementation Hint
Campaigns are created in stop status. You must explicitly set the status to running via PUT /campaigns/{id} to start dialing. Running a campaign incurs charges for each outbound call or message made. Always verify your outdial targets and outplan settings before starting.
Get list of campaigns
Example
$ curl --location --request GET 'https://api.voipbin.net/v1.0/campaigns?token=<YOUR_AUTH_TOKEN>'
{
"result": [
{
"id": "183c0d5c-691e-42f3-af2b-9bffc2740f83",
"type": "call",
"name": "test campaign",
"detail": "test campaign detail",
"status": "stop",
"service_level": 100,
"end_handle": "stop",
"actions": [
{
"id": "00000000-0000-0000-0000-000000000000",
"next_id": "00000000-0000-0000-0000-000000000000",
"type": "talk",
"option": {
"text": "Hello. This is outbound campaign's test calling. Please wait until the agent answer the call. Thank you.",
"language": "en-US"
}
}
],
"outplan_id": "d5fb7357-7ddb-4f2d-87b5-8ccbfd6c039e",
"outdial_id": "40bea034-1d17-474d-a5de-da00d0861c69",
"queue_id": "99bf739a-932f-433c-b1bf-103d33d7e9bb",
"next_campaign_id": "00000000-0000-0000-0000-000000000000",
"tm_create": "2022-04-28 02:16:39.712142",
"tm_update": "2022-04-30 17:53:51.685259",
"tm_delete": "9999-01-01 00:00:00.000000"
}
],
"next_page_token": "2022-04-28 02:16:39.712142"
}
Get detail of campaign
Example
$ curl --location --request GET 'https://api.voipbin.net/v1.0/campaigns/183c0d5c-691e-42f3-af2b-9bffc2740f83?token=<YOUR_AUTH_TOKEN>'
{
"id": "183c0d5c-691e-42f3-af2b-9bffc2740f83",
"type": "call",
"name": "test campaign",
"detail": "test campaign detail",
"status": "stop",
"service_level": 100,
"end_handle": "stop",
"actions": [
{
"id": "00000000-0000-0000-0000-000000000000",
"next_id": "00000000-0000-0000-0000-000000000000",
"type": "talk",
"option": {
"text": "Hello. This is outbound campaign's test calling. Please wait until the agent answer the call. Thank you.",
"language": "en-US"
}
}
],
"outplan_id": "d5fb7357-7ddb-4f2d-87b5-8ccbfd6c039e",
"outdial_id": "40bea034-1d17-474d-a5de-da00d0861c69",
"queue_id": "99bf739a-932f-433c-b1bf-103d33d7e9bb",
"next_campaign_id": "00000000-0000-0000-0000-000000000000",
"tm_create": "2022-04-28 02:16:39.712142",
"tm_update": "2022-04-30 17:53:51.685259",
"tm_delete": "9999-01-01 00:00:00.000000"
}
Create a new campaign
Example
$ curl --location --request POST 'https://api.voipbin.net/v1.0/campaigns?token=<YOUR_AUTH_TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "test campaign",
"detail": "test campaign detail",
"type": "call",
"service_level": 100,
"end_handle": "stop",
"actions": [
{
"type": "talk",
"option": {
"text": "Hello. This is outbound campaign's test calling. Please wait until the agent answer the call. Thank you.",
"language": "en-US"
}
}
],
"outplan_id": "d5fb7357-7ddb-4f2d-87b5-8ccbfd6c039e",
"outdial_id": "40bea034-1d17-474d-a5de-da00d0861c69",
"queue_id": "99bf739a-932f-433c-b1bf-103d33d7e9bb"
}'
{
"id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
"name": "test campaign",
"detail": "test campaign detail",
"type": "call",
"status": "stop",
"service_level": 100,
"end_handle": "stop",
"outplan_id": "d5fb7357-7ddb-4f2d-87b5-8ccbfd6c039e",
"outdial_id": "40bea034-1d17-474d-a5de-da00d0861c69",
"queue_id": "99bf739a-932f-433c-b1bf-103d33d7e9bb",
"tm_create": "2022-10-22 16:16:16.874761",
"tm_update": "9999-01-01 00:00:00.000000",
"tm_delete": "9999-01-01 00:00:00.000000"
}