Political Campaign Conducting a Poll

CallFire allows you to conduct different types of polls using phone calls. Our service provides an IVR technology which helps you interact with your clients, ask questions, get answers, record phone calls, etc. Let's see how we can set up a simple survey.

Story

An independent organization conducted a political poll. The results show that there may be a low voter turnout in Colorado, so they intend to increase voter turnout by calling voters to learn what issues matter to them this election cycle. But how can you reach that many people in so short a time? Tom, a volunteer coordinator, proposes to use an IVR. Tom needs to prepare an IVR dialplan, list of recipients, and then create an IVR broadcast. This article shows how to start the broadcast and gather the responses.

IVR dialplan

The term IVR stands for Interactive Voice Response. An IVR allows you to ask questions through pre-recorded or text-to-speech prompts, and receive responses via phone key presses. The CallFire IVR setup uses an XML-based definition. The following IVR XML dialplan first detects if the call is answered by a person, and then asks recipients a few questions. You can also define your questions based on a recipient's previous answers. The following is an example of an IVR political poll:

<dialplan name="Root">
    <amd>
        <live>
            <goto name="goto_Live">Live</goto>
        </live>
        <machine>
            <goto name="goto_Machine">Machine</goto>
        </machine>
    </amd>
    <menu maxDigits="1" timeout="3500" name="Live">
        <play type="tts" voice="female1" name="play_Live">Hello. 
        This is a call for a short political poll for the upcoming election. 
        Will you vote in the upcoming election? 
        Press 1 for Yes, or 2 for No..</play>
        <keypress pressed="1" name="kp_Vote">
            <stash varname="Vote" name="stash_Will_Vote">Yes</stash>
            <goto>Question_01</goto>
        </keypress>
        <keypress pressed="2" name="kp_Will_Not_Vote">
            <stash varname="Vote" name="stash_Will_Not_Vote">No</stash>
            <play type="tts" voice="female1" name="play_Goodbye_1">Thank you for your time. Goodbye.</play>
            <goto>Hangup</goto>
        </keypress>
        <keypress pressed="default" name="incorrect_Selection">
            <play type="tts" voice="female1" name="play_Inorrect_Selection">That is not a valid selection. Please try again.</play>
            <goto name="replay_Live">Live</goto>
        </keypress>
    </menu>
    <menu maxDigits="1" timeout="3500" name="Question_01">
        <play type="tts" voice="female1" name="play_Question_01">Who will you vote for in the upcoming elections? 
        Press 1 for Donkeys. 
        Press 2 for Elephants. 
        Press 3 for Greenies, 
        press 4 for Undecided, 
        or, 
        press 5 for Decline to state.</play>
        <keypress pressed="1-5" name="Selection_Question_01">
            <stash varname="Candidate" name="stash_Candidate">${call.lastinput}</stash>
            <goto name="goto_Goodbye">Goodbye</goto>
        </keypress>
        <keypress pressed="default" name="incorrect_Selection_Question_01">
            <play type="tts" voice="female1" name="play_Inorrect_Selection_Question_01">
                That is not a valid selection. Please try again.
            </play>
            <goto name="replay_Question_01">Question_01</goto>
        </keypress>
    </menu>
    <play type="tts" voice="female1" name="Goodbye">
        Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye.
    </play>
    <goto name="Goodbye_Hangup">Hangup</goto>
    <play type="tts" voice="female1" name="Machine">
        Hello. This is a call for a political poll for the upcoming election. 
        Sorry we missed you. We will try you again later, or, 
         if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play>
    <hangup name="Hangup"/>
</dialplan>

This flowchart shows how the IVR dialplan is executed:

Political survey flowchart

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

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

Create an IVR Broadcast

IVR Broadcasts send an IVR call to each recipient added to the broadcast. Then you can query the broadcast statistics, like the number of live answers, the billed duration, the number of failed calls, responses, and other information:

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

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
{
  "name": "Political Campaign",
  "fromNumber": "12135551189",
  "labels": [
    "political-poll",
    "id-10002"
  ],
  "localTimeRestriction": {
    "beginHour": 9,
    "beginMinute": 0,
    "endHour": 18,
    "endMinute": 0
  },
  "retryConfig": {
    "maxAttempts": 2,
    "minutesBetweenAttempts": 5,
    "retryResults": [
      "BUSY",
      "NO_ANS"
    ],
    "retryPhoneTypes": [
      "MOBILE_PHONE",
      "WORK_PHONE"
    ]
  },
  "dialplanXml": "<dialplan name=\"Root\"> <amd> <live> <goto name=\"goto_Live\">Live</goto> </live> <machine> <goto name=\"goto_Machine\">Machine</goto> </machine> </amd> <menu maxDigits=\"1\" timeout=\"3500\" name=\"Live\"> <play type=\"tts\" voice=\"female1\" name=\"play_Live\">Hello. This is a call for a short political poll for the upcoming election. Will you vote in the upcoming election? Press 1 for Yes, or 2 for No..</play> <keypress pressed=\"1\" name=\"kp_Vote\"> <stash varname=\"Vote\" name=\"stash_Will_Vote\">Yes</stash> <goto>Question_01</goto> </keypress> <keypress pressed=\"2\" name=\"kp_Will_Not_Vote\"> <stash varname=\"Vote\" name=\"stash_Will_Not_Vote\">No</stash> <play type=\"tts\" voice=\"female1\" name=\"play_Goodbye_1\">Thank you for your time. Goodbye.</play> <goto>Hangup</goto> </keypress> <keypress pressed=\"default\" name=\"incorrect_Selection\"> <play type=\"tts\" voice=\"female1\" name=\"play_Inorrect_Selection\">That is not a valid selection. Please try again.</play> <goto name=\"replay_Live\">Live</goto> </keypress> </menu> <menu maxDigits=\"1\" timeout=\"3500\" name=\"Question_01\"> <play type=\"tts\" voice=\"female1\" name=\"play_Question_01\">Who will you vote for in the upcoming elections? Press 1 for Donkeys. Press 2 for Elephants. Press 3 for Greenies, press 4 for Undecided, or, press 5 for Decline to state.</play> <keypress pressed=\"1-5\" name=\"Selection_Question_01\"> <stash varname=\"Candidate\" name=\"stash_Candidate\">${call.lastinput}</stash> <goto name=\"goto_Goodbye\">Goodbye</goto> </keypress> <keypress pressed=\"default\" name=\"incorrect_Selection_Question_01\"> <play type=\"tts\" voice=\"female1\" name=\"play_Inorrect_Selection_Question_01\"> That is not a valid selection. Please try again. </play> <goto name=\"replay_Question_01\">Question_01</goto> </keypress> </menu> <play type=\"tts\" voice=\"female1\" name=\"Goodbye\"> Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye. </play> <goto name=\"Goodbye_Hangup\">Hangup</goto> <play type=\"tts\" voice=\"female1\" name=\"Machine\"> Hello. This is a call for a political poll for the upcoming election. Sorry we missed you. We will try you again later, or, if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play> <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.common.model.ResourceId;

import java.util.Arrays;

class ApiClientSample {

    public static void main(String[] args) {
        CallfireClient client = new CallfireClient("api_login", "api_password");
        CallBroadcast broadcast = new CallBroadcast();
        broadcast.setName("Political Campaign");
        // attach custom labels if needed
        broadcast.setLabels(Arrays.asList("political-poll", "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);

        // 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\">                                                                                                 "
                + "      <amd>                                                                                                          "
                + "  <live>                                                                                                             "
                + "  <goto name=\"goto_Live\">Live</goto>                                                                               "
                + "      </live>                                                                                                        "
                + "  <machine>                                                                                                          "
                + "  <goto name=\"goto_Machine\">Machine</goto>                                                                         "
                + "      </machine>                                                                                                     "
                + "  </amd>                                                                                                             "
                + "  <menu maxDigits=\"1\" timeout=\"3500\" name=\"Live\">                                                              "
                + "      <play type=\"tts\" voice=\"female1\" name=\"play_Live\">Hello.                                                 "
                + "  This is a call for a short political poll for the upcoming election.                                               "
                + "      Will you vote in the upcoming election?                                                                        "
                + "  Press 1 for Yes, or 2 for No..</play>                                                                              "
                + "  <keypress pressed=\"1\" name=\"kp_Vote\">                                                                          "
                + "      <stash varname=\"Vote\" name=\"stash_Will_Vote\">Yes</stash>                                                   "
                + "      <goto>Question_01</goto>                                                                                       "
                + "  </keypress>                                                                                                        "
                + "  <keypress pressed=\"2\" name=\"kp_Will_Not_Vote\">                                                                 "
                + "      <stash varname=\"Vote\" name=\"stash_Will_Not_Vote\">No</stash>                                                "
                + "      <play type=\"tts\" voice=\"female1\" name=\"play_Goodbye_1\">Thank you for your time. Goodbye.</play>          "
                + "      <goto>Hangup</goto>                                                                                            "
                + "  </keypress>                                                                                                        "
                + "  <keypress pressed=\"default\" name=\"incorrect_Selection\">                                                        "
                + "      <play type=\"tts\" voice=\"female1\" name=\"play_Inorrect_Selection\">That is not a valid selection. Please try again.</play>"
                + "      <goto name=\"replay_Live\">Live</goto>                                                                         "
                + "      </keypress>                                                                                                    "
                + "  </menu>                                                                                                            "
                + "  <menu maxDigits=\"1\" timeout=\"3500\" name=\"Question_01\">                                                       "
                + "      <play type=\"tts\" voice=\"female1\" name=\"play_Question_01\">Who will you vote for in the upcoming elections?"
                + "  Press 1 for Donkeys.                                                                                               "
                + "      Press 2 for Elephants.                                                                                         "
                + "      Press 3 for Greenies,                                                                                          "
                + "      press 4 for Undecided,                                                                                         "
                + "      or,                                                                                                            "
                + "      press 5 for Decline to state.</play>                                                                           "
                + "  <keypress pressed=\"1-5\" name=\"Selection_Question_01\">                                                          "
                + "      <stash varname=\"Candidate\" name=\"stash_Candidate\">${call.lastinput}</stash>                                "
                + "      <goto name=\"goto_Goodbye\">Goodbye</goto>                                                                     "
                + "      </keypress>                                                                                                    "
                + "  <keypress pressed=\"default\" name=\"incorrect_Selection_Question_01\">                                            "
                + "      <play type=\"tts\" voice=\"female1\" name=\"play_Inorrect_Selection_Question_01\">                             "
                + "  That is not a valid selection. Please try again.                                                                   "
                + "      </play>                                                                                                        "
                + "  <goto name=\"replay_Question_01\">Question_01</goto>                                                               "
                + "      </keypress>                                                                                                    "
                + "  </menu>                                                                                                            "
                + "  <play type=\"tts\" voice=\"female1\" name=\"Goodbye\">                                                             "
                + "  Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye. "
                + "      </play>                                                                                                        "
                + "  <goto name=\"Goodbye_Hangup\">Hangup</goto>                                                                        "
                + "      <play type=\"tts\" voice=\"female1\" name=\"Machine\">                                                         "
                + "  Hello. This is a call for a political poll for the upcoming election.                                              "
                + "      Sorry we missed you. We will try you again later, or,                                                          "
                + "  if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play>                      "
                + "  <hangup name=\"Hangup\"/>                                                                                          "
                + "      </dialplan>                                                                                                    "
                + "                                                                                                                     ";
    }
}
[-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
        {
            Name = "Political Campaign",
            // set validated Caller ID number.
            FromNumber = "12135551189",
            // attach custom labels if needed
            Labels = new List<string> {"political-poll", "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
            },
            // 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"">
                    <amd>
                        <live>
                            <goto name=""goto_Live"">Live</goto>
                        </live>
                        <machine>
                            <goto name=""goto_Machine"">Machine</goto>
                        </machine>
                    </amd>
                    <menu maxDigits=""1"" timeout=""3500"" name=""Live"">
                        <play type=""tts"" voice=""female1"" name=""play_Live"">Hello.
                        This is a call for a short political poll for the upcoming election.
                        Will you vote in the upcoming election?
                        Press 1 for Yes, or 2 for No..</play>
                        <keypress pressed=""1"" name=""kp_Vote"">
                            <stash varname=""Vote"" name=""stash_Will_Vote"">Yes</stash>
                            <goto>Question_01</goto>
                        </keypress>
                        <keypress pressed=""2"" name=""kp_Will_Not_Vote"">
                            <stash varname=""Vote"" name=""stash_Will_Not_Vote"">No</stash>
                            <play type=""tts"" voice=""female1"" name=""play_Goodbye_1"">Thank you for your time. Goodbye.</play>
                            <goto>Hangup</goto>
                        </keypress>
                        <keypress pressed=""default"" name=""incorrect_Selection"">
                            <play type=""tts"" voice=""female1"" name=""play_Inorrect_Selection"">That is not a valid selection. Please try again.</play>
                            <goto name=""replay_Live"">Live</goto>
                        </keypress>
                    </menu>
                    <menu maxDigits=""1"" timeout=""3500"" name=""Question_01"">
                        <play type=""tts"" voice=""female1"" name=""play_Question_01"">Who will you vote for in the upcoming elections?
                        Press 1 for Donkeys.
                        Press 2 for Elephants.
                        Press 3 for Greenies,
                        press 4 for Undecided,
                        or,
                        press 5 for Decline to state.</play>
                        <keypress pressed=""1-5"" name=""Selection_Question_01"">
                            <stash varname=""Candidate"" name=""stash_Candidate"">${call.lastinput}</stash>
                            <goto name=""goto_Goodbye"">Goodbye</goto>
                        </keypress>
                        <keypress pressed=""default"" name=""incorrect_Selection_Question_01"">
                            <play type=""tts"" voice=""female1"" name=""play_Inorrect_Selection_Question_01"">
                                That is not a valid selection. Please try again.
                            </play>
                            <goto name=""replay_Question_01"">Question_01</goto>
                        </keypress>
                    </menu>
                    <play type=""tts"" voice=""female1"" name=""Goodbye"">
                        Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye.
                    </play>
                    <goto name=""Goodbye_Hangup"">Hangup</goto>
                    <play type=""tts"" voice=""female1"" name=""Machine"">
                        Hello. This is a call for a political poll for the upcoming election.
                        Sorry we missed you. We will try you again later, or,
                         if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play>
                    <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({
      // set start parameter to run broadcast immediately
      // start: true,
      body: {
        name: 'Political Campaign',
        fromNumber: '12135551189',
        labels: [
          'political-poll',
          'id-10002'
        ],
        localTimeRestriction: {
          beginHour: 9,
          beginMinute: 0,
          endHour: 18,
          endMinute: 0
        },
        retryConfig: {
          maxAttempts: 2,
          minutesBetweenAttempts: 5,
          retryResults: [
            'BUSY',
            'NO_ANS'
          ],
          retryPhoneTypes: [
            'MOBILE_PHONE',
            'WORK_PHONE'
          ]
        },
        dialplanXml: '<dialplan name="Root"> <amd> <live> <goto name="goto_Live">Live</goto> </live> <machine> <goto name="goto_Machine">Machine</goto> </machine> </amd> <menu maxDigits="1" timeout="3500" name="Live"> <play type="tts" voice="female1" name="play_Live">Hello. This is a call for a short political poll for the upcoming election. Will you vote in the upcoming election? Press 1 for Yes, or 2 for No..</play> <keypress pressed="1" name="kp_Vote"> <stash varname="Vote" name="stash_Will_Vote">Yes</stash> <goto>Question_01</goto> </keypress> <keypress pressed="2" name="kp_Will_Not_Vote"> <stash varname="Vote" name="stash_Will_Not_Vote">No</stash> <play type="tts" voice="female1" name="play_Goodbye_1">Thank you for your time. Goodbye.</play> <goto>Hangup</goto> </keypress> <keypress pressed="default" name="incorrect_Selection"> <play type="tts" voice="female1" name="play_Inorrect_Selection">That is not a valid selection. Please try again.</play> <goto name="replay_Live">Live</goto> </keypress> </menu> <menu maxDigits="1" timeout="3500" name="Question_01"> <play type="tts" voice="female1" name="play_Question_01">Who will you vote for in the upcoming elections? Press 1 for Donkeys. Press 2 for Elephants. Press 3 for Greenies, press 4 for Undecided, or, press 5 for Decline to state.</play> <keypress pressed="1-5" name="Selection_Question_01"> <stash varname="Candidate" name="stash_Candidate">${call.lastinput}</stash> <goto name="goto_Goodbye">Goodbye</goto> </keypress> <keypress pressed="default" name="incorrect_Selection_Question_01"> <play type="tts" voice="female1" name="play_Inorrect_Selection_Question_01"> That is not a valid selection. Please try again. </play> <goto name="replay_Question_01">Question_01</goto> </keypress> </menu> <play type="tts" voice="female1" name="Goodbye"> Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye. </play> <goto name="Goodbye_Hangup">Hangup</goto> <play type="tts" voice="female1" name="Machine"> Hello. This is a call for a political poll for the upcoming election. Sorry we missed you. We will try you again later, or, if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play> <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(
    # set start parameter to run broadcast immediately
    # start: true,
    body={
        'name': 'Political Campaign',
        'fromNumber': '12135551189',
        'labels': [
            'political-poll',
            'id-10002'
        ],
        'localTimeRestriction': {
            'beginHour': 9,
            'beginMinute': 0,
            'endHour': 18,
            'endMinute': 0
        },
        'retryConfig': {
            'maxAttempts': 2,
            'minutesBetweenAttempts': 5,
            'retryResults': [
                'BUSY',
                'NO_ANS'
            ],
            'retryPhoneTypes': [
                'MOBILE_PHONE',
                'WORK_PHONE'
            ]
        },
        'dialplanXml': '<dialplan name="Root"> <amd> <live> <goto name="goto_Live">Live</goto> </live> <machine> <goto name="goto_Machine">Machine</goto> </machine> </amd> <menu maxDigits="1" timeout="3500" name="Live"> <play type="tts" voice="female1" name="play_Live">Hello. This is a call for a short political poll for the upcoming election. Will you vote in the upcoming election? Press 1 for Yes, or 2 for No..</play> <keypress pressed="1" name="kp_Vote"> <stash varname="Vote" name="stash_Will_Vote">Yes</stash> <goto>Question_01</goto> </keypress> <keypress pressed="2" name="kp_Will_Not_Vote"> <stash varname="Vote" name="stash_Will_Not_Vote">No</stash> <play type="tts" voice="female1" name="play_Goodbye_1">Thank you for your time. Goodbye.</play> <goto>Hangup</goto> </keypress> <keypress pressed="default" name="incorrect_Selection"> <play type="tts" voice="female1" name="play_Inorrect_Selection">That is not a valid selection. Please try again.</play> <goto name="replay_Live">Live</goto> </keypress> </menu> <menu maxDigits="1" timeout="3500" name="Question_01"> <play type="tts" voice="female1" name="play_Question_01">Who will you vote for in the upcoming elections? Press 1 for Donkeys. Press 2 for Elephants. Press 3 for Greenies, press 4 for Undecided, or, press 5 for Decline to state.</play> <keypress pressed="1-5" name="Selection_Question_01"> <stash varname="Candidate" name="stash_Candidate">${call.lastinput}</stash> <goto name="goto_Goodbye">Goodbye</goto> </keypress> <keypress pressed="default" name="incorrect_Selection_Question_01"> <play type="tts" voice="female1" name="play_Inorrect_Selection_Question_01"> That is not a valid selection. Please try again. </play> <goto name="replay_Question_01">Question_01</goto> </keypress> </menu> <play type="tts" voice="female1" name="Goodbye"> Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye. </play> <goto name="Goodbye_Hangup">Hangup</goto> <play type="tts" voice="female1" name="Machine"> Hello. This is a call for a political poll for the upcoming election. Sorry we missed you. We will try you again later, or, if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play> <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": "Political Campaign",
                    "fromNumber": "12135551189",
                    "labels":
                    [
                        "political-poll",
                        "id-10002"
                    ],
                    "localTimeRestriction":
                    {
                        "beginHour": 9,
                        "beginMinute": 0,
                        "endHour": 18,
                        "endMinute": 0
                    },
                    "retryConfig":
                    {
                        "maxAttempts": 2,
                        "minutesBetweenAttempts": 5,
                        "retryResults":
                        [
                            "BUSY",
                            "NO_ANS"
                        ],
                        "retryPhoneTypes":
                        [
                            "MOBILE_PHONE",
                            "WORK_PHONE"
                        ]
                    },
                    "dialplanXml": "<dialplan name=\"Root\"> <amd> <live> <goto name=\"goto_Live\">Live</goto> </live> <machine> <goto name=\"goto_Machine\">Machine</goto> </machine> </amd> <menu maxDigits=\"1\" timeout=\"3500\" name=\"Live\"> <play type=\"tts\" voice=\"female1\" name=\"play_Live\">Hello. This is a call for a short political poll for the upcoming election. Will you vote in the upcoming election? Press 1 for Yes, or 2 for No..</play> <keypress pressed=\"1\" name=\"kp_Vote\"> <stash varname=\"Vote\" name=\"stash_Will_Vote\">Yes</stash> <goto>Question_01</goto> </keypress> <keypress pressed=\"2\" name=\"kp_Will_Not_Vote\"> <stash varname=\"Vote\" name=\"stash_Will_Not_Vote\">No</stash> <play type=\"tts\" voice=\"female1\" name=\"play_Goodbye_1\">Thank you for your time. Goodbye.</play> <goto>Hangup</goto> </keypress> <keypress pressed=\"default\" name=\"incorrect_Selection\"> <play type=\"tts\" voice=\"female1\" name=\"play_Inorrect_Selection\">That is not a valid selection. Please try again.</play> <goto name=\"replay_Live\">Live</goto> </keypress> </menu> <menu maxDigits=\"1\" timeout=\"3500\" name=\"Question_01\"> <play type=\"tts\" voice=\"female1\" name=\"play_Question_01\">Who will you vote for in the upcoming elections? Press 1 for Donkeys. Press 2 for Elephants. Press 3 for Greenies, press 4 for Undecided, or, press 5 for Decline to state.</play> <keypress pressed=\"1-5\" name=\"Selection_Question_01\"> <stash varname=\"Candidate\" name=\"stash_Candidate\">${call.lastinput}</stash> <goto name=\"goto_Goodbye\">Goodbye</goto> </keypress> <keypress pressed=\"default\" name=\"incorrect_Selection_Question_01\"> <play type=\"tts\" voice=\"female1\" name=\"play_Inorrect_Selection_Question_01\"> That is not a valid selection. Please try again. </play> <goto name=\"replay_Question_01\">Question_01</goto> </keypress> </menu> <play type=\"tts\" voice=\"female1\" name=\"Goodbye\"> Thank you for taking our poll. Please remember to vote in the upcoming election! Thank you for your time. Goodbye. </play> <goto name=\"Goodbye_Hangup\">Hangup</goto> <play type=\"tts\" voice=\"female1\" name=\"Machine\"> Hello. This is a call for a political poll for the upcoming election. Sorry we missed you. We will try you again later, or, if you would like to take this short poll, please call 8 5 5,5 5 5,5 5 5 5. Thank you.</play> <hangup name=\"Hangup\"/> </dialplan> "
                 }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

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

Check the Create Call Broadcast method for detailed information about request type, accepted parameters, and responses.

Add New Recipients to an IVR Broadcast

You can add only phone numbers to a broadcast, or you can add existing contacts (phone numbers, names, and other identifying informtaion). CallFire creates contacts on the fly from the provided 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:

Imagine you have uploaded a list of contacts into CallFire and received the contact list id. The following examples show how to use the Add Contact Batch API method to add a CallFire contact list to a broadcast:

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

#!/usr/bin/env bash

curl -u username:password -H "Content-Type:application/json" -X POST -d '
    {
        "name":"Contact Batch 1",
        "contactListId": 300555001,
        "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.campaigns.model.request.AddBatchRequest;
import com.callfire.api.client.api.common.model.ResourceId;

class ApiClientSample {
    public static void main(String[] args) {
        CallfireClient callfireClient = new CallfireClient("api_login", "api_password");
        AddBatchRequest request = AddBatchRequest.create()
            .campaignId(11646003L)
            .name("Contacts Batch 1")
            // scrub duplicate numbers if any
            .scrubDuplicates(true)
            // add all contacts from previously created contact list
            .contactListId(300555001L)
            .build();
        ResourceId resourceId = callfireClient.callBroadcastsApi().addBatch(request);
    }
}
[-java] [+csharp]
using CallfireApiClient;
using CallfireApiClient.Api.Campaigns.Model.Request;

public class ApiClientSample
{
    public static void Main(string[] args)
    {
        var client = new CallfireClient("api_login", "api_password");
        var request = new AddBatchRequest
        {
            // your existing campaign id, you can get it via find() operation
            CampaignId = 11646003,
            Name = "Contacts Batch 1",
            // id of contact list that you have added on previous step
            ContactListId = 300555001,
            ScrubDuplicates = true
        };
        var id = client.CallBroadcastsApi.AddBatch(request);
    }
}
[-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 1',
        contactListId: 300555001,
        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 1',
        'contactListId': 300555001,
        '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 1",
                    "contactListId": 300555001,
                    "scrubDuplicates": true
                 }';
        $request->getOperationConfig()->setBodyParameter($body);
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}

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

How to Start a Broadcast

Once you add new recipients to a broadcast, you can start it immediately or schedule it to run in the future. An example of how to start a broadcast:

[[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]]

To schedule a broadcast, you can add scheduling information upon broadcast creation, or invoke Update API on an existing broadcast with the schedule object set. Broadcasts support multiple schedule objects per single instance, so you can make a long-term schedule to start/stop your campaigns.

How to Pull User's Responses

CallFire provides two ways of retrieving a user's data:

Webhooks are a system of automated notifications indicating that an event has occurred in the CallFire system. They help you to build a bi-directional integration where your service receives HTTP POST notifications from our platform.

Check webhooks guide for more information about CallFire Webhooks.

The following examples show how to query outbound calls, and find a user's data in records.questionResponses array.

[[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?id=11646003&id=12646003&id=13776003&campaignId=449060003&batchId=447060003&fromNumber=12135551126&toNumber=12136666123&label=my label&states=READY,FINISHED,INVALID&results=LA&inboubd=true&intervalBegin=1473781817000&intervalEnd=1473781817000&offset=0&limit=10&fields=items(id,fromNumber,toNumber,modified,finalCallResult)"
response:
{
  "items": [
    {
      "id": 13395,
      "fromNumber": "12135551189",
      "toNumber": "12135551101",
      "state": "FINISHED",
      "campaignId": 10,
      "batchId": 6,
      "contact": {
        "id": 4097,
        "homePhone": "12135551101"
      },
      "labels": [
        "survey 1"
      ],
      "attributes": {
          "external_user_id":"45450007002",
          "external_route_id":"77770007002"
      },
      "inbound": false,
      "created": 1443373386000,
      "modified": 1443373412000,
      "finalCallResult": "LA",
      "records": [
        {
          "id": 10306,
          "billedAmount": 1.1667,
          "finishTime": 1443373425000,
          "callResult": "LA",
          "questionResponses":[  
           {  
             "question":"Do you have a dog",
             "response":"Yes"
           },
           {  
              "question":"What's your favorite movie",
              "response":"StarWars"
           }
          ]
        }
      ],
      "agentCall": false
    },
    {
      "id": 13394,
      "fromNumber": "12135551189",
      "toNumber": "12135551100",
      "state": "FINISHED",
      "campaignId": 10,
      "batchId": 6,
      "contact": {
        "id": 4096,
        "homePhone": "12135551100"
      },
      "inbound": false,
      "created": 1443373382000,
      "modified": 1443373412000,
      "finalCallResult": "CARRIER_ERROR",
      "records": [
        {
          "id": 10305,
          "billedAmount": 0,
          "finishTime": 1443373408000,
          "callResult": "CARRIER_ERROR"
        }
      ],
      "agentCall": false
    }
  ],
  "limit": 2,
  "offset": 0,
  "totalCount": 7160
}
[-curl] [+java]
import com.callfire.api.client.CallfireClient;
import com.callfire.api.client.api.callstexts.model.Call;
import com.callfire.api.client.api.callstexts.model.request.FindCallsRequest;
import com.callfire.api.client.api.common.model.Page;
import static com.callfire.api.client.api.callstexts.model.Action.State;
import static com.callfire.api.client.api.callstexts.model.Call.CallResult;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;

class ApiClientSample {
    public static void main(String[] args) throws ParseException {
        CallfireClient client = new CallfireClient("api_login", "api_password");
        // find all calls made through particular campaign, with exact toNumber and fromNumber
        FindCallsRequest request = FindCallsRequest.create()
            .id(Arrays.asList(11646003L, 12646003L, 13776003L))
            .campaignId(449060003L)
            .batchId(447060003L)
            .fromNumber("12135551126")
            .toNumber("12136666123")
            .label("my label")
            .states(Arrays.asList(State.READY, State.FINISHED, State.INVALID))
            .results(Arrays.asList(CallResult.LA))
            .inbound(false)
            .intervalBegin(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-09-13 15:50:17"))
            .intervalEnd(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-09-13 15:50:17"))
            .offset(0L)
            .limit(10L)
            .fields("items(id,fromNumber,toNumber,modified,finalCallResult)")
            .build();
        Page<Call> calls = client.callsApi().find(request);
        // check Call.records.questionResponses list for stored data
    }
}
[-java] [+csharp]
using System;
using System.Collections.Generic;
using CallfireApiClient;
using CallfireApiClient.Api.CallsTexts.Model;
using CallfireApiClient.Api.CallsTexts.Model.Request;
using CallfireApiClient.Api.Common.Model;

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

        var request = new FindCallsRequest
        {
            Id = new List<long> { 11646003, 12646003, 13776003 },
            CampaignId = 449060003,
            BatchId = 447060003,
            FromNumber = "12135551126",
            ToNumber  = "12136666123",
            Label = "my label",
            States = new List<StateType> { StateType.FINISHED, StateType.READY, StateType.INVALID },
            Results = new List<Call.CallResult> { Call.CallResult.LA },
            Inbound = true,
            IntervalBegin = new DateTime(2016, 9, 13, 15, 50, 17),
            IntervalEnd = new DateTime(2016, 9, 13, 15, 50, 17),
            Offset = 0,
            Limit = 10,
            Fields = "items(id,fromNumber,toNumber,modified,finalCallResult)"
        };
        Page<Call> calls = client.CallsApi.Find(request);
        // check Call.records.questionResponses for stored data
    }
}
[-csharp] [+js]
'strict'

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

client.ready(() => {
    client.calls.findCalls({
      // filter by call ids
      id: [
        11646003,
        12646003,
        13776003
      ],
      // specify  id of a campaign, queries for calls inside a particular campaign.
      // do not set to list calls of all campaigns or 0 for a default campaign
      campaignId: 449060003,
      // queries for calls which are used in the particular contact batch
      batchId: 447060003,
      // filter by fromNumber
      fromNumber: '12135551126',
      // filter by toNumber
      toNumber: '12136666123',
      // filter by label
      label: 'my label',
      // filter by call state
      states: 'READY,FINISHED,INVALID',
      // filter by call result
      results: 'SENT',
      // filter only inbound actions
      inbound: false,
      // filter by time interval
      intervalBegin: 1473781817000,
      // filter by time interval
      intervalEnd: 1473781817000,
      // search offset
      offset: 0,
      // return 10 items per request
      limit: 10,
      // return only specific fields
      fields: 'items(id,fromNumber,toNumber,modified,finalCallResult)'
    })
      .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.findCalls(
    # filter by call ids
    id=[
        11646003,
        12646003,
        13776003
    ],
    # specify  id of a campaign, queries for calls inside a particular campaign.
    # do not set to list calls of all campaigns or 0 for a default campaign
    campaignId=449060003,
    # queries for calls which are used in the particular contact batch
    batchId=447060003,
    # filter by fromNumber
    fromNumber='12135551126',
    # filter by toNumber
    toNumber='12136666123',
    # filter by label
    label='my label',
    # filter by call state
    states='READY,FINISHED,INVALID',
    # filter by call result
    results='LA',
    # filter only inbound actions
    inbound=False,
    # filter by time interval
    intervalBegin=1473781817000,
    # filter by time interval
    intervalEnd=1473781817000,
    # search offset
    offset=0,
    # return 10 items per request
    limit=10,
    # return only specific fields
    fields='items(id,fromNumber,toNumber,modified,finalCallResult)'
).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->findCalls();
        $request->getOperationConfig()->setQueryParameters(array("id" => 11646003,
                                                                 "id" => 12646003,
                                                                 "id" => 13776003,
                                                                 "campaignId" => 449060003,
                                                                 "batchId" => 447060003,
                                                                 "fromNumber" => "12135551126",
                                                                 "toNumber" => "12136666123",
                                                                 "label" => "my label",
                                                                 "states" => "READY,FINISHED,INVALID",
                                                                 "results" => "LA",
                                                                 "inbound" => true,
                                                                 "intervalBegin" => 1473781817000,
                                                                 "intervalEnd" => 1473781817000,
                                                                 "offset" => 0,
                                                                 "limit" => 10,
                                                                 "fields" => "items(id,fromNumber,toNumber,modified,finalCallResult)"));
        $result = $client->request($request);
        $json = json_decode($result->getBody());
    }
}
[-php] [[/code-container]]

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