All pages

Guides

Campaigns

Call a list of people at a pace you set, only in calling hours, and hear how each call went.

View as Markdown

A campaign is a list of people for an outbound agent to call, at the pace you set and only in the hours you allow. It is the same campaign the console shows on the agent's Campaigns tab: one you start through the API, a colleague can pause in the console, and the other way round.

Campaigns call real people, so making or changing one needs a live key with campaigns:write, and reading them needs campaigns:read. A test key reads no campaigns. To try your integration first, schedule single calls to the test numbers.

Create one

Create a campaign
#!/bin/sh
# Create a campaign. With a live key: a campaign calls real people. It is a draft until you start it.
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/campaigns" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY" \
  -H "Idempotency-Key: reminders-october" \
  --json '{
  "agent_id": "8a1f3c2e-0b6d-4f5e-9a7c-2d4e6f8a0b1c",
  "name": "Visit reminders, October",
  "calling_hours": {
    "start_hour": 9,
    "end_hour": 18,
    "days": [
      "mon",
      "tue",
      "wed",
      "thu",
      "fri"
    ]
  },
  "contacts": [
    {
      "to_number": "+12025550123",
      "variables": {
        "first_name": "Sara"
      },
      "metadata": {
        "crm_lead_id": "L-20931"
      },
      "external_id": "lead-20931"
    },
    {
      "to_number": "+12025550124",
      "variables": {
        "first_name": "Omar"
      },
      "timezone": "America/Chicago",
      "external_id": "lead-20932"
    }
  ]
}'

Each contact is one person: to_number, their variables, and if you like their timezone, your own metadata and an external_id. Everything is checked before anything is made. A number the platform does not call, the same number twice, a time zone that is not one, or a value that does not fit the agent is refused with validation_failed, and errors names each contact by its place in the list — contacts[3].variables.renewal_date. Up to 1,000 contacts go in one request; send the rest as more people.

Idempotency-Key is required. A retry with the same key returns the campaign the first attempt made, and never makes a second one that would call everybody twice. See Safe retries.

Field What it is
pacing max_concurrent calls at once, dials_per_minute, max_attempts for each person, and retry_backoff_minutes between tries.
calling_hours start_hour, end_hour and days, read in each contact's own timezone — or your organization's, for a contact without one.
voicemail hang_up when a machine answers, or leave_message with the message to leave.
callbacks Whether a person may ask the agent to call back at a time of their own.
phone_number_id Which of the agent's numbers to call from. The agent's own unless you say.
start, start_at Start now, or at a moment you choose. Leave both out to start it later.

A campaign is a draft until it starts. Starting checks that it can place a call: the agent is published, it has a number to call from, and every contact has the values the agent says out loud — other than a field with a default, which fills in, or one that is not required. It also needs somebody on its list: a campaign started with no contacts would finish at once, so it is refused with campaign_empty. To send the contacts in batches, create it as a draft, add them, then start it. A campaign with a start_at may be empty until then. If nobody is on its list when the time comes, it starts and waits for its first contacts instead of finishing.

Start, pause, resume and cancel

Start a campaign
#!/bin/sh
# Start a campaign
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b/start" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY"
Pause a campaign
#!/bin/sh
# Pause a campaign. Calls in progress carry on; nobody new is called until you resume it.
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b/pause" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY"
Resume a campaign
#!/bin/sh
# Resume a campaign
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b/resume" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY" \
  --json '{
  "reset_attempts": false
}'
Cancel a campaign
#!/bin/sh
# Cancel a campaign. For good: nobody else on the list is called.
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b/cancel" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY"

Pausing stops new calls. Calls in progress carry on, and resuming picks up where it stopped; send reset_attempts: true to give everybody not reached so far every try back. Cancelling stops it for good. Each answers with the campaign, and one that has already happened answers it as it is, so a retry is harmless. A campaign that has finished — completed or cancelled — answers campaign_finished.

A campaign can pause itself, too: when your organization's calls for the day are used up, or when calls cannot be placed at all. paused_reason says why, and resuming is your decision.

While the deployment has phone calls switched off, creating, starting and resuming a campaign are refused with feature_disabled. Pausing and cancelling still work.

Add more people

Add people to a campaign
#!/bin/sh
# Add people to a campaign. A number the campaign already holds is skipped, so sending a batch again is safe.
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b/contacts" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY" \
  --json '{
  "contacts": [
    {
      "to_number": "+12025550125",
      "variables": {
        "first_name": "Lina"
      },
      "external_id": "lead-20933"
    }
  ]
}'

A campaign that is a draft, running or paused takes more contacts, and a running one calls them in its next calling hours. A number the campaign already holds is skipped and listed in already_in_campaign, so sending a batch again is safe, even while the first is still being added. +15550100 and 15550100 are the same number. A campaign completes once nobody is left to call; after that, start a new one.

See how it went

Read a campaign and its progress
#!/bin/sh
# Read a campaign and its progress
curl -sS --fail-with-body -X GET "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY"

contacts counts the people in each state. List them, with how it went for each:

See how each call in a campaign went
#!/bin/sh
# See how each call in a campaign went
curl -sS --fail-with-body -X GET "https://api.aigently.ai/v1/campaigns/1c3e5a7b-9d0f-4b2c-8e4a-6c8e0a2c4e6b/contacts?status=done" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY"
status What it means
queued Waiting for their turn, or for their next try at next_attempt_at.
dialing On a call now.
done Reached — or a message was left on their machine.
exhausted Every try was used without reaching them.
failed Not called: the platform refused, and error says why — a number on your do-not-call list, for one.

conversation_id is their latest conversation. Every conversation with them carries their metadata, their external_id and the campaign_id, so a webhook about it can be tied back to its lead.

All your campaigns, newest first:

List campaigns
#!/bin/sh
# List campaigns
curl -sS --fail-with-body -X GET "https://api.aigently.ai/v1/campaigns?limit=10" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY"

Hear about it

Five events, sent to live receivers only:

Event When
campaign.started It started calling — at once, at its start time, or again after a pause.
campaign.paused Paused by somebody, or by itself, with paused_reason.
campaign.completed Nobody is left to call.
campaign.cancelled Stopped for good.
campaign.contact_finished One person's final result: done, exhausted or failed.

Each carries the campaign, or the contact, as the API reads it. A contact's number, values and metadata are left out for a receiver that does not include values, as they are for conversations.

A campaign belongs to your organization, not to the key that made it: revoking the key does not stop it. Pause or cancel it instead.