Launch a Campaign
Create and run an outbound voice or SMS campaign with voicemail deposit, live AI agent handoff, or human-like SMS drip sending.
This guide walks through creating a campaign end-to-end. Trunx supports two campaign channels:
- Voice — outbound calling with AMD, voicemail deposit, and AI agent handoff
- SMS — human-like bulk messaging with per-DID throttling (3-5 msgs/hr/DID)
The examples below show a voice campaign. For SMS, see the SMS campaign example at the end.
Upload audio for voicemail deposit
You can upload a pre-recorded file or generate audio from text using Trunx TTS.
curl -X POST https://api.trunx.io/audio \
-H "Authorization: Bearer $TRUNX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "q1-voicemail",
"text": "Hi, this is Sarah from Acme Solar. We have a special offer for homeowners in your area. Please call us back at your convenience.",
"voice": "american_female"
}'curl -X POST https://api.trunx.io/audio \
-H "Authorization: Bearer $TRUNX_API_KEY" \
-F "name=q1-voicemail" \
-F "file=@voicemail.mp3"Response:
{
"id": "aud_vm001",
"name": "q1-voicemail",
"duration_ms": 8200,
"created_at": "2026-03-09T14:00:00.000Z"
}Create the campaign
Configure the campaign with AI agent mode, voicemail audio, caller ID strategy, and a TCPA-compliant schedule. All configuration goes into the request body as flat fields.
curl -X POST https://api.trunx.io/campaigns \
-H "Authorization: Bearer $TRUNX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Q1 SoCal Outreach",
"mode": {
"ai": true,
"voicemailAudioUrl": "https://api.trunx.io/audio/aud_vm001/file",
"calls_per_second": 10,
"max_retries": 2,
"retry_delay": "4h"
},
"callerIds": ["+19495551000", "+17145551000"],
"callerIdStrategy": {
"selection": "health_score",
"local_presence": true
},
"schedule": {
"timezone": "America/Los_Angeles",
"startHour": 9,
"endHour": 17,
"days": [1, 2, 3, 4, 5]
}
}'Response:
{
"id": "camp_q1socal",
"name": "Q1 SoCal Outreach",
"status": "created",
"channel": "voice"
}Add prospects
Upload phone numbers to the campaign. Each number must be in E.164 format. You can add 1 to 10,000 numbers per request.
curl -X POST https://api.trunx.io/campaigns/camp_q1socal/prospects \
-H "Authorization: Bearer $TRUNX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phones": [
"+17145551001",
"+16195551002",
"+18185551003"
]
}'Response:
{
"added": 3
}Prospects are automatically checked against the suppression list (DNC) during dialing. Numbers on the DNC list are skipped.
Start dialing
curl -X POST https://api.trunx.io/campaigns/camp_q1socal/start \
-H "Authorization: Bearer $TRUNX_API_KEY"Response:
{
"id": "camp_q1socal",
"name": "Q1 SoCal Outreach",
"status": "dialing",
"channel": "voice"
}The campaign engine begins placing calls according to the schedule and rate limits.
Campaigns enforce TCPA time windows automatically. Calls are only placed during legal hours in the prospect's timezone, regardless of the campaign schedule.
Monitor progress
Check real-time stats at any time.
curl https://api.trunx.io/campaigns/camp_q1socal/stats \
-H "Authorization: Bearer $TRUNX_API_KEY"{
"total": 3,
"queued": 1,
"dialing": 0,
"completed": 2,
"failed": 0,
"cancelled": 0,
"noAnswer": 0,
"busy": 0,
"voicemail": 1,
"humanConnected": 1,
"progress": 66.7
}For real-time updates, stream events via SSE:
curl -N https://api.trunx.io/events?channels=campaign \
-H "Authorization: Bearer $TRUNX_API_KEY"Pause or resume
# Pause
curl -X POST https://api.trunx.io/campaigns/camp_q1socal/pause \
-H "Authorization: Bearer $TRUNX_API_KEY"
# Resume
curl -X POST https://api.trunx.io/campaigns/camp_q1socal/resume \
-H "Authorization: Bearer $TRUNX_API_KEY"All lifecycle actions return { id, name, status, channel }.
Campaign status flow:
created → dialing → completed
→ paused → dialing (resume)
→ cancelledThe campaign engine automatically rotates DIDs based on health scores. DIDs that drop below the health threshold are pulled from rotation and placed in cooldown. See the DID Health guide for details.
SMS campaign example
SMS campaigns skip the audio upload step. You provide the message text in mode.message and set channel: "sms".
# 1. Create SMS campaign
curl -X POST https://api.trunx.io/campaigns \
-H "Authorization: Bearer $TRUNX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "March Follow-Up Texts",
"channel": "sms",
"mode": {
"message": "Hi, this is Acme Solar following up on your inquiry. Reply YES to schedule a call."
},
"callerIds": ["+19495551000", "+17145551000"],
"schedule": {
"timezone": "America/Los_Angeles"
}
}'
# 2. Add prospects (same as voice)
curl -X POST https://api.trunx.io/campaigns/camp_sms001/prospects \
-H "Authorization: Bearer $TRUNX_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "phones": ["+17145551001", "+16195551002", "+18185551003"] }'
# 3. Start sending
curl -X POST https://api.trunx.io/campaigns/camp_sms001/start \
-H "Authorization: Bearer $TRUNX_API_KEY"SMS campaigns enforce a 7 AM – 7 PM sending window (stricter than voice TCPA). Messages are drip-sent at ~4 per DID per hour with 15-minute gaps for human-like pacing. With 10 DIDs, expect roughly 1 message every 90 seconds across the pool.
SMS prospect lifecycle
SMS prospects follow a different status flow than voice:
queued → sending → sent → delivered
→ failed- sending — message handed off to carrier
- sent — carrier accepted, awaiting delivery confirmation
- delivered — carrier confirmed delivery to recipient
- failed — carrier rejected or delivery failed