Text and Voice Broadcast Messaging

Overview

Broadcasting is a communication technique that broadcasts a text or voice messages to hundreds or thousands of recipients at once. CallFire provides 3 types of broadcasts: Text, Voice and IVR. The last two types are represented by single entity within CallFire API which called Call Broadcast.

Text Broadcasts

Text Broadcast allows you to send a short text message to a list of recipients. By default, all messages go out from the shared shortcode 67076. You can stay with our shortcode or buy a dedicated long or shortcode to use as the FromNumber. Recipients can reply to a received message, and those replies will appear on on the UI Inbox page and can be queried via API. CallFire provides the ability to create a templated message, for instance "Hello ${user}, the current date is ${current_date}" and then pass attributes or custom fields unique to each recipient.

You can create a broadcast with no contacts and bare minimum configuration and add contacts later to an existing broadcast. The code examples below show how to create a broadcast with recipients and a templated message:

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
    {
        "name":"Charity SMS Campaign",
        "labels":
        [
            "charity",
            "id-10003"
        ],
        "fromNumber":"19206596476",
        "recipients":
        [
            {
                "phoneNumber":"13233834422",
                "attributes":
                {
                    "u_name": "Alice",
                    "age": 30
                }
            },
            {
                "phoneNumber":"13233834433",
                "attributes":
                {
                    "u_name": "Mark",
                    "age": 45
                }
            },
            {
                "phoneNumber":"13233834488",
                "message": "Hi ${u_name}, the megic number is ${magic_number}",
                "attributes":
                {
                    "u_name": "Jane",
                    "magic_number": "10"
                }
            }
        ],
        "message":"Hello {u_name} ..."
    }' "https://api.callfire.com/v2/texts/broadcasts"
response:
{
  "id": 13
}
[-curl] [+java]

import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.campaigns.model.TextBroadcast;
import com.callfire.api.client.api.campaigns.model.TextRecipient;
import com.callfire.api.client.api.common.model.ResourceId;

import java.util.Arrays;

class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");

        TextBroadcast broadcast = new TextBroadcast();
        broadcast.setName("Charity SMS Campaign");
        // attach custom labels if needed
        broadcast.setLabels(Arrays.asList("charity", "id-10003"));
        // You can use default shared short code 67076 or uncomment the next line and set your own number
        broadcast.setFromNumber("19206596476");

        // by default if text exceeds length of 160 characters, CallFire will send a text as multiple messages.
        // broadcast.setBigMessageStrategy(TextBroadcast.BigMessageStrategy.TRIM);
        broadcast.setMessage("Hello {u_name} ...");

        // add new recipients
        TextRecipient recipient1 = new TextRecipient();
        recipient1.setPhoneNumber("13233834422");
        // set custom recipient attributes, they are available only to a single Call/Text
        //  action, do not confuse them with contact fields which are stored with contact and are available to
        //  each Call/Text where contact is attached to
        recipient1.getAttributes().put("u_name", "Alice");
        recipient1.getAttributes().put("age", "30");

        TextRecipient recipient2 = new TextRecipient();
        recipient2.setPhoneNumber("13233834433");
        recipient2.getAttributes().put("u_name", "Mark");
        recipient2.getAttributes().put("age", "45");

        TextRecipient recipient3 = new TextRecipient();
        recipient3.setPhoneNumber("13233834488");
        // You can override a message set in broadcast for a particular recipient
        recipient3.setMessage("Hi {u_name}, the megic number is ${magic_number}");
        // Set custom attribute
        recipient3.getAttributes().put("u_name", "Jane");
        recipient3.getAttributes().put("magic_number", "10");

        broadcast.setRecipients(Arrays.asList(recipient1, recipient2, recipient3));

        // create broadcast and start immediately
        ResourceId id = client.textBroadcastsApi().create(broadcast, true);
    }
}
[-java] [+csharp]
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.CallsTexts.Model;
using CallfireApiClient.Api.Campaigns.Model;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var broadcast = new TextBroadcast
        {
            Name = "Charity Campaign",
            // set validated Caller ID number.
            FromNumber = "19206596476",
            // attach custom labels if needed
            Labels = new List<string> {"charity", "id-10003"},
            // set message text
            Message = @"Hello {u_name} ...",
            // add new recipients
            Recipients = new List<TextRecipient>
            {
                new TextRecipient
                {
                    PhoneNumber = "13233834422",
                    // set custom recipient attributes, they are available only to a single Call/Text
                    //  action, do not confuse them with contact fields which are stored with contact
                    //  and are available to each Call/Text where contact is attached to
                    Attributes = new Dictionary<string, string>
                    {
                        {"u_name", "Alice"},
                        {"age", "30"}
                    }
                },
                new TextRecipient
                {
                    PhoneNumber = "13233834433",
                    Attributes = new Dictionary<string, string>
                    {
                        {"u_name", "Mark"},
                        {"age", "45"}
                    }
                },
                new TextRecipient
                {
                    PhoneNumber = "13233834488",
                    // you can override a message set in broadcast for a particular recipient
                    Message = "Hi ${u_name}, the megic number is ${magic_number}",
                    Attributes = new Dictionary<string, string>
                    {
                        {"u_name", "Jane"},
                        {"magic_number", "10"}
                    }
                }
            }
        };

        // create broadcast with 'start' argument = true to start campaign immediately
        var id = client.TextBroadcastsApi.Create(broadcast, true);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.texts.createTextBroadcast({
      // set start parameter to run broadcast immediately
      // start: true,
      body: {
        name: 'Charity SMS Campaign',
        labels: [
          'charity',
          'id-10003'
        ],
        fromNumber: '19206596476',
        recipients: [
          {
            phoneNumber: '13233834422',
            attributes: {
              u_name: 'Alice',
              age: 30
            }
          },
          {
            phoneNumber: '13233834433',
            attributes: {
              u_name: 'Mark',
              age: 45
            }
          },
          {
            phoneNumber: '13233834488',
            message: 'Hi ${u_name}, the megic number is ${magic_number}',
            attributes: {
              u_name: 'Jane',
              magic_number: 10
            }
          }
        ],
        message: 'Hello {u_name} ...'
      }
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
response = client.texts.createTextBroadcast(
    # set start parameter to run broadcast immediately
    # start: true,
    body={
        'name': 'Charity SMS Campaign',
        'labels': [
            'charity',
            'id-10003'
        ],
        'fromNumber': '19206596476',
        'recipients': [
            {
                'phoneNumber': '13233834422',
                'attributes': {
                    'u_name': 'Alice',
                    'age': 30
                }
            },
            {
                'phoneNumber': '13233834433',
                'attributes': {
                    'u_name': 'Mark',
                    'age': 45
                }
            },
            {
                'phoneNumber': '13233834488',
                'message': 'Hi ${u_name}, the megic number is ${magic_number}',
                'attributes': {
                    'u_name': 'Jane',
                    'magic_number': 10
                }
            }
        ],
        'message': 'Hello {u_name} ...'
    }
).result()

# see sample JSON response for this API
# on 'curl' samples tab
print(response)
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->createTextBroadcast();
        $body = '{
                    "name":"Charity SMS Campaign",
                    "labels":
                    [
                        "charity",
                        "id-10003"
                    ],
                    "fromNumber":"19206596476",
                    "recipients":
                    [
                        {
                            "phoneNumber":"13233834422",
                            "attributes":
                            {
                                "u_name": "Alice",
                                "age": 30
                            }
                        },
                        {
                            "phoneNumber":"13233834433",
                            "attributes":
                            {
                                "u_name": "Mark",
                                "age": 45
                            }
                        },
                        {
                            "phoneNumber":"13233834488",
                            "message": "Hi ${u_name}, the megic number is ${magic_number}",
                            "attributes":
                            {
                                "u_name": "Jane",
                                "magic_number": "10"
                            }
                        }
                    ],
                    "message":"Hello {u_name} ..."
                 }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

See Create Text Broadcast API for detailed information about accepted parameters and responses.

Call Broadcasts (Voice and IVR)

Call Broadcasts represent two type of broadcasts: Voice and IVR. Everything that Voice broadcast can do you can also accomplish with the IVR broadcast, and the IVR allows you to ask questions through pre-recorded or text-to-speech prompts, and receive responses via phone key presses.

Voice Broadcasts allow you to send a pre-recorded voice message to a number of people. You can configure what message to play if the call is answered by a person, and set a different message to play if an answering machine is detected. Voice broadcasts can be configured to transfer a call when a transfer digit is pressed. The following settings are available for Call Broadcasts (Voice & IVR):

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
    {
        "name":"Call Broadcast",
        "fromNumber":"12135551189",
        "answeringMachineConfig":"AM_AND_LIVE",
        "sounds":
        {
            "liveSoundText":"Hello! This is a live answer text to speech recording",
            "machineSoundText":"This is an answering machine text to speech recording"
        },
        "labels":
        [
            "voice tag",
            "id-10002"
        ],
        "localTimeRestriction":
        {
            "beginHour": 9,
            "beginMinute": 0,
            "endHour": 18,
            "endMinute": 0
        },
        "schedules":
        [
            {
                "startTimeOfDay":
                {
                    "hour": 10,
                    "minute": 0,
                    "second": 0
                },
                "daysOfWeek":
                [
                    "MONDAY",
                    "WEDNESDAY"
                ],
                "timeZone": "America/New_York",
                "startDate":
                {
                    "year": 2016,
                    "month": 12,
                    "day": 1
                }
            }
        ],
        "retryConfig":
        {
            "maxAttempts": 2,
            "minutesBetweenAttempts": 5,
            "retryResults":
            [
                "BUSY",
                "NO_ANS"
            ],
            "retryPhoneTypes":
            [
                "MOBILE_PHONE",
                "WORK_PHONE"
            ]
        }
    }' "https://api.callfire.com/v2/calls/broadcasts"
response:
{
  "id": 15
}
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.campaigns.model.AnsweringMachineConfig;
import com.callfire.api.client.api.campaigns.model.CallBroadcast;
import com.callfire.api.client.api.campaigns.model.CallBroadcastSounds;
import com.callfire.api.client.api.campaigns.model.LocalTimeRestriction;
import com.callfire.api.client.api.campaigns.model.RetryConfig;
import com.callfire.api.client.api.campaigns.model.RetryConfig.RetryPhoneTypes;
import com.callfire.api.client.api.campaigns.model.RetryConfig.RetryResults;
import com.callfire.api.client.api.campaigns.model.Schedule;
import com.callfire.api.client.api.common.model.LocalDate;
import com.callfire.api.client.api.common.model.LocalTime;
import com.callfire.api.client.api.common.model.ResourceId;

import java.time.DayOfWeek;
import java.util.Arrays;
import java.util.HashSet;

class CreateVoiceBroadcastSample {

    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");
        CallBroadcast broadcast = new CallBroadcast();
        broadcast.setName("Call Broadcast");
        // attach custom labels if needed
        broadcast.setLabels(Arrays.asList("voice tag", "id-10002"));
        // set validated Caller ID number. 
        broadcast.setFromNumber("12135551189");
        // set answering machine detection
        broadcast.setAnsweringMachineConfig(AnsweringMachineConfig.AM_AND_LIVE);

        // set voice messages using TTS option for Live answers and when Answering Machine is detected.
        // you also can set a pre-defined TTS voice.
        CallBroadcastSounds sounds = new CallBroadcastSounds();
        sounds.setLiveSoundText("Hello! This is a live answer text to speech recording");
        sounds.setMachineSoundText("This is an answering machine text to speech recording");
        broadcast.setSounds(sounds);

        // allow CallFire to dial recipient only between 09:00 - 18:00 depending on
        //  recipient's number area code timezone
        LocalTimeRestriction timeRestriction = new LocalTimeRestriction();
        timeRestriction.setBeginHour(9);
        timeRestriction.setBeginMinute(0);
        timeRestriction.setEndHour(18);
        timeRestriction.setEndMinute(0);
        broadcast.setLocalTimeRestriction(timeRestriction);

        // set retry configuration to attempt a contact's Mobile and Work phone numbers twice in case Call was 
        //  resulted to BUSY or No Answer response. Set 5 minutes between attempts.  
        RetryConfig retryConfig = new RetryConfig();
        retryConfig.setMaxAttempts(2);
        retryConfig.setMinutesBetweenAttempts(5);
        retryConfig.setRetryResults(Arrays.asList(RetryResults.BUSY, RetryResults.NO_ANS));
        retryConfig.setRetryPhoneTypes(Arrays.asList(RetryPhoneTypes.MOBILE_PHONE, RetryPhoneTypes.WORK_PHONE));
        broadcast.setRetryConfig(retryConfig);

        // schedule a campaign to run on every Monday and Wednesday starting from 2016-12-01 10:00:00 
        Schedule schedule = new Schedule();
        schedule.setStartDate(new LocalDate(2016, 12, 1));
        schedule.setStartTimeOfDay(new LocalTime(10, 0, 0));
        // set weekly schedule
        schedule.setDaysOfWeek(new HashSet<>(Arrays.asList(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY)));
        // set optional time zone, if leave empty account's timezone will be used 
        schedule.setTimeZone("America/New_York");
        broadcast.setSchedules(Arrays.asList(schedule));

        // create broadcast with 'start' argument = true to start campaign immediately
        ResourceId id = client.callBroadcastsApi().create(broadcast);

        System.out.println(id);
    }
}
[-java] [+csharp]
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.Campaigns.Model;
using CallfireApiClient.Api.Common.Model;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var broadcast = new CallBroadcast
        {
            Name = "Call Broadcast",
            // set validated Caller ID number.
            FromNumber = "12135551189",
            // attach custom labels if needed
            Labels = new List<string> { "voice tag", "id-10002" },
            // set answering machine detection
            AnsweringMachineConfig = AnsweringMachineConfig.AM_AND_LIVE,
            // set voice messages using TTS option for Live answers and when Answering Machine is detected.
            Sounds = new CallBroadcastSounds
            {
                LiveSoundText = "Hello! This is a live answer text to speech recording",
                MachineSoundText = "This is an answering machine text to speech recording",
            },
            // allow CallFire to dial recipient only between 09:00 - 18:00 depending on
            //  recipient's number area code timezone
            LocalTimeRestriction = new LocalTimeRestriction
            {
                BeginHour = 9,
                BeginMinute = 0,
                EndHour = 18,
                EndMinute = 0
            },
            // schedule a campaign to run on every Monday and Wednesday starting from 2016-12-01 10:00:00
            Schedules = new List<Schedule>
            {
                new Schedule
                {
                    StartDate = new LocalDate {Year = 2016, Month = 12, Day = 1},
                    StartTimeOfDay = new LocalTime {Hour = 10, Minute = 0, Second = 0},
                    // set weekly schedule
                    DaysOfWeek = new HashSet<DayOfWeek> {DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY},
                    // set optional time zone, if leave empty account's timezone will be used
                    TimeZone = "America/New_York"
                }
            },
            // set retry configuration to attempt a contact's Mobile and Work phone numbers twice in case Call was
            //  resulted to BUSY or No Answer response. Set 5 minutes between attempts.
            RetryConfig = new RetryConfig
            {
                MaxAttempts = 2,
                MinutesBetweenAttempts = 5,
                RetryResults = new List<RetryResults> { RetryResults.BUSY, RetryResults.NO_ANS },
                RetryPhoneTypes = new List<RetryPhoneTypes>
                {
                    RetryPhoneTypes.MOBILE_PHONE,
                    RetryPhoneTypes.WORK_PHONE
                }
            }
        };

        // create broadcast with 'start' argument = true to start campaign immediately
        var id = client.CallBroadcastsApi.Create(broadcast);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.createCallBroadcast({
      body: {
        name: 'Call Broadcast',
        fromNumber: '12135551189',
        answeringMachineConfig: 'AM_AND_LIVE',
        sounds: {
          liveSoundText: 'Hello! This is a live answer text to speech recording',
          machineSoundText: 'This is an answering machine text to speech recording'
        },
        labels: [
          'voice tag',
          'id-10002'
        ],
        localTimeRestriction: {
          beginHour: 9,
          beginMinute: 0,
          endHour: 18,
          endMinute: 0
        },
        schedules: [
          {
            startTimeOfDay: {
              hour: 10,
              minute: 0,
              second: 0
            },
            daysOfWeek: [
              'MONDAY',
              'WEDNESDAY'
            ],
            timeZone: 'America/New_York',
            startDate: {
              year: 2016,
              month: 12,
              day: 1
            }
          }
        ],
        retryConfig: {
          maxAttempts: 2,
          minutesBetweenAttempts: 5,
          retryResults: [
            'BUSY',
            'NO_ANS'
          ],
          retryPhoneTypes: [
            'MOBILE_PHONE',
            'WORK_PHONE'
          ]
        }
      }
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
response = client.calls.createCallBroadcast(
    body={
        'name': 'Call Broadcast',
        'fromNumber': '12135551189',
        'answeringMachineConfig': 'AM_AND_LIVE',
        'sounds': {
            'liveSoundText': 'Hello! This is a live answer text to speech recording',
            'machineSoundText': 'This is an answering machine text to speech recording'
        },
        'labels': [
            'voice tag',
            'id-10002'
        ],
        'localTimeRestriction': {
            'beginHour': 9,
            'beginMinute': 0,
            'endHour': 18,
            'endMinute': 0
        },
        'schedules': [
            {
                'startTimeOfDay': {
                    'hour': 10,
                    'minute': 0,
                    'second': 0
                },
                'daysOfWeek': [
                    'MONDAY',
                    'WEDNESDAY'
                ],
                'timeZone': 'America/New_York',
                'startDate': {
                    'year': 2016,
                    'month': 12,
                    'day': 1
                }
            }
        ],
        'retryConfig': {
            'maxAttempts': 2,
            'minutesBetweenAttempts': 5,
            'retryResults': [
                'BUSY',
                'NO_ANS'
            ],
            'retryPhoneTypes': [
                'MOBILE_PHONE',
                'WORK_PHONE'
            ]
        }
    }
).result()

# see sample JSON response for this API
# on 'curl' samples tab
print(response)
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->createCallBroadcast();
        $body = '{
                    "name":"Call Broadcast",
                    "fromNumber":"12135551189",
                    "answeringMachineConfig":"AM_AND_LIVE",
                    "sounds":
                    {
                        "liveSoundText":"Hello! This is a live answer text to speech recording",
                        "machineSoundText":"This is an answering machine text to speech recording"
                    },
                    "labels":
                    [
                        "voice tag",
                        "id-10002"
                    ],
                    "localTimeRestriction":
                    {
                        "beginHour": 9,
                        "beginMinute": 0,
                        "endHour": 18,
                        "endMinute": 0
                    },
                    "schedules":
                    [
                        {
                            "startTimeOfDay":
                            {
                                "hour": 10,
                                "minute": 0,
                                "second": 0
                            },
                            "daysOfWeek":
                            [
                                "MONDAY",
                                "WEDNESDAY"
                            ],
                            "timeZone": "America/New_York",
                            "startDate":
                            {
                                "year": 2016,
                                "month": 12,
                                "day": 1
                            }
                        }
                    ],
                    "retryConfig":
                    {
                        "maxAttempts": 2,
                        "minutesBetweenAttempts": 5,
                        "retryResults":
                        [
                            "BUSY",
                            "NO_ANS"
                        ],
                        "retryPhoneTypes":
                        [
                            "MOBILE_PHONE",
                            "WORK_PHONE"
                        ]
                    }
                 }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

Let's take a look how to create an IVR broadcast. The next XML sample represents a CallFire IVR dialplan which does the following:

<dialplan name="Root">
    <!-- answering machine detection -->
    <amd>
        <!-- if call is answered by human go to live menu -->
        <live>
            <goto>live</goto>
        </live>
        <!-- hangup if answering machine detected -->
        <machine>
            <goto>hangup</goto>
        </machine>
    </amd>
    <menu maxDigits="1" timeout="3500" name="live">
        <!-- play a text message -->
        <play type="tts" voice="female1" name="play_msg">Hello, ${contact.firstName}, this is CallFire IVR message.</play>
        <!-- user has pressed 1, repeat starting from menu entry -->
        <keypress pressed="1">
            <goto>live</goto>
        </keypress>
        <!-- nothing is pressed for a 3500 milliseconds, hang up the phone -->
        <keypress pressed="timeout">
            <hangup/>
        </keypress>
    </menu>
    <hangup name="hangup"/>
</dialplan>

You can find more information about the IVR at CallFire Answers Page and different IVR examples are available on our public Github repository.

Check the CallFire XML page for a detailed description of all IVR tags.

The examples below show how to send an IVR call with the given dialplan, please make sure you properly encoded an XML string; otherwise you'll receive 400 Bad Request response.

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
{
  "name": "Call Broadcast",
  "fromNumber": "12135551189",
  "labels": [
    "ivr tag",
    "id-10002"
  ],
  "localTimeRestriction": {
    "beginHour": 9,
    "beginMinute": 0,
    "endHour": 18,
    "endMinute": 0
  },
  "schedules": [
    {
      "startTimeOfDay": {
        "hour": 10,
        "minute": 0,
        "second": 0
      },
      "daysOfWeek": [
        "MONDAY",
        "WEDNESDAY"
      ],
      "timeZone": "America/New_York",
      "startDate": {
        "year": 2016,
        "month": 12,
        "day": 1
      }
    }
  ],
  "retryConfig": {
    "maxAttempts": 2,
    "minutesBetweenAttempts": 5,
    "retryResults": [
      "BUSY",
      "NO_ANS"
    ],
    "retryPhoneTypes": [
      "MOBILE_PHONE",
      "WORK_PHONE"
    ]
  }, 
  "dialPlanXml": "<dialplan name=\"Root\"> <amd> <live> <goto>live</goto> </live> <machine> <goto>hangup</goto> </machine> </amd> <menu maxDigits=\"1\" timeout=\"3500\" name=\"live\"> <play type=\"tts\" voice=\"female1\" name=\"play_msg\">Hello, ${contact.firstName}, this is CallFire IVR message.</play> <keypress pressed=\"1\"> <goto>live</goto> </keypress> <keypress pressed=\"timeout\"> <hangup/> </keypress> </menu> <hangup name=\"hangup\"/> </dialplan>"
}' "https://api.callfire.com/v2/calls/broadcasts"
response:
{
  "id": 15
}
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.campaigns.model.CallBroadcast;
import com.callfire.api.client.api.campaigns.model.LocalTimeRestriction;
import com.callfire.api.client.api.campaigns.model.RetryConfig;
import com.callfire.api.client.api.campaigns.model.RetryConfig.RetryPhoneTypes;
import com.callfire.api.client.api.campaigns.model.RetryConfig.RetryResults;
import com.callfire.api.client.api.campaigns.model.Schedule;
import com.callfire.api.client.api.common.model.LocalDate;
import com.callfire.api.client.api.common.model.LocalTime;
import com.callfire.api.client.api.common.model.ResourceId;

import java.time.DayOfWeek;
import java.util.Arrays;
import java.util.HashSet;

class CreateVoiceBroadcastSample {

    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");
        CallBroadcast broadcast = new CallBroadcast();
        broadcast.setName("Call Broadcast");
        // attach custom labels if needed
        broadcast.setLabels(Arrays.asList("ivr tag", "id-10002"));
        // set validated Caller ID number. 
        broadcast.setFromNumber("12135551189");
        // add IVR XML
        broadcast.setDialplanXml(buildDialplanXml());

        // allow CallFire to dial recipient only between 09:00 - 18:00 depending on
        //  recipient's number area code timezone
        LocalTimeRestriction timeRestriction = new LocalTimeRestriction();
        timeRestriction.setBeginHour(10);
        timeRestriction.setBeginMinute(0);
        timeRestriction.setEndHour(18);
        timeRestriction.setEndMinute(0);
        broadcast.setLocalTimeRestriction(timeRestriction);

        // set retry configuration to attempt a contact's Mobile and Work phone numbers twice in case Call was 
        //  resulted to BUSY or No Answer response. Set 5 minutes between attempts.  
        RetryConfig retryConfig = new RetryConfig();
        retryConfig.setMaxAttempts(2);
        retryConfig.setMinutesBetweenAttempts(5);
        retryConfig.setRetryResults(Arrays.asList(RetryResults.BUSY, RetryResults.NO_ANS));
        retryConfig.setRetryPhoneTypes(Arrays.asList(RetryPhoneTypes.MOBILE_PHONE, RetryPhoneTypes.WORK_PHONE));
        broadcast.setRetryConfig(retryConfig);

        // schedule a campaign to run on every Monday and Wednesday starting from 2016-12-01 10:00:00 
        Schedule schedule = new Schedule();
        schedule.setStartDate(new LocalDate(2016, 12, 1));
        schedule.setStartTimeOfDay(new LocalTime(10, 0, 0));
        // set weekly schedule
        schedule.setDaysOfWeek(new HashSet<>(Arrays.asList(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY)));
        // set optional time zone, if leave empty account's timezone will be used 
        schedule.setTimeZone("America/New_York");
        broadcast.setSchedules(Arrays.asList(schedule));

        // create broadcast with 'start' argument = true to start campaign immediately
        ResourceId id = client.callBroadcastsApi().create(broadcast);

        System.out.println(id);
    }

    private static String buildDialplanXml() {
        return
            "<dialplan name=\"Root\">" +
            "<!-- answering machine detection -->" +
            "<amd>" +
            "    <!-- if call is answered by human go to live menu -->" +
            "    <live>" +
            "        <goto>live</goto>" +
            "    </live>" +
            "    <!-- hangup if answering machine detected -->" +
            "    <machine>" +
            "        <goto>hangup</goto>" +
            "    </machine>" +
            "</amd>" +
            "<menu maxDigits=\"1\" timeout=\"3500\" name=\"live\">" +
            "    <!-- play a text message -->" +
            "    <play type=\"tts\" voice=\"female1\" name=\"play_msg\">Hello, ${contact.firstName}, this is CallFire IVR message.</play>" +
            "    <!-- user has pressed 1, repeat starting from menu entry -->" +
            "    <keypress pressed=\"1\">" +
            "        <goto>live</goto>" +
            "    </keypress>" +
            "    <!-- nothing is pressed for a 3500 milliseconds, hang up the phone -->" +
            "    <keypress pressed=\"timeout\">" +
            "        <hangup/>" +
            "    </keypress>" +
            "</menu>" +
            "<hangup name=\"hangup\"/>" +
            "</dialplan>";
    }
}
[-java] [+csharp]
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.Campaigns.Model;
using CallfireApiClient.Api.Common.Model;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var broadcast = new CallBroadcast
        {
            Name = "Call Broadcast",
            // set validated Caller ID number.
            FromNumber = "12135551189",
            // attach custom labels if needed
            Labels = new List<string> { "ivr tag", "id-10002" },
            // allow CallFire to dial recipient only between 09:00 - 18:00 depending on
            //  recipient's number area code timezone
            LocalTimeRestriction = new LocalTimeRestriction
            {
                BeginHour = 9,
                BeginMinute = 0,
                EndHour = 18,
                EndMinute = 0
            },
            // schedule a campaign to run on every Monday and Wednesday starting from 2016-12-01 10:00:00
            Schedules = new List<Schedule>
            {
                new Schedule
                {
                    StartDate = new LocalDate {Year = 2016, Month = 12, Day = 1},
                    StartTimeOfDay = new LocalTime {Hour = 10, Minute = 0, Second = 0},
                    // set weekly schedule
                    DaysOfWeek = new HashSet<DayOfWeek> {DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY},
                    // set optional time zone, if leave empty account's timezone will be used
                    TimeZone = "America/New_York"
                }
            },
            // set retry configuration to attempt a contact's Mobile and Work phone numbers twice in case Call was
            //  resulted to BUSY or No Answer response. Set 5 minutes between attempts.
            RetryConfig = new RetryConfig
            {
                MaxAttempts = 2,
                MinutesBetweenAttempts = 5,
                RetryResults = new List<RetryResults> { RetryResults.BUSY, RetryResults.NO_ANS },
                RetryPhoneTypes = new List<RetryPhoneTypes>
                {
                    RetryPhoneTypes.MOBILE_PHONE,
                    RetryPhoneTypes.WORK_PHONE
                }
            },
            // set IVR XML
            DialplanXml = @"
                <dialplan name=""Root"">
                    <!-- answering machine detection -->
                    <amd>
                        <!-- if call is answered by human go to live menu -->
                        <live>
                            <goto>live</goto>
                        </live>
                        <!-- hangup if answering machine detected -->
                        <machine>
                            <goto>hangup</goto>
                        </machine>
                    </amd>
                    <menu maxDigits=""1"" timeout=""3500"" name=""live"">
                        <!-- play a text message -->
                        <play type=""tts"" voice=""female1"" name=""play_msg"">Hello, ${contact.firstName}, this is CallFire IVR message.</play>
                        <!-- user has pressed 1, repeat starting from menu entry -->
                        <keypress pressed=""1"">
                            <goto>live</goto>
                        </keypress>
                        <!-- nothing is pressed for a 3500 milliseconds, hang up the phone -->
                        <keypress pressed=""timeout"">
                            <hangup/>
                        </keypress>
                    </menu>
                    <hangup name=""hangup""/>
                </dialplan>
            "
        };

        // create broadcast with 'start' argument = true to start campaign immediately
        var id = client.CallBroadcastsApi.Create(broadcast);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.createCallBroadcast({
      body: {
        name: 'Call Broadcast',
        fromNumber: '12135551189',
        labels: [
          'ivr tag',
          'id-10002'
        ],
        localTimeRestriction: {
          beginHour: 9,
          beginMinute: 0,
          endHour: 18,
          endMinute: 0
        },
        schedules: [
          {
            startTimeOfDay: {
              hour: 10,
              minute: 0,
              second: 0
            },
            daysOfWeek: [
              'MONDAY',
              'WEDNESDAY'
            ],
            timeZone: 'America/New_York',
            startDate: {
              year: 2016,
              month: 12,
              day: 1
            }
          }
        ],
        retryConfig: {
          maxAttempts: 2,
          minutesBetweenAttempts: 5,
          retryResults: [
            'BUSY',
            'NO_ANS'
          ],
          retryPhoneTypes: [
            'MOBILE_PHONE',
            'WORK_PHONE'
          ]
        },
        dialPlanXml: '<dialplan name=\"Root\"> <amd> <live> <goto>live</goto> </live> <machine> <goto>hangup</goto> </machine> </amd> <menu maxDigits=\"1\" timeout=\"3500\" name=\"live\"> <play type=\"tts\" voice=\"female1\" name=\"play_msg\">Hello, ${contact.firstName}, this is CallFire IVR message.</play> <keypress pressed=\"1\"> <goto>live</goto> </keypress> <keypress pressed=\"timeout\"> <hangup/> </keypress> </menu> <hangup name=\"hangup\"/> </dialplan>'
      }
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
response = client.calls.createCallBroadcast(
    body={
        'name': 'Call Broadcast',
        'fromNumber': '12135551189',
        'labels': [
            'ivr tag',
            'id-10002'
        ],
        'localTimeRestriction': {
            'beginHour': 9,
            'beginMinute': 0,
            'endHour': 18,
            'endMinute': 0
        },
        'schedules': [
            {
                'startTimeOfDay': {
                    'hour': 10,
                    'minute': 0,
                    'second': 0
                },
                'daysOfWeek': [
                    'MONDAY',
                    'WEDNESDAY'
                ],
                'timeZone': 'America/New_York',
                'startDate': {
                    'year': 2016,
                    'month': 12,
                    'day': 1
                }
            }
        ],
        'retryConfig': {
            'maxAttempts': 2,
            'minutesBetweenAttempts': 5,
            'retryResults': [
                'BUSY',
                'NO_ANS'
            ],
            'retryPhoneTypes': [
                'MOBILE_PHONE',
                'WORK_PHONE'
            ]
        },
        'dialPlanXml': '<dialplan name=\"Root\"> <amd> <live> <goto>live</goto> </live> <machine> <goto>hangup</goto> </machine> </amd> <menu maxDigits=\"1\" timeout=\"3500\" name=\"live\"> <play type=\"tts\" voice=\"female1\" name=\"play_msg\">Hello, ${contact.firstName}, this is CallFire IVR message.</play> <keypress pressed=\"1\"> <goto>live</goto> </keypress> <keypress pressed=\"timeout\"> <hangup/> </keypress> </menu> <hangup name=\"hangup\"/> </dialplan>'
    }
).result()

# see sample JSON response for this API
# on 'curl' samples tab
print(response)
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->createCallBroadcast();
        $body = '{
                    "name": "Call Broadcast",
                    "fromNumber": "12135551189",
                    "labels":
                    [
                        "ivr tag",
                        "id-10002"
                    ],
                    "localTimeRestriction":
                    {
                        "beginHour": 9,
                        "beginMinute": 0,
                        "endHour": 18,
                        "endMinute": 0
                    },
                    "schedules":
                    [
                        {
                            "startTimeOfDay":
                            {
                                "hour": 10,
                                "minute": 0,
                                "second": 0
                            },
                            "daysOfWeek":
                            [
                                "MONDAY",
                                "WEDNESDAY"
                            ],
                            "timeZone": "America/New_York",
                            "startDate":
                            {
                                "year": 2016,
                                "month": 12,
                                "day": 1
                            }
                        }
                    ],
                    "retryConfig":
                    {
                        "maxAttempts": 2,
                        "minutesBetweenAttempts": 5,
                        "retryResults":
                        [
                            "BUSY",
                            "NO_ANS"
                        ],
                        "retryPhoneTypes":
                        [
                            "MOBILE_PHONE",
                            "WORK_PHONE"
                        ]
                    },
                    "dialPlanXml": "<dialplan name=\"Root\"> <amd> <live> <goto>live</goto> </live> <machine> <goto>hangup</goto> </machine> </amd> <menu maxDigits=\"1\" timeout=\"3500\" name=\"live\"> <play type=\"tts\" voice=\"female1\" name=\"play_msg\">Hello, ${contact.firstName}, this is CallFire IVR message.</play> <keypress pressed=\"1\"> <goto>live</goto> </keypress> <keypress pressed=\"timeout\"> <hangup/> </keypress> </menu> <hangup name=\"hangup\"/> </dialplan>"
                 }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

See Create Call Broadcast API for detailed information about accepted parameters and responses.

How to Add Recipients / Contacts to an Existing Broadcast

You can add only phone numbers to a broadcast (no contact names required), or you can add existing contacts. CallFire creates contacts on the fly from the recipients' numbers. Check contacts guide for more information on how to manage CallFire Contacts.

Users have two options to add contacts to an existing broadcast:

Both methods above are applicable for Call Broadcasts, the same methods are available for Text Broadcasts as well.

The main difference to both approaches is the first one accepts an existing contact list id and performs validation of recipients' numbers, whereas the second one does not perform a contact validation, so you may have duplicates in your broadcast. In case if you are adding recipients as plain phone numbers and one of passed numbers is bad, the API will return an error.

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
    {
        "name":"contact batch for call broadcast",
        "recipients":
        [
            {
                "phoneNumber":"12135551122"
            },
            {
                "phoneNumber":"12135553434"
            },
            {
                "phoneNumber":"12135558090",
                "attributes":
                {
                    "custom_external_id": 30005044,
                    "custom_property_1": "value1"
                }
            }
        ],
        # or you can add contacts from particular contact list
        # contactListId: 70055003,
        "scrubDuplicates": true
    }' "https://api.callfire.com/v2/calls/broadcasts/11646003/batches"
response:
{
  "id": 13
}
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.callstexts.model.CallRecipient;
import com.callfire.api.client.api.campaigns.model.request.AddBatchRequest;
import com.callfire.api.client.api.common.model.ResourceId;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient callfireClient = new CallfireClient("api_login", "api_password");
        CallRecipient recipient1 = new CallRecipient();
        recipient1.setPhoneNumber("12135551122");
        CallRecipient recipient2 = new CallRecipient();
        recipient2.setPhoneNumber("12135553434");
        CallRecipient recipient3 = new CallRecipient();
        recipient3.setPhoneNumber("12135558090");
        Map<String,String> attrs = new HashMap<>();
        attrs.put("custom_external_id", "30005044");
        attrs.put("custom_property_1", "value1");
        recipient3.setAttributes(attrs);

        AddBatchRequest request = AddBatchRequest.create()
            .campaignId(11646003L)
            .name("contact batch for call broadcast")
            .scrubDuplicates(true)
            .recipients(Arrays.asList(recipient1, recipient2, recipient3))
            //or you can add contacts from particular contact list
            //.contactListId(70055003L)
            .build();
        ResourceId resourceId = callfireClient.callBroadcastsApi().addBatch(request);
    }
}
[-java] [+csharp]
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.CallsTexts.Model;
using CallfireApiClient.Api.Campaigns.Model;
using CallfireApiClient.Api.Campaigns.Model.Request;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var request1 = new AddBatchRequest
        {
            CampaignId = 11646003,
            Name = "contact batch for call broadcast",
            Recipients = new List<Recipient>
            {
                new CallRecipient {PhoneNumber = "12135551122"},
                new CallRecipient {PhoneNumber = "12135553434"},
                new CallRecipient
                {
                    PhoneNumber = "12135558090",
                    Attributes = new Dictionary<string, string>
                    {
                        {"custom_external_id", "30005044"},
                        {"custom_property_1", "value1"}
                    }
                }
            },
            //or you can add contacts from particular contact list
            //ContactListId = 70055003
            ScrubDuplicates = true
        };
        var resourceId = client.TextBroadcastsApi.AddBatch(request1);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.addCallBroadcastBatch({
      id: 11646003,
      body: {
        name: 'contact batch for call broadcast',
        recipients: [
          {phoneNumber: '12135551122'},
          {phoneNumber: '12135553434'},
          {
            phoneNumber: '12135558090',
            attributes: {
              custom_external_id: 30005044,
              custom_property_1: 'value1'
            }
          },
        ],
        // or you can add contacts from particular contact list
        // contactListId: 70055003,
        scrubDuplicates: true
      }
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
response = client.calls.addCallBroadcastBatch(
    id=11646003,
    body={
        'name': 'contact batch for call broadcast',
        'recipients': [
            {'phoneNumber': '12135551122'},
            {'phoneNumber': '12135553434'},
            {
                'phoneNumber': '12135558090',
                'attributes': {
                    'custom_external_id': 30005044,
                    'custom_property_1': 'value1'
                }
            }
        ],
        # or you can add contacts from particular contact list
        # contactListId: 70055003,
        'scrubDuplicates': True
    }
).result()

# see sample JSON response for this API
# on 'curl' samples tab
print(response)
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->addCallBroadcastBatch();
        $request->getOperationConfig()->setPathParameters(array("id" => 11646003));
        $body = '{
                    "name":"contact batch for call broadcast",
                    "recipients":
                    [
                        {
                            "phoneNumber":"12135551122"
                        },
                        {
                            "phoneNumber":"12135553434"
                        },
                        {
                            "phoneNumber":"12135558090",
                            "attributes":
                            {
                                "custom_external_id": 30005044,
                                "custom_property_1": "value1"
                            }
                        }
                    ],
                    # or you can add contacts from particular contact list
                    # contactListId: 70055003,
                    "scrubDuplicates": true
                 }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}
[-php] [[/code-container]]

Another method to add recipients to broadcast:

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
    [
        {
            "phoneNumber":"12135551122"
        },
        {
            "contactId":122460000043
        },
        {
            "phoneNumber":"12135558090",
            "attributes":
            {
                "custom_external_id": 30005044,
                "custom_property_1": "value1"
            }
        }
    ]' "https://api.callfire.com/v2/calls/broadcasts/11646003/recipients"
response:
{
  "items": [
    {
      "id": 13410,
      "fromNumber": "12135551189",
      "toNumber": "12135551100",
      "state": "READY",
      "campaignId": 14,
      "batchId": 12,
      "contact": {
        "id": 4096,
        "homePhone": "12135551100"
      },
      "inbound": false,
      "created": 1443383295000,
      "modified": 1443383295000,
      "agentCall": false
    },
    {
      "id": 13411,
      "fromNumber": "12135551189",
      "toNumber": "12135551101",
      "state": "READY",
      "campaignId": 14,
      "batchId": 12,
      "contact": {
        "id": 4097,
        "homePhone": "12135551101"
      },
      "inbound": false,
      "created": 1443383295000,
      "modified": 1443383295000,
      "agentCall": false
    }
  ]
}
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.callstexts.model.Call;
import com.callfire.api.client.api.campaigns.model.Recipient;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient callfireClient = new CallfireClient("api_login", "api_password");
        Recipient recipient1 = new Recipient();
        recipient1.setPhoneNumber("12135551122");
        Recipient recipient2 = new Recipient();
        recipient2.setContactId(122460000043L);
        Recipient recipient3 = new Recipient();
        recipient3.setPhoneNumber("12135558090");
        Map<String,String> attrs = new HashMap<>();
        attrs.put("custom_external_id", "30005044");
        attrs.put("custom_property_1", "value1");
        recipient3.setAttributes(attrs);
        List<Recipient> recipients = Arrays.asList(recipient1, recipient2, recipient3);
        List<Call> calls = callfireClient.callBroadcastsApi().addRecipients(11646003L, recipients);
    }
}
[-java] [+csharp]
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.Campaigns.Model;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var calls = client.CallBroadcastsApi.AddRecipients(11646003, new List<Recipient>
        {
            new Recipient {PhoneNumber = "12135551122"},
            new Recipient {ContactId = 122460000043},
            new Recipient {PhoneNumber = "12135558090",
                           Attributes = new Dictionary<string, string>
                          {
                              {"custom_external_id", "30005044"},
                              {"custom_property_1", "value1"}
                          }
            }
        });
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.addCallBroadcastRecipients({
      id: 11646003,
      body: [
        {phoneNumber: '12135551122'},
        // use an existing contact in CallFire account
        {contactId: 122460000043},
        {
          phoneNumber: '12135558090',
          attributes: {
            custom_external_id: 30005044,
            custom_property_1: 'value1'
          }
        },
      ]
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
response = client.calls.addCallBroadcastRecipients(
    id=11646003,
    body=[
        {'phoneNumber': '12135551122'},
        # use an existing contact in CallFire account
        {'contactId': 122460000043},
        {
            'phoneNumber': '12135558090',
            'attributes': {
                'custom_external_id': 30005044,
                'custom_property_1': 'value1'
            }
        }
    ]
).result()

# see sample JSON response for this API
# on 'curl' samples tab
print(response)
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->addCallBroadcastRecipients();
        $request->getOperationConfig()->setPathParameters(array("id" => 11646003));
        $body = '[
                    {
                        "phoneNumber":"12135551122"
                    },
                    {
                        "contactId":122460000043
                    },
                    {
                        "phoneNumber":"12135558090",
                        "attributes":
                        {
                            "custom_external_id": 30005044,
                            "custom_property_1": "value1"
                        }
                    }
                 ]';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

Default Broadcast

Each action (call or text, inbound or outbound) is always part of broadcast, and each broadcast has its own configuration, for instance:

Important. By default Send Texts and Send Calls operations send out an action through default broadcast. Each account has default Voice, IVR, and Text broadcasts which are used in case you don't specify a campaignId parameter in Send Calls/Texts request. In case you need to send a voice or text message through a campaign with a specific configuration, just set the campaignId parameter.

Start / Stop a Broadcast

CallFire provides the ability to start and stop broadcasts at any time. This applies to all types of broadcasts: Voice, IVR, and Text. Also, you can schedule a broadcast to start in the future. The following examples show how to start a Call Broadcast, and the same operations are available for Text broadcasts as well.

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST "https://api.callfire.com/v2/calls/broadcasts/11646003/start"
response:
200 OK - No Response
[-curl] [+java]
import com.callfire.api.client.CallfireClient;

class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");
        client.callBroadcastsApi().start(11646003L);
    }
}
[-java] [+csharp]
using CallfireApiClient;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        client.CallBroadcastsApi.Start(11646003);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.startVoiceBroadcast({id: 11646003})
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
client.calls.startVoiceBroadcast(id=11646003).result()
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->startVoiceBroadcast();
        $request->getOperationConfig()->setPathParameters(array("id" => 11646003));
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

The same API method is available to start Text Broadcasts.

Schedule a Broadcast

CallFire allows you to schedule a broadcast upon creation or after it was created. Broadcasts support multiple schedule objects per single instance, so you can make a long-term schedule to start-stop your campaigns. You may specify a particular timezone for your schedules, and turn on and off that schedule.

To remove broadcast schedules invoke an Update API on a particular broadcast with an empty array of schedules e.g. "schedules":[]

The following code examples show how to add schedules to an existing call broadcast with ID 10030003 so that it will start twice in December: one the one hand, between 10:00 and 18:00 between the 1st through 10th, and on the other, between 10:00 and 18:00 on weekends between the 20th and 30th.

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X PUT -d '
{
  "schedules": [
    {
      "startTimeOfDay": {
        "hour": 10,
        "minute": 0,
        "second": 0
      },
      "stopTimeOfDay": {
        "hour": 18,
        "minute": 0,
        "second": 0
      },
      "daysOfWeek": [
        "SATURDAY",
        "SUNDAY"
      ],
      "timeZone": "America/New_York",
      "startDate": {
        "year": 2016,
        "month": 12,
        "day": 1
      },
      "stopDate": {
        "year": 2016,
        "month": 12,
        "day": 10
      }
    },
    {
      "startTimeOfDay": {
        "hour": 10,
        "minute": 0,
        "second": 0
      },
      "stopTimeOfDay": {
        "hour": 18,
        "minute": 0,
        "second": 0
      },
      "daysOfWeek": [
        "SATURDAY",
        "SUNDAY"
      ],
      "timeZone": "America/New_York",
      "startDate": {
        "year": 2016,
        "month": 12,
        "day": 20
      },
      "stopDate": {
        "year": 2016,
        "month": 12,
        "day": 30
      }
    }
  ]
}' "https://api.callfire.com/v2/calls/broadcasts/11646003"
response:
200 OK - No Response
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.campaigns.model.CallBroadcast;
import com.callfire.api.client.api.campaigns.model.DayOfWeek;
import com.callfire.api.client.api.campaigns.model.LocalDate;
import com.callfire.api.client.api.campaigns.model.LocalTime;
import com.callfire.api.client.api.campaigns.model.Schedule;
import com.callfire.api.client.api.common.model.LocalDate;
import com.callfire.api.client.api.common.model.LocalTime;

import java.time.DayOfWeek;
import java.util.Arrays;
import java.util.HashSet;

/**
 * An Example how update broadcast and set multiple schedule to
 * start-stop campaign twice in December
 */
class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");

        CallBroadcast broadcast = new CallBroadcast();
        // set id of an existing broadcast, you can use find() method to search
        //  for particular broadcast id
        broadcast.setId(11646003L);
        // schedule a campaign to run on Saturday and Sunday between 2016-12-01 10:00:00
        //  and 2016-12-10 18:00:00
        Schedule schedule1 = new Schedule();
        schedule1.setStartDate(new LocalDate(2016, 12, 1));
        schedule1.setStartTimeOfDay(new LocalTime(10, 0, 0));
        schedule1.setStopDate(new LocalDate(2016, 12, 10));
        schedule1.setStopTimeOfDay(new LocalTime(18, 0, 0));
        schedule1.setDaysOfWeek(new HashSet<>(Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY)));
        // set optional time zone, if leave empty account's timezone will be used
        schedule1.setTimeZone("America/New_York");
        // add another schedule for campaign to start on Saturday and Sunday between 2016-12-20 10:00:00
        //  and 2016-12-30 18:00:00
        Schedule schedule2 = new Schedule();
        schedule2.setStartDate(new LocalDate(2016, 12, 20));
        schedule2.setStartTimeOfDay(new LocalTime(10, 0, 0));
        schedule2.setStopDate(new LocalDate(2016, 12, 30));
        schedule2.setStopTimeOfDay(new LocalTime(18, 0, 0));
        schedule2.setDaysOfWeek(new HashSet<>(Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY)));
        broadcast.setSchedules(Arrays.asList(schedule1, schedule2));

        // update broadcast
        client.callBroadcastsApi().update(broadcast);
    }
}
[-java] [+csharp]
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.Campaigns.Model;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var broadcast = new CallBroadcast
        {
            Id = 11646003,
            Schedules = new List<Schedule>
            {
                // schedule a campaign to run on Saturday and Sunday between 2016-12-01 10:00:00
                //  and 2016-12-10 18:00:00
                new Schedule
                {
                    StartDate = new LocalDate {Year = 2016, Month = 12, Day = 1},
                    StartTimeOfDay = new LocalTime {Hour = 10, Minute = 0, Second = 0},
                    StopDate = new LocalDate {Year = 2016, Month = 12, Day = 10},
                    StopTimeOfDay = new LocalTime {Hour = 18, Minute = 0, Second = 0},
                    // set weekly schedule
                    DaysOfWeek = new HashSet<DayOfWeek> {DayOfWeek.SATURDAY, DayOfWeek.SUNDAY},
                    // set optional time zone, if leave empty account's timezone will be used
                    TimeZone = "America/New_York"
                },
                // add another schedule for campaign to start on Saturday and Sunday between 2016-12-20 10:00:00
                //  and 2016-12-30 18:00:00
                new Schedule
                {
                    StartDate = new LocalDate {Year = 2016, Month = 12, Day = 20},
                    StartTimeOfDay = new LocalTime {Hour = 10, Minute = 0, Second = 0},
                    StopDate = new LocalDate {Year = 2016, Month = 12, Day = 30},
                    StopTimeOfDay = new LocalTime {Hour = 18, Minute = 0, Second = 0},
                    // set weekly schedule
                    DaysOfWeek = new HashSet<DayOfWeek> {DayOfWeek.SATURDAY, DayOfWeek.SUNDAY}
                }
            }
        };

        // update broadcast with new schedules
        client.CallBroadcastsApi.Update(broadcast);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.updateCallBroadcast({
      id: 11646003,
      body: {
        schedules: [
          {
            startTimeOfDay: {
              hour: 10,
              minute: 0,
              second: 0
            },
            stopTimeOfDay: {
              hour: 18,
              minute: 0,
              second: 0
            },
            daysOfWeek: [
              'SATURDAY',
              'SUNDAY'
            ],
            timeZone: 'America/New_York',
            startDate: {
              year: 2016,
              month: 12,
              day: 1
            },
            stopDate: {
              year: 2016,
              month: 12,
              day: 10
            }
          },
          {
            startTimeOfDay: {
              hour: 10,
              minute: 0,
              second: 0
            },
            stopTimeOfDay: {
              hour: 18,
              minute: 0,
              second: 0
            },
            daysOfWeek: [
              'SATURDAY',
              'SUNDAY'
            ],
            timeZone: 'America/New_York',
            startDate: {
              year: 2016,
              month: 12,
              day: 20
            },
            stopDate: {
              year: 2016,
              month: 12,
              day: 30
            }
          },
        ]
      }
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
client.calls.updateCallBroadcast(
    id=11646003,
    body={
        'schedules': [
            {
                'startTimeOfDay': {
                    'hour': 10,
                    'minute': 0,
                    'second': 0
                },
                'stopTimeOfDay': {
                    'hour': 18,
                    'minute': 0,
                    'second': 0
                },
                'daysOfWeek': [
                    'SATURDAY',
                    'SUNDAY'
                ],
                'timeZone': 'America/New_York',
                'startDate': {
                    'year': 2016,
                    'month': 12,
                    'day': 1
                },
                'stopDate': {
                    'year': 2016,
                    'month': 12,
                    'day': 10
                }
            },
            {
                'startTimeOfDay': {
                    'hour': 10,
                    'minute': 0,
                    'second': 0
                },
                'stopTimeOfDay': {
                    'hour': 18,
                    'minute': 0,
                    'second': 0
                },
                'daysOfWeek': [
                    'SATURDAY',
                    'SUNDAY'
                ],
                'timeZone': 'America/New_York',
                'startDate': {
                    'year': 2016,
                    'month': 12,
                    'day': 20
                },
                'stopDate': {
                    'year': 2016,
                    'month': 12,
                    'day': 30
                }
            },
        ]
    }
).result()
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->updateCallBroadcast();
        $request->getOperationConfig()->setPathParameters(array("id" => 11646003));
        $body = '{
                    "schedules":
                    [
                        {
                            "startTimeOfDay":
                            {
                                "hour": 10,
                                "minute": 0,
                                "second": 0
                            },
                            "stopTimeOfDay":
                            {
                                "hour": 18,
                                "minute": 0,
                                "second": 0
                            },
                            "daysOfWeek":
                            [
                                "SATURDAY",
                                "SUNDAY"
                            ],
                            "timeZone": "America/New_York",
                            "startDate":
                            {
                                "year": 2016,
                                "month": 12,
                                "day": 1
                            },
                            "stopDate":
                            {
                                "year": 2016,
                                "month": 12,
                                "day": 10
                            }
                        },
                        {
                            "startTimeOfDay":
                            {
                                "hour": 10,
                                "minute": 0,
                                "second": 0
                            },
                            "stopTimeOfDay":
                            {
                                "hour": 18,
                                "minute": 0,
                                "second": 0
                            },
                            "daysOfWeek":
                            [
                                "SATURDAY",
                                "SUNDAY"
                            ],
                            "timeZone": "America/New_York",
                            "startDate":
                            {
                                "year": 2016,
                                "month": 12,
                                "day": 20
                            },
                            "stopDate":
                            {
                                "year": 2016,
                                "month": 12,
                                "day": 30
                            }
                        }
                    ]
                }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

How to Get Call/Text Statistics from a Broadcast

You can fetch a broadcast's statistics like the number of total actions (Call/Text) made by the platform, the number of remaining actions, the number of errors, the number of calls by disposition, the calls duration, billed amount, etc. The following samples show how to fetch statistics for a Call Broadcast:

[[code-container]] [+curl] request:

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X GET "https://api.callfire.com/v2/calls/broadcasts/11646003/stats?begin=1473781817000&end=1473781817000&fields=totalOutboundCount,billedAmount,callsAttempted"
response:
{
  "totalOutboundCount": 2,
  "remainingOutboundCount": 0,
  "billedAmount": 1.6667,
  "callsAttempted": 1,
  "callsPlaced": 1,
  "callsDuration": 1,
  "billedDuration": 60,
  "responseRatePercent": 100,
  "callsRemaining": 1,
  "callsAwaitingRedial": 0,
  "callsLiveAnswer": 1,
  "totalCount": 2,
  "answeringMachineCount": 0,
  "busyCount": 0,
  "dialedCount": 1,
  "doNotCallCount": 1,
  "errorCount": 0,
  "liveCount": 1,
  "miscCount": 0,
  "noAnswerCount": 0,
  "transferCount": 0
}
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.campaigns.model.CallBroadcastStats;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");
        Date end = new GregorianCalendar(2016, Calendar.SEPTEMBER, 15, 50, 17, 0).getTime();
        Date begin = new GregorianCalendar(2016, Calendar.SEPTEMBER, 15, 50, 17, 0).getTime();
        // limit returned fields if needed
        String fields = "totalOutboundCount,billedAmount,callsAttempted";
        CallBroadcastStats stats = client.callBroadcastsApi().getStats(11646003L, fields, begin, end);
    }
}
[-java] [+csharp]
using System;
using CallfireApiClient;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        // limit returned fields if needed
        var fields = "totalOutboundCount,billedAmount,callsAttempted";
        var begin = new DateTime(2016, 9, 13, 15, 50, 17);
        var end = new DateTime(2016, 9, 13, 15, 50, 17);
        var stats = client.CallBroadcastsApi.GetStats(11646003, fields, begin, end);
    }
}
[-csharp] [+js]
'strict'

const CallfireClient = require('callfire-api-client-js');
const client = new CallfireClient('api-login', 'api-password');

client.ready(() => {
    client.calls.getCallBroadcastStats({
      id: 11646003,
      // filter by time interval
      begin: 1473781817000,
      // filter by time interval
      end: 1473781817000,
      // return only specific fields
      fields: 'totalOutboundCount,billedAmount,callsAttempted'
    })
      .then((response) => {
        console.log(response.obj);
      })
      .catch((err) => {
        console.log('request error ' + err.data);
      });
  },
  (clientError) => {
    console.log('client error ' + clientError);
  }
);
[-js] [+python]
from callfire.client import CallfireClient

client = CallfireClient('api-login', 'api-password')
response = client.calls.getCallBroadcastStats(
    id=11646003,
    # filter by time interval
    begin=1473781817000,
    # filter by time interval
    end=1473781817000,
    # return only specific fields
    fields='totalOutboundCount,billedAmount,callsAttempted'
).result()

# see sample JSON response for this API
# on 'curl' samples tab
print(response)
[-python] [+php]
<?php

class ApiClientSample {

    public static function main() {
        $client = \CallFire\Api\DocumentedClient::createClient("login", "password");
        $request = $client->getCallBroadcastStats();
        $request->getOperationConfig()->setPathParameters(array("id" => 11646003));
        $request->getOperationConfig()->setQueryParameters(array("begin" => 1473781817000,
                                                                 "end" => 1473781817000,
                                                                 "fields" => "totalOutboundCount,billedAmount,callsAttempted"));
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

ApiClientSample::main();
[-php] [[/code-container]]

Check API method reference for detailed information about request type, parameters, responses.

Receiving Notifications from CallFire

CallFire provides a notification service called webhooks. You can always create a webhook to start receiving notifications from CallFire based on some event, for instance when a broadcast is started or finished, or a call is finished. Information on how to create and configure a webhook can be found at Webhooks Guide page.

API Use Cases

The following guides show how to build an integration with CallFire based on a particular use-case. Each use-case shows how to use Broadcasts API