Add promotional codes to your messages. Coupons are an AXP feature.

About Coupons

Like other forms of personalization in Airship, with Coupons you create a merge field representing a value you want to personalize, surrounded by double curly braces {{ }}, also known as HandlebarsHandlebars is Airship’s templating language for personalization. Handlebars expressions use double curly braces wrapped around a content template, ranging from a simple variable, e.g., {{first_name}}, to complex evaluations of personalization data. . Airship replaces the merge field (and braces) with the data specified by the merge field at send time — just like mail merge in a word processor or mail client.

The source of this data (including your promotional codes) is a CSV file you upload to Airship and the campaign you define for the codes. We refer to this source as a feed for the campaign, and you’ll see the term in the dashboard and in the required formatting for your message content.

Example uses:

  • Provide exclusive discounts or rewards to retain or transition your customers and build loyalty
  • Clear out excess or slow-moving inventory
  • Re-engage existing customers with your business

Coupons are supported for messages in both the dashboard and API.

Promotional codes are rendered in plain text in your messages. You can use the JsBarcode library to render the codes as barcodes instead.

Codes are limited to 100 requests per second and are best used with automation. Consider this rate if you intend to distribute codes via broadcasts to large audiences.

Supported message types

You can add codes to any message content you create using the Message, A/B Test, Automation, and Sequence composers:

  • Push notification
  • In-app message (standard format)
  • Message Center (Not supported for A/B Tests)
  • Landing page
  • Web push notification
  • Email
  • SMS
  • Open channel

You can also add codes to TemplatesReusable message content that saves you the trouble of having to rewrite a message. Templates support merge fields and other logic, letting you personalize the resulting messages. for:

  • Push notification
  • Message Center (can also be used for landing pages)
  • Web push notification
  • Email
  • SMS
  • Open channel

The same message types and template content are supported in the API.

Coupons are not supported for In-App Automation, Surveys, or Scenes, as these are ephemeral and not a good place to show the promotional code. We suggest using a link in these formats to other messaging formats that are persistent.

Remaining code notifications

When you upload your CSV file, a value equal to 10% of the number of codes is stored and checked when a code is used in a message. We’ll notify you by email when 90% of codes have been used in messages and again at 100%.

You can specify up to five email addresses for notification. Add as a contact in your email client to ensure these messages are not marked as spam.

We repeat the calculation when you add more codes to a campaign.

Coupons workflow

The following is the general workflow for using promotional codes in messages. For illustration, we are using retail loyalty as an example.

  1. Create your CSV file. The first row must contain headers coupon_code and campaign. Each additional row must contain a unique alphanumeric code and the same ID for the campaign. (You can add more information in your file, but we’re keeping it simple for this example).

    Example CSV

  2. Create a campaign in the dashboard. You will upload your CSV file and define the following:

    • Campaign name — This is used for identification in the list of all campaigns in your project.
    • Campaign ID — This must match what you put in your CSV. You will use the ID when creating your messages so Airship can use codes from the right campaign.
    • Validity period — The effective and expiration dates for the campaign and its codes.

    In our examples the campaign ID is 2023loyalty, and we’ll use expiration date 2023-03-20.

  3. Create your content using the following format. In all content, use the feed ID couponing.

    {{#feed "couponing"}}
    Content referencing the feed, like a {{coupon_code}}.

    Using our loyalty example, your message would look like this in the Interactive EditorA tool for creating content for landing pages, Message Center, email, and in-app automation. You can provide your own HTML or design using the drag-and-drop WYSIWYG option. :

  4. Specify the campaign ID and determine failure behavior when sending the message.

    • In the dashboard, you’ll do this in the Delivery step of a composer.
    • With the API, you’ll make these specifications in the External Data Feed References object.

    As a best practice, verify the campaign ID, its validity period, and that it has available codes prior to sending the message. The feed will fail if the expiration date has passed or does not have remaining codes.

    You can view the number of available codes for each campaign in Settings » Project Configuration » Coupons.

Boom! We just sent codes to our audience. Now what happens? This is what Airship does next:

  • Populates your message content at send time, using one code from your CSV file per message
  • Checks the number of remaining codes so we can process your remaining code notifications
  • Generates an event every time a code is used in a message (See next section)

Codes do not populate messages as ordered in your CSV file. For example, if your CSV file has rows with codes in order 1001, 1002, 1003, they may be sent to users in order 1003, 1001, 1002.


Codes are associated with the Channel IDAn Airship-specific unique identifier used to address a channel instance, e.g., a smartphone, web browser, email address. of the message recipient at send time. This association is recorded as a Custom EventEvents that indicate that a user performed a predefined action, such as adding an item to a shopping cart, viewing a screen, or clicking an Unsubscribe button. Custom events can trigger automation, sequences, scenes, and surveys. You can code them into your app or website, or send them to Airship from an external source using the custom event API. Custom events contain properties that you can use to personalize messages. with name coupon_assigned. The event properties use keys coupon_code and campaign. coupon_code_alt will also appear if included in your CSV file. The property values are the actual code used in the message and the campaign ID.

The event is recorded the first time a code for a given campaign is assigned to a channel ID. Additional events are not recorded if you send messages to the same channel ID that references the same code.

Example Coupons custom event
    "name": "coupon_assigned",
        "coupon_code": "RS8E3589",
        "campaign": "2023loyalty"

Formatting your CSV file

When uploading in the dashboard, maximum file size 1.5 GB. There is no file size limit when using SFTP to add more codes to a campaign. To ensure the support of special characters and accents, the file must be encoded to UTF-8 without BOM.

  • campaign — Required. The campaign ID. Used to determine which campaign to use for populating message content. Ignored when uploaded in the dashboard. Must match an existing campaign when uploaded via SFTP.
  • coupon_code — Required. A unique alphanumeric value to render in a message. Duplicate values are ignored and not added to the campaign as available codes.
  • coupon_code_alt Optional. An alternative version of the coupon code (such as an online code) that can be rendered in a message. Must be a unique alphanumeric value.
  • starts_time — Optional. The effective date for the campaign. Must be in ISO 8601 date-time format YYYY-MM-DDThh:mm:ss. Defaults to current time if not provided. Ignored when file is uploaded in the dashboard. Updates the campaign effective date in the dashboard when uploaded via SFTP.
  • ends_time — Optional. The expiration date for the campaign. Must be in ISO 8601 date-time format YYYY-MM-DDThh:mm:ss. Ignored when uploaded in the dashboard. Updates or sets the campaign expiration date in the dashboard when uploaded via SFTP.

Example Coupons CSV file


Creating a campaign

  1. Go to Settings » Project Configuration and click Manage for Coupons.
  2. Click Create coupon campaign.
  3. Configure fields:
    • Campaign name — Used for identification in the list of all coupon campaigns in your project.
    • Campaign ID — Used to determine which campaign to use for populating message content.
      • Format supports alphanumeric characters, dashes, and underscores.
      • The ID must be unique for a project, without spaces or special characters.
      • The campaign value in your CSV file will be ignored.
      • You cannot change the campaign ID later.
    • Effective/Expiration dates — Optional. The beginning and end dates for the campaign and its codes.
      • If the effective date is not specified, it defaults to the date-time at time of saving the campaign.
      • If you set a start date, you cannot edit it later.
    • Remaining codes contact — The email address used to contact you with remaining code notifications. You can enter up to five comma-separated addresses. Addresses entered here will replace those entered for every campaign in the project.
  4. Upload your CSV file.
  5. Click Save campaign.

You will return to the list of all campaigns in the project.

Adding codes to messages

You add codes to messages in two parts:

  1. Formatting the message content
  2. Specifying the campaign to use as the data feed and determining how to handle the message if the feed fails

Formatting content

Formatting your message content is identical in the dashboard and the API. In the dashboard you add content when configuring a template or in the Content step in a composer.

Content format for Coupons

{{#feed "couponing"}}
Content referencing the feed, like a {{coupon_code}}.
{{#feed "couponing" campaign="FallSavings"}}
Content referencing the feed, like a {{coupon_code}}.

The feed ID is always couponing. To render coupon codes, the campaign ID, or effective and expiration dates, use {{coupon_code}}, {{campaign}}, {{campaign_start_date}}, and {{campaign_end_date}}.

Dates are rendered in ISO 8601 date-time format: YYYY-MM-DDThh:mm:ss. If you want dates to appear differently in your message, use Date and time helpers. Examples for a campaign with expiration date 2023-10-15:

  • To render the date as 10/15/2023, you would enter it like so in your message content: {{dateFormat campaign_end_date locale="en-US" format="SHORT"}}.
  • To render the date as Oct 15, 2023, you would use: {{dateFormat campaign_end_date locale="en-US" format="MEDIUM"}}.

You can use reference variables (or Merge FieldsA variable in your message or template that you want to populate with a personalized value for each member of the audience. Merge fields use Handlebars syntax — {{merge_field}}. ) that aren’t a part of a feed and variables that are part of a feed in the same #feed block. See: Differentiating data sources.


When using the Interactive EditorA tool for creating content for landing pages, Message Center, email, and in-app automation. You can provide your own HTML or design using the drag-and-drop WYSIWYG option. to create content for a template, email, landing page, or Message Center message, we provide a helper for inserting the feed formatting.

  1. Click Data Feed in the left sidebar.
  2. Click   next to Coupon Service. The feed ID couponing will be exposed.
  3. Hover over the feed ID and click  .
  4. Select a field in your message content and paste the copied data. You should see:
    {{#feed "couponing"}}

Rendering as a barcode

Use the JsBarcode library to render your alphanumeric codes as barcodes. Make sure that the location where you are using a barcode supports HTML and JavaScript. For example, you cannot use barcodes in push notifications since they only support plain text.

Sample content for a barcode
<div style="text-align:center;">
   <svg id="barcode"></svg>
<script src=""></script>
   JsBarcode("#barcode", "{{#feed 'couponing' as |data|}}{{data.coupon_code}}{{/feed}}");

Displaying an alternative coupon code

If your use case requires two versions of a coupon code such as an in-store and an online version, you can include both versions in your CSV file and display them in your message.

Content format for alternative code
{{#feed "couponing"}}
In-store code {{coupon_code}} or an online code {{coupon_code_alt}}

Specifying the campaign ID and feed failure behavior

Specifying the campaign ID and determining feed failure handling differs between the dashboard and API.

In the dashboard, you set both in the Delivery step of a composer in External data feed options:

  • Default value for campaign — Enter the campaign ID (not the campaign name) for the campaign you want to use for the message. The default value is the first campaign created for the project.

  • Failure behavior — Select Abort sending the message or Send message without this data.

    For most Coupons scenarios, you likely want to use Abort… since the message won’t make sense without a code and, potentially, its validity period.. Also consider how ongoing (automated and recurring) messages will be affected if you later delete their campaigns. See also: Success, Retry, and Error Conditions.

With the API, you set the campaign ID and failure (error) behavior in the External Data Feed References Object. When using a Coupons feed you must include a templates object in the payload or set the personalization option to true.

  • The value for name is couponing for all Coupons campaigns.

  • The possible values for on_error are cancel and continue. These are equivalent to the dashboard options Abort sending the message and Send message without this data.

    continue will result in sending the message despite an error. Otherwise, a feed failure will prevent Airship from sending your message.

  • To specify the campaign ID, you must include a defaults object couponing with property campaign and the campaign ID as its value.

Example push request using a Coupons feed
POST /api/push HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

      "tag": "earlyBirds"
      "alert":"{{#feed \"couponing\"}} As a token of our appreciation for being a loyal Fan, please enjoy 15% off your next in-app order. Offer expires {{dateFormat campaign_end_date locale="en-US" format="SHORT"}} Use coupon code: {{coupon_code}}{{/feed}}"
   "options": {
      "personalization": true
   "feed_references": {
      "feeds": [
            "name": "couponing",
            "params": {
            "on_error": "cancel"
      "defaults": {
         "couponing": {
            "campaign": "2023loyalty"

Managing campaigns and adding more codes

Go to Settings » Project Configuration and click Manage for Coupons to see a list of all your campaigns and their current number of available coupons. Campaigns are sorted by effective date and time, latest first.

Click   to edit the following for a campaign:

  • Name
  • Expiration date
  • Remaining codes contact — Addresses entered here will replace those entered for every campaign in the project.
  • CSV file — You can upload a new file only. You cannot download previously uploaded data.

Generally, you only need to upload a new CSV file when you want to add more codes to a campaign. You can either append rows to the original CSV file used to create the campaign and reupload it or create a new CSV file containing only rows with new codes. If creating a new file, the only required headers are coupon_code and campaign, even if a previously uploaded file contained additional headers.

You also have the option to provide a new CSV file via SFTP. Understand the differences in handling before deciding on a method:

  • If you upload a new CSV file using the dashboard, only coupon_code values will be processed. All other columns will be ignored.
  • If you upload a new CSV file via SFTP, all values (other than for campaign) will update the current campaign settings in the dashboard. For this reason, always verify that your CSV file has the correct campaign value for the campaign you intend to update.

To upload a new CSV file via SFTP, see: SFTP upload for CSV files.


Since message content is populated at send time, if you upload a new CSV file for a campaign, scheduled messages will use the most recent campaign data. They won’t necessarily use the values available when the message was created. “Scheduled” includes recurring messages.

Deleting a campaign


If you delete a campaign, any messages content referencing its data will be handled according to the messages’s feed failure behavior setting.

  1. Go to Settings » Project Configuration and click Manage for Coupons.
  2. Click   for a campaign.

Success, Retry, and Error conditions

Airship considers any 2xx response from a feed to be a success and will continue a message using the feed response. Airship considers any 3xx, 4xx, and 5xx codes (except 502/503) to be error conditions.

HTTP StatusResultBehavior
2xxSuccessAirship uses the feed response, even if empty.
3xxErrorError behavior determined by user.
4xxErrorError behavior determined by user.
5xxErrorError behavior determined by user.
timeout (60s)RetryUp to 4 retries, 60s between attempts.
502/503RetryUp to 4 retries, 60s between attempts.