# Bulk sending

Send messages to lists of users by providing audience identifiers at send time, either directly in the request or by first creating a bulk audience ID.

Bulk sending eliminates the need to add users to your project ahead of time. For example, you can send messages to a list of users generated from [Performance Analytics](https://www.airship.com/docs/reference/glossary/#pa) or other reporting platforms without having to re-create your audience criteria.

To address existing channels by [Channel ID](https://www.airship.com/docs/reference/glossary/#channel_id), use the [Upload and Send](#upload-and-send) method. To send to email addresses, phone numbers, or Open channel addresses, use [Create and Send](#create-and-send), and any unregistered addresses will be registered as new channels at send time.

## Upload and Send

Upload and Send targets existing channels by [Channel ID](https://www.airship.com/docs/reference/glossary/#channel_id) across app, web, email, SMS, and Open channels.

To use this method, first prepare a CSV file of Channel IDs (see [CSV formatting](#csv-formatting) for requirements), and then:

* **Dashboard:** In the [Message composer](https://www.airship.com/docs/guides/messaging/messages/create/), select **Upload users** in the Audience step, and upload your CSV in the Review step.

* **API:** Upload your CSV to the [Create bulk send audience endpoint](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#bulkuploadcreateandsendplatform) to obtain a `bulk_id`, and then send your message using the [Send message with bulk ID](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#bulksendpush) or [Schedule message with bulk ID](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#schedulebulksendpush) endpoint.

## Create and Send

*Create and Send* is a way to target recipients of a single channel type by providing a list of user identifiers when creating a message. You can send to email addresses, phone numbers, or Open channel addresses. Unknown identifiers are registered as new channels.

You can provide your identifiers as CSV in the dashboard or API, and the API also supports an array method:

| Use | ID format | Steps |
| --- | --- | --- |
| Dashboard | CSV | In the [Message composer](https://www.airship.com/docs/guides/messaging/messages/create/), select **Upload users** in the Audience step, and upload your CSV in the Review step. |
| API | CSV | First, upload identifiers in CSV format to the [Create bulk send audience](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#bulkuploadcreateandsendplatform) endpoint to obtain a `bulk_id`. Then, send your message using the [Create and Send a message](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#createandsend) or [Schedule a Create and Send message](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#schedulecreateandsendoperations) endpoint. New channels are created at send time, not when requesting the ID. |
| API | Array | Include audience identifiers in the `create_and_send` array within the `audience` object when calling the [Create and Send a message](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#createandsend) or [Schedule a Create and Send message](https://www.airship.com/docs/developer/rest-api/ua/operations/bulk-sending/#schedulecreateandsendoperations) endpoint. |

The Create and Send endpoints also support sending to app and web Channel IDs using a `bulk_id`, but it works identically to [Upload and Send](#upload-and-send).

## Usage guidelines

Bulk send methods have the following limitations:

* Channels must all be of the same type.
* Each `bulk_id` can only be used once. After sending, the bulk audience data is deleted.
* [CSV columns](#csv-formatting) not prefixed with `ua_` are used for message personalization only and are not saved as channel attributes.
* Bulk sends support only a single device type per request. Setting multiple `device_types` returns a 400 response.
* [Optimal Send Time](https://www.airship.com/docs/reference/glossary/#optimal_send_time) is not supported.

## CSV formatting

CSV files must be smaller than 150 MB, with a maximum of three million rows. The header row is case-sensitive and must contain the required `ua_`-prefixed channel fields as column headers, with values in corresponding fields. Airship ignores rows that are empty or contain malformed channel information.

### Using Channel IDs

Use Channel IDs for [Upload and Send](#upload-and-send).

* The first column header must be `ua_channel_id`. Entries in the first column contain the target Channel ID.
* Your audience must all belong to the same device type. For App channels, this means one of iOS, Android, or Fire OS channels at a time.<!-- what happens if a channel is not for the current device type? error or drop? --> For example, if you want to send a message to both iOS and Android channels, you must curate separate lists of iOS and Android users and send two separate messages.

### Using email, SMS, or Open channel identifiers
   
Use email addresses, phone numbers, or Open channel identifiers for [Create and Send](#create-and-send).

* The first column header varies per channel. Entries in the first column contain the target identifier.
* For existing channels, you must provide an `opted_in` date-time value that is newer than an `opted_out` value on the channel. <!-- Previously it said this was for email and SMS only, but it doesn't say that in the API docs. -->
   > **Important:** Setting a newer `opted_in` date-time value within the CSV data does not update the `opted_in` value on the channel. It only overrides the `opted_out` value to send the current message. You must update the `opted_in` value using the appropriate channel API to opt it back in to your messaging audience.

* Opt-in/out dates must be formatted as ISO 8601 strings. See [Date-Time Format](https://www.airship.com/docs/developer/rest-api/ua/introduction/#date-time-format) in the API reference.

Required fields and formatting information per channel type:

<div class="table-scroll-wrapper">
<table width="100%" class="reference-table">
  <col style="width:10%">
  <col style="width:15%">
  <col style="width:25%">
  <col style="width:40%">
  <thead>
    <tr>
      <th>Channel</th>
      <th>First column header field value</th>
      <th>First column row field values</th>
      <th>Additional header field values</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SMS</td>
      <td><code>ua_msisdn</code></td>
      <td>A [MSISDN](https://www.airship.com/docs/reference/glossary/#msisdn)</td>
      <td>
        <ul>
          <li><code>ua_sender</code></li>
          <li><code>ua_opted_in</code><sup>1</sup></li>
        </ul>
      </td>
    </tr>
    <tr>
      <td>Email</td>
      <td><code>ua_address</code></td>
      <td>An email address</td>
      <td>
        <ul>
          <li><code>ua_commercial_opted_in</code> or <code>ua_commercial_opted_out</code><sup>1,2</sup></li>
          <li><code>ua_open_tracking_opted_in</code> or <code>ua_open_tracking_opted_out</code><sup>1,3</sup></li>
          <li><code>ua_click_tracking_opted_in</code> or <code>ua_click_tracking_opted_out</code><sup>1,3</sup></li>
          <li><code>ua_email_suppression_state</code><sup>4</sup></li>
          <li><code>timezone</code><sup>5</sup></li>
        </ul>
      </td>
    </tr>
    <tr>
      <td>Open</td>
      <td><code>ua_address</code></td>
      <td>A unique address that your Open channel uses</td>
      <td>n/a</td>
    </tr>
  </tbody>
</table>
</div>

<sup>1. The <code>opted_in</code> values for email and SMS channels are the date-time when the user subscribed to messages.</sup><br>
<sup>2. An opt-in or -out date is required for commercial emails. You can also provide dates for <code>ua_transactional_opted_in</code> or <code>ua_transactional_opted_out</code>, but they are optional. Opt-in/out dates are mutually exclusive. Providing a date for both opted in and opted out in the same row is considered invalid.</sup><br>
<sup>3. By default, new channels are opted in to both open and click tracking. A channel can be opted out of tracking by setting an opted out date. The channel can be opted back in to tracking by setting an opted in date that is newer than the opted out date. Providing a date for both opted in and opted out in the same row is considered invalid.</sup><br>
<sup>4. With value <code>BOUNCE</code>, <code>SPAM_COMPLAINT</code>, <code>COMMERCIAL_SPAM_COMPLAINT</code>, or <code>IMPORTED</code>. See <a href='https://www.airship.com/docs/developer/api-integrations/email/bounce-handling/#suppression-types'>Suppression types</a> in <i>Email Bounce Handling and Suppression</i>.</sup><br/>
<sup>5. Format time zones according to the IANA time zone database. For example, <code>America/Los_Angeles</code>.</sup>

**CSV example for a Create and Send email**

```text
ua_address,ua_commercial_opted_in,name,city,state
someone@example.com,2022-04-01T18:45:30,Joe Someone,Portland,OR
else@example.com,2022-04-21T16:13:01,Sir Else,Seattle,WA
```


## Personalization

All bulk send methods support [personalization](https://www.airship.com/docs/guides/personalization/about/). Your CSV can contain additional columns for personalizing messages using [Handlebars](https://www.airship.com/docs/reference/glossary/#handlebars). All values in CSV uploads, including numbers, are represented as strings and cannot be used with [math helpers](https://www.airship.com/docs/guides/personalization/handlebars/math-helpers/).

When sending to a `bulk_id`, include `"personalization": true` in the `options` object of your send request. Personalization is enabled automatically for the array method and dashboard sends.

See [Personalize your Create and Send messages](https://www.airship.com/docs/guides/personalization/sources/create-and-send/).
