Passes and Adaptive Links

Understand how to generate and distribute mobile wallet passes using the Wallet API after you’ve set up your project and templates.

Wallet generates URLs that you distribute to your users. When your audience clicks or taps an adaptive link, dynamic link, or pass URL, they can view and install a pass.

Adaptive links are vendor-agnostic, shortened links that support both Apple and Google templates. When a user taps an adaptive link, Airship determines the the platform that the user is on (Apple Wallet or Google Pay), generates the appropriate pass for that platform, and installs the pass.

In general, we recommend that you use adaptive links because they make it easier to send and install passes without having to know the platforms of the devices that you’re sending passes to. If generating event tickets or boarding passes, you must use adaptive links to generate passes.

Adaptive links also support:

  • URL-encoded pass personalization: just add query parameters to the adaptive link to personalize the passes that your users install. This can help you leverage your CRM data to populate passes without performing additional API calls.

  • Location detection: Upload locations to your project. Passes your users install from adaptive links will detect the 10 nearest locations and associate them with iOS passes. (Apple Wallet limits passes to 10 locations each.)

 Tip

You can take advantage of adaptive links even when supporting a single platform.To generate an Adaptive Link for a single platform, set the ID for the opposing template to null. If a user on the unsupported platform attempts to install your pass, you can send the user to a landing page.

Example boarding pass adaptive link payload
POST /v1/links/adaptive/multiple/project/id/<projectExternalId> HTTP/1.1
Authorization: Basic <authorization string>
Content-Type: application/json

{
  "iosTemplateExternalId": "<iosTemplateExternalId>",
  "androidTemplateExternalId": "<androidTemplateExternalId>",
  "payload": {
    "flights": [
      {
        "flightExternalId": "<flightExternalId1>",
        "fields": {
          "flightNumber": { "value": "815" },
          "airlineCode": { "value": "WN" },
          "airlineName": { "value": "Southwest Airlines" },
          "departureAirport": {
            "label": "San Francisco",
            "value": "SFO"
          },
          "departureGate": {
            "label": "Gate #",
            "value": "25"
          },
          "boardingTime": { "value": "2018-07-30T08:35:00" },
          "departureTime": { "value": "2018-07-30T09:00:00" },
          "arrivalAirport": {
            "label": "Portland",
            "value": "PDX"
          },
          "arrivalTime": { "value": "2018-07-30T11:00:00" },
          "flightStatus": { "value": "scheduled" }
        },
        "passengers": [
          {
            "adaptiveLinkExternalId": "<adaptiveLinkExternalId1>",
            "fields": {
              "seatNumber": { "value": "13A" },
              "confirmationCode": { "value": "E4583B" },
              "passengerName": { "value": "SMITH/JOE" },
              "specialAssistance": { "label": "Special Assistance", "value": "Wheelchair" },
              "barcode_value": { "value": "12345" },
              "barcodeAltText": { "value": "12345" }
            }
          },
          {
            "adaptiveLinkExternalId": "<adaptiveLinkExternalId2>",
            "fields": {
              "seatNumber": { "value": "13B" },
              "confirmationCode": { "value": "E4583B" },
              "passengerName": { "value": "SMITH/SALLY" },
              "barcode_value": { "value": "12346" },
              "barcodeAltText": { "value": "12346" }
            }
          },
          {
            "adaptiveLinkExternalId": "<adaptiveLinkExternalId2>",
            "fields": {
              "seatNumber": { "value": "13C" },
              "confirmationCode": { "value": "E4583B" },
              "passengerName": { "value": "SMITH/SAM" },
              "barcode_value": { "value": "12347" },
              "barcodeAltText": { "value": "12347" }
            }
          }
        ],
        "passGroups": ["sfo-pdx-20180730"]
      }
    ]
  }
}

 Note

You cannot personalize boarding passes or event tickets using query parameters. You must provide all values pass in the adaptive link payload object including passenger/attendee information.

When you send adaptive links, you can add query parameters to the link that will populate the pass when the user installs it.

For example: if you want to add an offer code, barcode value, member ID, and time/location to a pass, you could append query parameters to the adaptive link:

https://wallet-api.urbanairship.com/v1/pass/adaptive/QXynXTbMhS?offercode=AUGUST&barcode=A1234567&tags=PST~OR&exid=A1234567

 Tip

If you send a message using a template, you can use HandlebarsAirship’s message personalization syntax using double curly braces, more commonly known as {{handlebars}}. Use handlebars to insert variables and conditional logic in messages and templates. in the adaptive link action to automatically personalize adaptive links for your audience

 Note

You cannot personalize Google Pay class fields with unique values. Any field preceded by class constitutes a class field. See Google Pay Pass Verticals documentation for a full list of class fields for each pass type.

Updating Pass Information

After a user installs a pass, you can seamlessly update the pass as the user accrues loyalty points, uses some of their gift card balance, or event information changes, so that your users are always up to date.

By updating an already-installed pass, you help ensure that your customers never miss their gates, and that they take advantage of the loyalty programs that bring them back to your business.

When you update passes and adaptive links, you only need to provide the individual fields that you want to update.

PUT /v1/pass/12345/ HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json

{
  "fields": {
    "points": {
      "value": "98765"
    }
  }
}

Update Passes After Updating a Template

If you change your template, you can “publish” an update to your template to update passes for all of your passholders. This makes it easy to update the look and feel of your passes with a single operation. You can also update fields on your template when you publish changes, but you should take care when updating fields that might be personalized. If you update a field that has already been personalized for individual passholders, you’ll erase passholders’ personalized information when you publish changes to your template.

 Note

If you add or remove fields from a template, Airship automatically publishes your changes to relevant passes generated from a template

Learn how to publish changes to templates.

Updating Flights and Events

You can manage flights and events independently of boarding passes and event tickets respectively, making it much easier to update passholders when their flights or events change.

You can also use passGroups to update a group of flights or events — e.g. for a flight with multiple stops.

Update a flight
PUT /v1/flights/project/<projectId>/<flightId> HTTP/1.1
Authorization: Basic <authorization string>
Content-Type: application/json

{
    "fields": {
        "departureGate": {
            "value": "21"
        },
        "boardingTime": {
            "value": "2018-07-30T09:20:00"
        },
        "departureTime": {
            "value": "2018-07-30T09:45:00"
        },
        "arrivalTime": {
            "value": "2018-07-30T11:45:00"
        },
        "passGroups": [
            "sfo-pdx-20180730"
        ]
    }
}

Tags and Pass Organization

You can assign tags to passes, to organize groups of passes and passholders. You can target tags in the wallet API to change a group of passes.

Update passes by tag
PUT /v1/tag/tag-name/passes HTTP/1.1
Authorization: Basic <Base64 key>
Content-Type: application/json
Api-Revision: 1.2

{
    "fields": {
        "secondary1": {
            "value": "12/31/2013"
        },
        "primary1": {
            "value": "$2 Off"
        }
    }
}

Distributing Passes

You can distribute pass URLs over any channel you use to communicate with your audience.

It’s important to remember that you are sending a link to install a pass, not an attachment to a message body. You should send adaptive links over a medium that you expect to persist, in case your users decide to dismiss a notification alert and install the pass later.

If you are also an Airship messaging customer, you can include an adaptive link in your message. The way your audience uses an adaptive link depends on your message type:

  • When the user taps or clicks the notification.
  • When the user taps a button in the message.
  • Include the link in the the body of the message.

Send automated message with adaptive link action through Airship
POST /api/pipelines HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3;
Content-Type: application/json

{
  "name":"Ticket Purchases",
  "enabled": true,
  "immediate_trigger": [
    {
      "custom_event": {
        "key": "ticket_purchase"
      }
    }
  ],
  "outcome":{
    "push":{
      "audience": {
        "tag": "needs_ticket",
        "group": "future_passengers"
      },
      "device_types":[
        "ios",
        "android",
      ],
      "notification":{
        "alert":"Tap to install your pass!",
        "actions": {
          "open": {
            "type": "url",
            "content": "https://wallet-api.urbanairship.com/v1/pass/adaptive/<linkId>"
          }
        }
      }
    }
  }
}