Flights and Boarding Passes

Managing boarding passes in a wallet project involves some unique differences from other pass types. This document covers information about flights, passengers, and boarding passes.

 Note

While you can create and modify boarding pass templates from the dashboard, all other operations — flight creation, creating adaptive links with flight and passenger information, etc. — are performed through the API.

Boarding Pass Composition

A boarding pass is an Adaptive LinkA vendor-agnostic, shortened mobile wallet pass link that supports templates for both Google Wallet and Apple Wallet. When a user taps the link, Airship determines the user’s platform and generates the right pass for that platform. that references a boarding pass template, populated with one or more flights and one or more passengers per flight.

While boarding passes resemble adaptive links for other pass types, you cannot create a boarding pass using the standard dashboard or /links/adaptive methods. You must use the /links/adaptive/multiple/project endpoints instead.

A boarding pass works much like a standard adaptive link, with the following differences.

  • Boarding pass templates are referenced by ID. You must include at least one of iosTemplate or googleTemplate (or external ID equivalents iosTemplateExternalId, androidTemplateExternalId) in an adaptive link payload.

  • The adaptive link payload references a flightId, flightExternalId, or contains a complete flight object.

  • Each flight in a boarding pass adaptive link request includes an array of passengers. The request generates an adaptive link for each passenger in the array.

  • Assets referenced by ID (templates, flights, etc.) must belong to the same project; you cannot use combinations of flights or templates across projects to create a boarding pass.

Flights

You can create flights either:

  • Using the POST method for the /flights endpoint. The /flights endpoint is a convenient way to create and modify flight information, independent of adaptive links and passholders.

  • By providing a flight payload when creating adaptive links.

In both cases, the result of your request is a flightId or flightExternalIdthat you can use to reference the event — either to create boarding passes or to modify flight information from the /flights endpoint.

Any changes you make to an flight — moving the gate, changing departure or arrival times, etc. — automatically propagate to boarding passes (adaptive links) that reference the flight.

Flight request example
POST /v1/flights/project/<projectId> HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json

{
    "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"
        }
    },
    "passGroups": [
        "sfo-pdx-20180730"
    ]
}

External IDs for Flights

You can create a flight with a custom identifier using the /v1/flights/project/id/{projectExternalId}/id/{flightExternalId} endpoint. A request specifying an external flight ID returns the custom identifier as flightExternalId, and you reference flights using this external identifier in lieu of the standard flightId in subsequent payloads, including the request to create boarding pass adaptive links.

Pass Groups for Flights and Boarding Passes

You can group flights together, so that you can modify multiple flights simultaneously — something you might need to do for flights with multiple stops.

To do this, you can assign flights to passGroups — plain text strings, similar to tags for passes. You can assign pass groups in any payload where you create a flight or after you create a flight using /passgroups endpoints.

Add a pass group to an existing flight with an external ID
POST /v1/flights/project/id/<projectExternalId>/id/<flightExternalId>/passGroups HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json

{
  "passGroups" :["sfo-pdx-20180730", "pdx-yvr-20180730"]
}

You can then return a list of all flights bearing the passGroup string, or modify the group. When you modify a pass group, you only need to provide the individual fields that you want to update for all flights in the pass group. Any passes generated from flights in the group are automatically updated accordingly.

Update all flights in a pass group
PUT /v1/flights/project/12345/passGroups/sfo-pdx-20180730 HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json

{
  "fields": {
    "departureTime": {
      "value": "2018-08-30T10:00:00"
    }
  }
}

Passengers

The passengers array represents passholders. Each object in the array is an individual passholder and results in adaptive link. The passengers array appears within a flight object when creating boarding passes.

Example boarding pass request with an array of passengers
{
  "iosTemplateExternalId": "boardingPass-ios",
  "androidTemplateExternalId": "boardingPass-android",
  "payload":{
    "flights":[
      {
        "flightExternalId": "sfo-tac-2018-08-30",
        "passengers": [
          {
            "fields": {
              "passengerName": { "value": "SMITH/JOE" },
              "seatNumber": { "value": "13A" },
              "seatClass": { "value": "Economy" },
              "boardingGroup": { "value": "5" },
              "securityProgram": { "value": "tsaPrecheck" },
              "confirmationCode": { "value": "E4583B" },
              "eticketNumber": { "value": "20595923485" },
              "frequentFlyerProgramName": { "value": "Rapid Rewards®" },
              "frequentFlyerNumber": { "value": "34525" },
              "drinkCoupon":  { "label": "Drink Coupon", "value": "Premium Drink" },
              "fareType": { "label": "Fare Type", "value": "Business Select" },
              "specialAssistance": { "label": "Special Assistance", "value": "Wheelchair" }
            }
          }
        ]
      }
    ]
  }
}

Google Wallet Boarding Pass Templates

Google boarding pass templates are not as customizable as other template types. Many of the fields on a boarding pass are required, like seat number, gate number, etc. These fields cannot have default values, nor can they be moved or customized in any way.

You can set colors, logos, and otherwise customize the general feel of your boarding pass. But with boarding passes, more so than other pass types, you will focus less on templates, and much more on modifying the information that populates adaptive links built from those templates.

 Important

The flight information you enter when creating your template is only to help you design your template and send test passes; it is overwritten by a flight object when you create boarding passes. See the Boarding Pass Request object for information about the flight object or ID you must provide when creating passes.

 Note

The Google Wallet boarding pass type supports airline boarding passes only. It does not support ferry, bus, or train tickets.

Apple Wallet Boarding Pass Templates

While flight and passenger fields are native to Google Wallet templates, they are not native to Apple Wallet templates. You must name fields on your Apple Wallet template according to the flight and passenger schemas to support event ticket adaptive links. See Flight and Boarding Pass Objects for a complete list of the field names your template should use.

  • If you create your Apple Wallet Boarding Pass template through the dashboard: you must rename fields on your template to match flight and passenger object fields through the API.
  • If you create your Apple Wallet Boarding Pass template through the API: you must name fields identically to flight and passenger objects.
 Important

The flight information you enter when creating your template is only to help you design your template and send test passes; it is overwritten by a flight object when you create boarding passes. See the Boarding Pass Request object for information about the flight object or ID you must provide when creating passes.

 Note

For date-time fields on iOS boarding pass templates, you may want to set set ignoresTimeZone: true. Date-times for flights are set local to an airport terminal. Setting ignoresTimeZone: true prevents Apple Wallet from modifying times based on recipients’ time zones.

Example default Apple Wallet field names and supported boarding pass equivalents

Default field nameRename field to
SeatseatNumber
Depart TimedepartureTime
Departure AirportdepartureAirport
ClassseatClass
Arrival AirportarrivalAirport
PassengerpassengerName
Ticket #eticketNumber
Terminal GatedepartureTerminal
Flight #flightNumber

A boarding pass adaptive link is an adaptive link that generates or returns platform-appropriate passes of the boarding pass type. It is created from boarding pass templates and associated with flights and passengers.

 Note

You must use the /links/adaptive/multiple/project/ endpoints to create boarding passes. While a boarding pass adaptive link has a similar request structure to other adaptive links, you cannot create boarding pass adaptive links through the standard /links/adaptive endpoint.

When you create an adaptive link, you can specify flights by flightId — the identifier from a successful POST to the /flights endpoint. Templates and flights referenced by ID must belong to the same project.

Within each flight, you will specify passengers — an array of objects, each object representing an individual passenger with information like their seat number, boarding group, etc.

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

{
  "availablePasses": 1,
  "iosTemplateExternalId": "<iosTemplateExternalId>",
  "androidTemplateExternalId": "<androidTemplateExternalId>",
  "payload": {
    "isEventTicketUpdatePermitted": false,
    "flights": [
      {
        "flightId": "<flightId1>",
        "passengers": [
          {
            "adaptiveLinkExternalId": "<adaptiveLinkExternalId1>",
            "fields": {
              "seatNumber": { "value": "13A" },
              "confirmationCode": { "value": "E4583B" },
              "passengerName": { "value": "SMITH/JOE" },
              "specialAssistance": { "label": "Special Assistance", "value": "Wheelchair" }
            }
          },
          {
            "adaptiveLinkExternalId": "<adaptiveLinkExternalId2>",
            "fields": {
              "seatNumber": { "value": "13B" },
              "confirmationCode": { "value": "E4583B" },
              "passengerName": { "value": "SMITH/SALLY" }
            }
          },
          {
            "adaptiveLinkExternalId": "<adaptiveLinkExternalId2>",
            "fields": {
              "seatNumber": { "value": "13C" },
              "confirmationCode": { "value": "E4583B" },
              "passengerName": { "value": "SMITH/SAM" }
            }
          }
        ]
      }
    ]
  }
}
Adaptive link response
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

[
  {
      "status": 201,
      "adaptiveLinkId": "<uaAdaptiveLinkId1>",
      "adaptiveLinkExternalId": "<adaptiveLinkExternalId1>",
      "iosTemplateId": "<iosTemplateId>",
      "iosTemplateExternalId": "<iosTemplateExternalId>",
      "androidTemplateId": "<androidTemplateId>",
      "androidTemplateExternalId": "<androidTemplateExternalId>",
      "url": "https://wallet-api.urbanairship.com/v1/pass/<adaptiveLinkSerialNumber1>",
      "iosUrl": "https://wallet-api.urbanairship.com/v1/pass/<adaptiveLinkSerialNumbe1r>/ios",
      "androidUrl": "https://wallet-api.urbanairship.com/v1/pass/<adaptiveLinkSerialNumber1>/android",
      "createdAt": "2018-07-05T09:12:32Z",
      "updatedAt": "2018-07-05T09:12:32Z",
      "isPersonalized": "false",
      "availablePasses": 1000000,
      "flightId": 465,
      "flightExternalId": "<flightExternalId1>",
      "iosPassLinkId": "eb94e8e0-4353-4e0b-bfe9-cfd21c52a540",
      "androidPassLinkId": "41c1ea48-f469-4968-b610-a98629ea19bc"
  }
]

Modifying Flights and Passengers

Any endpoint supporting a flight payload will return a flightId. You can look up, modify, or delete a flight using this ID in the path of the /v1/flights endpoint, regardless of whether you created the flight using the /v1/flights endpoint or provided all flight information directly in an adaptive link payload.

If you assigned your flights to Pass GroupsGroups of flights or events that you can modify in bulk. You can assign events or flights to one or more pass groups when you create them. , you can target the pass group to modify a common field across multiple flights in a group. For example, if you need to update departureTime for a group of flights, you could target the group and with a single update rather than updating each flight individually. When you update flights in a pass group, boarding passes associated with flights in the group are all updated accordingly.

Modify all flights belonging to a pass group
PUT /v1/flights/project/12345/passGroups/sfo-pdx-20180730 HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json

{
  "fields": {
    "departureTime": {
      "value": "2018-08-30T10:00:00"
    }
  }
}

Passenger objects exist on adaptive links (boarding passes). If you want to modify passengers on a flight (if a passenger moves seats, or cancels their ticket), you will do so by modifying adaptive links directly.

You can also modify a flight at the same time you modify corresponding boarding passes, using a POST to /v1/links/adaptive/multiple/project/id/{externalProjectId} specifying both an existing flight and the existing adaptiveLinkExternalId for the boarding passes you want to modify in the payload

Modifying, Looking-up, and Deleting Boarding Passes

You can modify boarding passes using a POST to /v1/links/adaptive/multiple/project/id/{externalProjectId} specifying both an existing flight and the existing adaptiveLinkExternalId for the boarding passes you want to modify in the payload; Airship treats this call as a PUT and updates boarding passes for the specified adaptive links. You cannot do the same with standard adaptiveLinkId. Therefore, you should expect to set external IDs for your adaptive links.

You can look up and delete boarding pass adaptive links using the standard GET and DELETE methods for the /v1/links/adaptive/{adaptiveLinkId} and /v1/links/adaptive/id/{adaptiveLinkExternalId} endpoints.