# API-triggered broadcasts

An API-triggered broadcast is like an event-triggered campaign, but the event—the `trigger`—represents a group of recipients.

## How it works[](#how-it-works)

API-triggered broadcasts provide a way to send a one-to-many campaign on demand. It may help to think of API-triggered broadcasts like event-triggered campaigns, except the event comes from your backend integration and represents a group of people. For example, you might use an API-triggered broadcast to:

*   Send news alerts to a group of people interested in a specific topic.
*   Alert users interested in an event when tickets go on sale.
*   Alert students when registration opens for a new online class.

Unlike a newsletter, you can reference trigger data in your API-triggered broadcasts with [liquidA syntax that supports variables, letting you personalize messages for your audience. For example, if you want to reference a person’s first name, you might use the variable `{{customer.first_name}}`.](/using-liquid).

 Try our Postman collection!

You can use our [Postman](https://www.getpostman.com) collection and associated environment to get started with the Customer.io API. Our environment is based on our US endpoints; if you’re in our EU region, you’ll need to add `-eu` to `track_api_url` and `app_api_url` variables.

(function(e,t,n,s,o,i,a){!e\[n\]&&(e\[n\]=function(){(e\[s\]||(e\[s\]=\[\])).push(arguments)}),!t.getElementById(n+s)&&t.getElementsByTagName("head")\[0\].appendChild((a=t.createElement("script"),a.id=n+s,a.async=1,a.src=o,a))})(window,document,"\_pm","PostmanRunObject","https://run.pstmn.io/button.js")

 You cannot trigger a broadcast more than once every 10 seconds.

This is because broadcasts are meant for a wide audience of people per trigger. They’re *not* intended for one-to-one interactions with individual people.

[You also can’t have more than 5 broadcasts queued for a single API-triggered broadcast.](#what-does-queueing-mean)

## Create an API-triggered broadcast[](#set-up-an-api-triggered-broadcast)

The steps to set up an API-triggered broadcast are fairly simple, but each step includes settings that we’ve explained in the sections below.

1.  Go to **Broadcasts** and click **Create Broadcast**.
2.  Enter a **name** so your team members can easily find the broadcast on the landing page.
3.  Click **Messages triggered via API**.
    
    [![The first page after clicking Create broadcast. There's a field for the name of the broadcast. Under the name, you can choose between newsletter and messages triggered via API.](https://docs.customer.io/images/broadcast-type-latest.png)](#856983bb7249f46b93fc2b3ae101d878-lightbox)
    
4.  (Optional) Click the name and add a **description** so your team members can tell what the purpose of the broadcast is.
    
    [![After you click the name of the broadcast in the top left, you see this menu. From top to bottom you see the name, description, tag, goal, and finally messages.](https://docs.customer.io/images/broadcast-upper-left-menu.png)](#a15d7de7c4bc22c1545b11e36f4275de-lightbox)
    
5.  (Optional) Add one or more [tags](/journeys/tagging-campaigns/) to help you organize and filter your broadcasts on the landing page.
6.  Click [**Set goal**](#goal). You can choose “No goal” if you don’t want to set one up.
7.  Modify your settings and *Messages* to change what [subscription center](/journeys/subscription-center/) topic people must be subscribed to to receive messages. If you don’t have the subscription center enabled, we’ll send messages to people who are [globally subscribed](/journeys/unsubscribes/). Set a [message limit](/journeys/message-limits/) if you want people to only receive a certain number of messages from you over a period of time.
8.  Click **Build** at the bottom of the workflow. Click and drag a [message, flow control, or data block](#set-up-your-workflow) from the panel onto your canvas. After you add your first block, you can drop subsequent blocks over any plus sign.
    
    [![An image of the workflow builder. In the top left is the name of the campaign. In the center is a workflow that starts with trigger followed by a true/false branch. In each branch is an email. In the top right is a button to review an item. To the right of that is the start button.](https://docs.customer.io/images/broadcast-workflow-latest.png)](#a19e74794b714056551075e6af6c25c2-lightbox)
    
9.  Decide your **message sending behavior**. By default, all messages are set to “Queue draft.” If you want messages to send automatically, click into each message and adjust the dropdown:
    
    [![broadcast-sending-behavior.png](https://docs.customer.io/images/broadcast-sending-behavior.png)](#05c44514ae1dc65b9c15abf88818bdeb-lightbox)
    
10.  After you’re finished building your workflow, click **Start Broadcast** in the top right to review and start your broadcast. If you haven’t fully set up your broadcast, click **Review items** and complete setup.
11.  [Define your recipients and trigger your broadcast](#trigger-your-broadcast).

### Set a goal[](#goal)

You can set up a **goal** to track the success of messages and journeys based on whether or not a person performs an event, enters a segment, or exits a segment after they receive a message from your broadcast.

If a person performs your goal criteria within a configurable time frame after they receive a message in your workflow, we’ll mark the messageThe instance of a message sent to a person. When you set up a message, you determine an audience for your message. Each individual “send”—the version of a message sent to a single member of your audience—is a delivery. and [journeyTypically, a person’s path through your campaign. If the campaign is triggered by a webhook, then a journey captures the webhook’s path, not a person’s.](/journeys/campaign-journeys/) converted.

Goals help you determine the success of your broadcast, and follow conversion rates over time to try and improve your messaging strategies. See [Goals](/journeys/campaign-conversions) for more information about conversions; api-triggered broadcasts have the same goal options as campaigns.

We track conversions for the following message/delivery types:

Conversions attributed

Conversions not attributed

Email

Slack Message

SMS

Create or update person action

Customer.io Push Notifications

Customer.io In-app Messages

Webhooks1

1You must [enable webhook conversions manually](/journeys/webhooks-action/#track-conversions).

Slack and *Create or update person* actions are often internal or used for analytics purposes; they don’t always send messages to end-users. For that reason, we don’t attach conversions to them. You can enable webhook conversions on individual webhook actions.

### Set up your workflow[](#set-up-your-workflow)

The workflow defines the journey for people who receive the broadcast—the messages they receive and the actionsA block in a campaign workflow—like a message, delay, or attribute change. you perform. API-triggered broadcasts perform all actions in the workflow at the same time, so you can’t use delays or time windows in your workflow.

You can, however, [send multiple messages if you want, or add additional actions](/journeys/workflow-builder/) like updating people’s attributes, sending events, and so on.

 Did you just update a snippet?

If you just updated a [snippet](/journeys/snippets/) used in your messages, make sure you wait a couple of minutes before activating your workflow to ensure all updates appear in your delivered messages.

### Define recipients & trigger your broadcast[](#define-recipients--trigger-your-broadcast)

You can manually define recipients or define them programmatically in your API call.

If you define them manually, you can either trigger the broadcast through the UI too or through an API call.

You might define your recipients in the UI if there’s a common group of people you send these broadcasts to. If you trigger the broadcast through an API call, note that the recipients defined there will override your UI conditions.

 Recipients defined in your API call override recipients defined in the UI

Make sure you don’t include recipients in your API call if you want to send to recipients defined in the UI.

#### Define recipients via UI[](#define-recipients-via-ui)

After you activate an API-triggered broadcast, you can define the recipients manually.

To define your recipients in the UI,

1.  Click **Workflow**.
2.  Click **Trigger > Edit Conditions**.
3.  Define your audience based on their attributes, segment membership, and/or message conditions.

Then you can trigger the broadcast through the UI or an API call.

#### Define recipients via API[](#define-recipients-via-api)

In your [API call](/integrations/api/app/#operation/triggerBroadcast), you can define recipients using a complex set of filters:

 You can nest `and` and `or` filters

Nest filters to create complex filters where you have different sets of `and` and `or` criteria that a person must meet to receive your broadcast.

 And

#### And[](#And)

The “And” filter is an array of objects, where each object represents criteria for your audience. Each object must be true for a person to receive the broadcast. You can nest other compound filters—`or` or `not`—to set up complex audience conditions.

```json
{
  "recipients": {
    "and": [
      {
        "attribute": {
          "field": "first_name",
          "operator": "exists"
        }
      },
      {
        "attribute": {
          "field": "likes_baseball",
          "operator": "eq",
          "value": true
        }
      }
    ]
  }
}
```

*   and array of \[ objects \]
    
    Match *all* conditions to return results.
    
    *   not 
        
        Returns results if a condition is false. While and/or support an array of items, `not` supports a single filter object.
        
        *   and array of \[ objects \]
            
            Match *all* conditions to return results.
            
        
        *   or array of \[ objects \]
            
            Match *any* condition to return results.
            
        
    *   or array of \[ objects \]
        
        Returns results matching *any* conditions.
        

 Or

#### Or[](#Or)

The “Or” filter is an array of objects where each object represents criteria for your audience. At least one object in the array must be true for a person to receive the broadcast. You can nest other compound filters—`and` or `not`—to set up complex audience conditions.

```json
{
  "recipients": {
    "or": [
      {
        "segment": {
          "id": 4
        }
      },
      {
        "attribute": {
          "field": "likes_baseball",
          "operator": "eq",
          "value": true
        }
      }
    ]
  }
}
```

*   or array of \[ objects \]
    
    Match *any* condition to return results.
    
    *   and array of \[ objects \]
        
        Returns results matching *all* conditions.
        
    *   not 
        
        Returns results if a condition is false. While and/or support an array of items, `not` supports a single filter object.
        
        *   and array of \[ objects \]
            
            Match *all* conditions to return results.
            
        
        *   or array of \[ objects \]
            
            Match *any* condition to return results.
            
        

 Not

#### Not[](#Not)

A condition that, if true, excludes people from your audience. The `not` filter is an object, but can take a complex filter, like `and` or `or`.

```json
{
  "recipients": {
    "not": {
      "and": [
        {
          "segment": {
            "id": 3
          }
        },
        {
          "attribute": {
            "field": "likes_baseball",
            "operator": "eq",
            "value": true
          }
        }
      ]
    }
  }
}
```

*   and array of \[ objects \]
    
    Match *all* conditions to return results.
    

*   or array of \[ objects \]
    
    Match *any* condition to return results.
    

 Segment

#### Segment[](#Segment)

A ID of a segment that people must belong to.

```json
{
  "recipients": {
    "segment": {
      "id": 3
    }
  }
}
```

*   id integer
    
    The ID of the segment you want to return people from.
    

 Audience

#### Audience[](#Audience)

Filter your audience based on an attribute value. In this case, you’ll provide:

*   `field`: the name of the attribute
*   `operator`: One of `exists` (true if a person has a value) or `eq` (true if a person matches a `value`).
*   `value`: Required if you use the `eq` operator. The value a person’s attribute must equal (`eq`) for the condition to be true.

```json
{
  "recipients": {
    "attribute": {
      "field": "likes_baseball",
      "operator": "eq",
      "value": true
    }
  }
}
```

*   field string
    
    Required The name of the attribute you want to filter against.
    
*   operator string
    
    Required Determine how to evaluate criteria against the field—`exists` returns results if a person in the audience has the attribute; `eq` returns results if the audience has the attribute and the attribute has the `value` you specify.
    
    Accepted values:`eq`,`exists`
    
*   value string
    
    The value you want to match for this attribute. You must include a value if you use the `eq` operator.
    

The people you set must already exist in your workspace. An API-triggered broadcast cannot create new people. Using an ID or an email that doesn’t belong to a person in your workspace will [produce errors](/journeys/api-triggered-errors/).

##### Add custom data for recipients[](#add-custom-data-for-recipients)

You can send custom data for each member of your broadcast using `per_user_data` or `data_file_url`. You can match data to people by `id` or `email`. For example, using the example below, you could use `{{trigger.voucher_code}}` to provide a custom coupon or voucher for your individual broadcast recipients.

 per\_user\_data

#### per\_user\_data[](#per_user_data)

Go to our [API docs](/api/app/#operation/triggerBroadcast) and select **User Maps** under Request Body to learn more.

```json
{
    "data": {
        "headline": "Roadrunner spotted in Albuquerque!",
        "date": 1511315635,
        "text": "We received reports of a roadrunner in your immediate area! Head to your dashboard to view more information!"
    },
    "per_user_data": [
        {"id":"wiley","data": {"voucher_code": "FESwYm"}},
        {"email":"road@runner.net","data": {"voucher_code": "cYm6XJ"}}
    ]
}
```

 data\_file\_url

#### data\_file\_url[](#data_file_url)

Go to our [API docs](/api/app/#operation/triggerBroadcast) and select **Data file URL** under Request Body to learn more.

```json
{
    "data": {
        "headline": "Roadrunner spotted in Albuquerque!",
        "date": 1511315635,
        "text": "We received reports of a roadrunner in your immediate area! Head to your dashboard to view more information!"
    },
    "data_file_url": "https://myFile.example.com"
}
```

#### Trigger via UI[](#trigger-via-ui)

To trigger a broadcast through the UI,

1.  Go to **Triggering Details**.
2.  (Optional) Under *Manual*, you can [include JSON data](#use-custom-data-in-your-trigger). Make sure you preview this data in your messages before you send.
    
    [![image.png](https://docs.customer.io/images/image%28240%29.png)](#3d15cad8eaf33d3bc71fba3850ef1799-lightbox)
    
3.  Under *Manual*, click **Trigger a Broadcast**. After you confirm, you will immediately trigger the broadcast.

Note, you can’t schedule an API-triggered broadcast through our UI like you can a newsletter.

#### Trigger via API[](#trigger-via-api)

In your [API call](/integrations/api/app/#operation/triggerBroadcast), enter your broadcast ID. You can find it in the *Triggering Details* tab of an active broadcast.

#### Define liquid variables with JSON[](#use-custom-data-in-your-trigger)

In the UI or API, you can define liquid variables with JSON data. In the UI, go to *Triggering Details*. Or in your API call, add info to the `data` key. Make sure you preview with sample data in your message(s) before triggering the broadcast.

```json
{
  "data": {
    "headline": "Roadrunner spotted in Albuquerque!",
    "date": "January 24, 2018", 
    "text": "We've received reports of a roadrunner in your immediate area! Head to your dashboard to view more information!" 
  }
}
```

## Track API-triggered Broadcasts[](#track-api-triggered-broadcasts)

After you trigger your broadcast, you can track metrics. Go to the *Overview* tab and you’ll see when you last triggered your broadcast and metrics across all sends.

In the *Broadcasts* tab, you’ll see a history of all the times you triggered the broadcast, and how many recipients there were for each trigger. Click into an individual broadcast to check its performance.

## Duplicate broadcasts[](#duplicate-broadcasts)

Duplicate an API-triggered broadcast to create your next broadcast faster or to run them in parallel for experimentation. You can copy entire broadcasts to preserve settings like recipient conditions, goals, and message settings in addition to their workflows. **You must activate the duplicate broadcast before anyone can enter it.**

 You can only duplicate API-triggered broadcasts *within* a workspace

If you need to duplicate a broadcast across workspaces, you can [copy workflow items](/journeys/copying-workflow-items/#copying-between-workspaces), but not broadcast settings.

To duplicate a broadcast:

1.  Click broadcast settings  inline with the broadcast you want to copy.
2.  Click **Duplicate**.

[![duplicate-apitb.png](https://docs.customer.io/images/duplicate-apitb.png)](#4ddea87cc5527ba12a3a24e7d264999f-lightbox)

The duplicate uses the original broadcast’s name prefixed with `[COPY]` and appears at the top of the API-triggered broadcast tab. You need to activate it before people can enter the broadcast.

[![duplicate-apitb-entry.png](https://docs.customer.io/images/duplicate-apitb-entry.png)](#ee1574aed8c29a5a2958d22ac493f0c6-lightbox)

## Frequently Asked Questions[](#frequently-asked-questions)

### What does “queueing” mean?[](#what-does-queueing-mean)

When you send an API call to trigger a broadcast, we put that broadcast in a queue. When it reaches the front, we start creating and sending messages or storing drafts depending on the sending behavior you’ve selected. When it finishes, it drops out of the queue!

Per [workspace](/journeys/workspaces), you can’t have more than 5 broadcasts queued for the same API-triggered broadcast. If you try to send more, you’ll get an error. You can retry the failed requests after the previous broadcasts finish sending.

### Why can’t I add delays and/or time windows?[](#why-cant-i-add-delays-andor-time-windows)

With API-triggered broadcasts, you’re meant to send one message to many people quickly or immediately in response to an API call or a recent change. For that reason, we haven’t added delays or time windows to the feature. That said, if you have a specific use case that necessitates time windows or delays in your broadcast, please [let us know](mailto:win@customer.io)!

### How many people can I message with a single API-triggered broadcast call?[](#how-many-people-can-i-message-with-a-single-api-triggered-broadcast-call)

There is no limit. You can pre-define a segment within Customer.io with the profiles you wish to message, or host a [data file](/journeys/api-triggered-data-format) containing all profiles you wish to have messaged.