Create a Campaign

POST /v1/campaigns - create a voice broadcast or agent-dialer campaign with caller ID, TTS or audio message, concurrency, retries, calling window and schedule, then upload contacts and start it.

2 min read

POSThttps://voice-api.edesy.in/v1/campaigns

Create a campaign with a name, a from_number you own and either a message (audio_type of audio or tts) for broadcast, or a queue_id for an agent dialer. Then upload contacts, optionally test and estimate it, and call POST/v1/campaigns/{id}/start. The portal's four-step campaign wizard does the same.

1. Create#

curl -X POST https://voice-api.edesy.in/v1/campaigns \
  -H "Authorization: Bearer $EDESY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Diwali offer",
    "from_number": "+9180XXXXXXXX",
    "fallback_from_number": "+9180YYYYYYYY",
    "audio_type": "tts",
    "tts_text": "Namaste! Acme Diwali sale is live. Visit our store this week for 20 percent off.",
    "tts_language": "hi-IN",
    "max_concurrent": 10,
    "retry_attempts": 2,
    "retry_delay_sec": 1800,
    "ring_timeout_sec": 30,
    "amd_enabled": true,
    "recording_enabled": false,
    "window_start_minute": 600,
    "window_end_minute": 1200,
    "timezone": "Asia/Kolkata"
  }'
Field Type Required Description
name string Required Campaign name
from_number string Required Caller ID; a number in your workspace
fallback_from_number string Optional Backup caller ID used while the main one's carrier is refusing calls. Omit to use the workspace default; "" means none
audio_type string broadcast audio (upload a file) or tts
tts_text, tts_voice, tts_language string for tts Message text, voice and language
max_concurrent integer Optional Simultaneous calls
retry_attempts, retry_delay_sec integer Optional Retries for unanswered contacts, and the gap between them
ring_timeout_sec integer Optional Seconds to ring each contact
amd_enabled boolean Optional Answering-machine detection
recording_enabled boolean Optional Record calls
scheduled_at RFC 3339 Optional Start time
window_start_minute, window_end_minute integer Optional Daily calling window in minutes after midnight. Default 540 to 1260 (09:00 to 21:00)
timezone string Optional Timezone for the window, for example Asia/Kolkata
queue_id UUID agent dialer Contact-center queue whose free agents take answered calls
dial_ratio number Optional Agent dialer lines per free agent: 1.0 (progressive, default), 1.5 or 2.0 (power)

The response is the campaign object in data with its id and status.

2. Add the message (broadcast with audio)#

curl -X POST https://voice-api.edesy.in/v1/campaigns/{id}/audio \
  -H "Authorization: Bearer $EDESY_KEY" \
  -F "[email protected]"

WAV or MP3.

3. Add contacts#

CSV (multipart field contacts):

curl -X POST https://voice-api.edesy.in/v1/campaigns/{id}/contacts \
  -H "Authorization: Bearer $EDESY_KEY" \
  -F "[email protected]"
phone_number,name,consent_source,consent_timestamp
+9198XXXXXXXX,Asha,website_form,2026-10-01T10:00:00Z
+9197XXXXXXXX,Ravi,,

The phone column may be named phone_number, phone, number, mobile or msisdn; the name column name or contact_name. consent_source and consent_timestamp are optional and kept for your compliance export.

Or JSON:

{ "contacts": [ { "phone_number": "+9198XXXXXXXX", "name": "Asha" } ] }

The response accounts for every row:

{
  "data": {
    "contacts_added": 1,
    "total_rows": 2,
    "suppressed_dnc": 1,
    "suppressed_duplicate": 0,
    "invalid": 0,
    "invalid_samples": [],
    "consent_timestamp_unparsed": 0
  }
}

4. Test, estimate, start#

# Hear the message on your own phone
curl -X POST https://voice-api.edesy.in/v1/campaigns/{id}/test-call \
  -H "Authorization: Bearer $EDESY_KEY" -H "Content-Type: application/json" \
  -d '{ "phone_number": "+9198XXXXXXXX" }'

# Cost and duration estimate
curl https://voice-api.edesy.in/v1/campaigns/{id}/estimate -H "Authorization: Bearer $EDESY_KEY"

# Start now
curl -X POST https://voice-api.edesy.in/v1/campaigns/{id}/start -H "Authorization: Bearer $EDESY_KEY"

To start later, POST/v1/campaigns/{id}/schedule with scheduled_at (and optionally a new window, or "clear_window": true to remove it). DELETE/v1/campaigns/{id}/schedule cancels the schedule.

Control#

Action Endpoint
Pause / resume POST/v1/campaigns/{id}/pause, /resume
Stop for good POST/v1/campaigns/{id}/stop
Run again POST/v1/campaigns/{id}/duplicate with {"audience": "all"}, "unreached" or "none"

See also AMD, Fallback Caller ID and DNC and Estimate and Results.

Was this page helpful?