Create a campaign
Updated
Creates an outbound campaign that dials a list of contacts with a saved agent.
Preview documentation
https://preview.ai.agora.io/conversational-ai/v1/projects/{appid}/campaignsEach contact is one dial task, and each dial starts a telephony session with the agent in agent_id. You supply the contacts when you create the campaign, and you can't change them afterward.
Before you create a campaign, create the agent and register the phone number to call from.
Caution
A campaign places real phone calls. When schedule.mode is immediate, dialing starts as soon as the campaign is created. To test, create a scheduled campaign with a start time in the future, then cancel it.
appidstringThe App ID of your project.
namestringA name for the campaign that helps you identify it, 1 to 255 characters.
agent_idstringThe ID of the saved agent that makes the calls.
transportobjectHow the campaign reaches its contacts.
typestringtelephony: The campaign places phone calls.
fromOne number | Several numbersThe number_id of the number to call from, or a list of up to 100 unique number_id values. With a list, the campaign rotates across the numbers.
call_policyobjectLimits and behavior for each call the campaign places. Each limit you omit adds no limit.
max_ring_duration_msintegerThe maximum time in milliseconds from starting the dial until the call is answered. If the call isn't answered in time, the dial attempt ends.
max_call_duration_secondsintegerThe maximum length of the call in seconds, measured from when it's answered. The session's lifecycle limits can end the call earlier.
max_silence_duration_msintegerHang up when nobody on the call has spoken for this many milliseconds. This is separate from pipeline.silence_config, which only prompts the user.
end_callobjectConditions under which the agent can end the call itself. Every condition is off unless you set it to true.
on_user_requestbooleanEnd the call when the caller clearly says goodbye or asks to hang up.
on_voicemailbooleanEnd the call when the agent reaches voicemail, such as a "please leave a message after the tone" announcement.
on_ai_assistantbooleanEnd the call when the call is answered by an AI assistant, a voice secretary, or another automated answering system.
contactsarray<object>The contacts to call, from 1 to 50,000. The whole request body can be at most 10 MiB. You can't change the list after you create the campaign. A phone number that appears more than once is called once for each entry.
phonestringThe phone number to call, in E.164 format, for example +12025550123.
valuesobjectValues for the agent's variables for this contact, keyed by variable name, up to 100. Each key must be a variable the agent declares, and each value must match its type and options. Pass a value for every required variable. If any contact breaks these rules, the whole request fails with 400, and no campaign is created. null values are rejected.
scheduleImmediate | ScheduledWhen the campaign dials. Pass the fields of one schedule mode only.
modestring(Immediate)immediate: The campaign starts dialing as soon as it's created.
timezonestring(Immediate)The IANA time zone for days, for example America/New_York. Daylight saving time is handled automatically. Required when you pass days.
daysarray<object>(Immediate)The weekly hours when new calls can start. Outside these hours, no new calls start. A day you don't list has no dialing. Omit days to dial at any time.
weekdaystringThe day of the week. Each day can appear only once.
rangesarray<object>One to 10 windows on this day, which can't overlap.
startstringThe start of the window, as a local time in 24-hour HH:MM format.
endstringThe end of the window, as a local time in HH:MM format, later than start. Use 24:00 for the end of the day.
modestring(Scheduled)scheduled: The campaign dials from start until end.
timezonestring(Scheduled)The IANA time zone for start, end, and days, for example America/New_York. Daylight saving time is handled automatically.
startstring(Scheduled)When the campaign can start dialing, as a local date and time in YYYY-MM-DDTHH:MM format with no offset, for example 2026-11-02T09:00. A local time that doesn't exist or occurs twice because of a daylight saving change is rejected.
endstring(Scheduled)When the campaign stops placing new calls, as a local date and time in YYYY-MM-DDTHH:MM format, later than start. Calls in progress continue. A local time that doesn't exist or occurs twice because of a daylight saving change is rejected.
daysarray<object>(Scheduled)The weekly hours when new calls can start. Outside these hours, no new calls start. A day you don't list has no dialing. Omit days to dial at any time.
weekdaystringThe day of the week. Each day can appear only once.
rangesarray<object>One to 10 windows on this day, which can't overlap.
startstringThe start of the window, as a local time in 24-hour HH:MM format.
endstringThe end of the window, as a local time in HH:MM format, later than start. Use 24:00 for the end of the day.
lifecycleobjectThe lifecycle settings for each session the campaign starts. Each session can last up to 1 hour, and lasts up to 5 minutes by default.
idle_timeout_msintegerHow long in milliseconds the session continues with no participant present: after the subscribed user leaves the RTC channel, or after the other side of a phone call hangs up. It isn't silence detection. Set to 0 to turn off the idle timer. Can't be greater than max_duration_ms.
max_duration_msintegerThe maximum length of each session in milliseconds, measured from start_ts. Defaults to 5 minutes. The maximum is 1 hour.
graceful_stopobjectHow the agent finishes when you stop the session, or when the idle timer expires. It doesn't extend max_duration_ms, and it doesn't add a farewell message.
enabledbooleanWhether the agent finishes what it's saying before it leaves.
timeout_msintegerThe longest time in milliseconds the agent can take to finish.
pacingobjectHow fast the campaign dials. Each contact is called once.
max_concurrentintegerThe maximum number of calls in progress at the same time.
max_calls_per_secondintegerThe maximum number of new dials in any one-second window. If you omit it, the campaign uses your project's default dial rate. A value above the project's limit is rejected with InvalidFieldValue.
data_policyobjectThe data policy for each session the campaign starts. Defaults to 30-day retention.
retentionstringHow long Agora keeps the conversation data:
30_days: Agora keeps the data for 30 days.none: Agora doesn't keep the data, and variable extraction doesn't run. Use it, for example, when a caller declines recording.
Response Body
The campaign was created. The response body contains the campaign.
Response Headers
campaign_idstringThe ID of the campaign, a UUID.
namestringThe name of the campaign.
statusstringThe status of the campaign:
scheduled: The campaign is waiting for its start time.running: The campaign is dialing, or can dial during its schedule.paused: You paused the campaign.completed: The campaign has finished.canceled: You canceled the campaign.failed: The campaign failed. The details are infailure.
agent_idstringThe ID of the agent that makes the calls.
transportobjecttypestringAlways telephony.
fromarray<string>The number_id values of the numbers the campaign calls from.
call_policyobjectLimits and behavior for each call the campaign places. Each limit you omit adds no limit.
max_ring_duration_msintegerThe maximum time in milliseconds from starting the dial until the call is answered. If the call isn't answered in time, the dial attempt ends.
max_call_duration_secondsintegerThe maximum length of the call in seconds, measured from when it's answered. The session's lifecycle limits can end the call earlier.
max_silence_duration_msintegerHang up when nobody on the call has spoken for this many milliseconds. This is separate from pipeline.silence_config, which only prompts the user.
end_callobjectConditions under which the agent can end the call itself. Every condition is off unless you set it to true.
on_user_requestbooleanEnd the call when the caller clearly says goodbye or asks to hang up.
on_voicemailbooleanEnd the call when the agent reaches voicemail, such as a "please leave a message after the tone" announcement.
on_ai_assistantbooleanEnd the call when the call is answered by an AI assistant, a voice secretary, or another automated answering system.
lifecycleobjectWhen each session the campaign starts ends on its own.
idle_timeout_msintegerHow long in milliseconds the session continues with no participant present: after the subscribed user leaves the RTC channel, or after the other side of a phone call hangs up. It isn't silence detection. Set to 0 to turn off the idle timer. Can't be greater than max_duration_ms.
max_duration_msintegerThe maximum length of each session in milliseconds, measured from start_ts. Defaults to 5 minutes. The maximum is 1 hour.
graceful_stopobjectHow the agent finishes when you stop the session, or when the idle timer expires. It doesn't extend max_duration_ms, and it doesn't add a farewell message.
enabledbooleanWhether the agent finishes what it's saying before it leaves.
timeout_msintegerThe longest time in milliseconds the agent can take to finish.
scheduleImmediate | ScheduledWhen the campaign dials. Pass the fields of one schedule mode only.
modestring(Immediate)immediate: The campaign starts dialing as soon as it's created.
timezonestring(Immediate)The IANA time zone for days, for example America/New_York. Daylight saving time is handled automatically. Required when you pass days.
daysarray<object>(Immediate)The weekly hours when new calls can start. Outside these hours, no new calls start. A day you don't list has no dialing. Omit days to dial at any time.
weekdaystringThe day of the week. Each day can appear only once.
rangesarray<object>One to 10 windows on this day, which can't overlap.
startstringThe start of the window, as a local time in 24-hour HH:MM format.
endstringThe end of the window, as a local time in HH:MM format, later than start. Use 24:00 for the end of the day.
modestring(Scheduled)scheduled: The campaign dials from start until end.
timezonestring(Scheduled)The IANA time zone for start, end, and days, for example America/New_York. Daylight saving time is handled automatically.
startstring(Scheduled)When the campaign can start dialing, as a local date and time in YYYY-MM-DDTHH:MM format with no offset, for example 2026-11-02T09:00. A local time that doesn't exist or occurs twice because of a daylight saving change is rejected.
endstring(Scheduled)When the campaign stops placing new calls, as a local date and time in YYYY-MM-DDTHH:MM format, later than start. Calls in progress continue. A local time that doesn't exist or occurs twice because of a daylight saving change is rejected.
daysarray<object>(Scheduled)The weekly hours when new calls can start. Outside these hours, no new calls start. A day you don't list has no dialing. Omit days to dial at any time.
weekdaystringThe day of the week. Each day can appear only once.
rangesarray<object>One to 10 windows on this day, which can't overlap.
startstringThe start of the window, as a local time in 24-hour HH:MM format.
endstringThe end of the window, as a local time in HH:MM format, later than start. Use 24:00 for the end of the day.
countsobjectThe number of contacts in each state. Retrieve the campaign to get current counts.
contactsintegerThe total number of contacts.
pendingintegerContacts not called yet, or waiting for a retry.
callingintegerContacts in a call now.
completedintegerContacts whose call has finished.
failedintegerContacts not reached after all attempts.
canceledintegerContacts that won't be called because the campaign was canceled.
create_tsintegerThe time the campaign was created, as a Unix timestamp in seconds.
start_tsinteger | nullThe time the campaign started dialing, as a Unix timestamp in seconds. null before it starts.
complete_tsinteger | nullThe time the campaign finished, as a Unix timestamp in seconds. null until it finishes.
failureobject | nullDetails of the failure when status is failed. Otherwise null.
codestring(object)A stable runtime error code, for example provider_error.
providerstring(object)The model provider that caused the failure, for example openai.
messagestring(object)A human-readable explanation.
tsinteger(object)The time the failure occurred, as a Unix timestamp in seconds.
Request examples
curl -X POST 'https://preview.ai.agora.io/conversational-ai/v1/projects/string/campaigns' \ -H 'Content-Type: application/json' \ -d '{ "name": "q3-renewals", "agent_id": "3f6c2a9e-8d1b-4e7a-9c55-0b2f7d1e4a10", "transport": { "type": "telephony", "from": "92e68758-3d3a-4f27-8b93-3fd8d834467c" }, "contacts": [ { "phone": "+12025550123", "values": { "name": "Ava", "renewal_year": 2027 } } ], "lifecycle": { "idle_timeout_ms": 30000 }, "pacing": { "max_concurrent": 10, "max_calls_per_second": 2 }, "schedule": { "mode": "scheduled", "timezone": "America/New_York", "start": "2026-11-02T09:00", "end": "2026-11-13T17:00", "days": [ { "weekday": "mon", "ranges": [ { "start": "09:00", "end": "12:00" }, { "start": "13:00", "end": "17:00" } ] }, { "weekday": "wed", "ranges": [ { "start": "09:00", "end": "17:00" } ] } ] }}'Response example
{ "campaign_id": "b4f0581e-f138-43a2-851c-a8f8d228bb37", "name": "q3-renewals", "status": "scheduled", "agent_id": "3f6c2a9e-8d1b-4e7a-9c55-0b2f7d1e4a10", "transport": { "type": "telephony", "from": [ "92e68758-3d3a-4f27-8b93-3fd8d834467c" ] }, "lifecycle": { "idle_timeout_ms": 30000, "max_duration_ms": 300000, "graceful_stop": { "enabled": false, "timeout_ms": 30000 } }, "schedule": { "mode": "scheduled", "timezone": "America/New_York", "start": "2026-11-02T09:00", "end": "2026-11-13T17:00" }, "counts": { "contacts": 1, "pending": 1, "calling": 0, "completed": 0, "failed": 0, "canceled": 0 }, "create_ts": 1787673602, "start_ts": null, "complete_ts": null, "failure": null}