# Apple Wallet PassKit API

The PassKit Designer API lets you create, update, download, and manage [Apple Wallet passes](/product/messaging-channels/apple-wallet-passes/) programmatically. It supports the same operations the pass builder in the Control Panel performs. Use it to issue loyalty cards, coupons, event tickets, boarding passes, and store cards, and to push live updates to passes already installed on your users' devices.

<Aside type="note" title="Prerequisite: PassKit certificate">
Before you can create passes for an application, an iOS PassKit signing certificate must be configured for that application. The certificate is managed in the Pushwoosh Control Panel. Without it, `create` and `update` requests fail. See [Apple Wallet pass configuration for iOS](/developer/first-steps/connect-messaging-services/ios-configuration/ios-wallet-pass-configuration/).
</Aside>

## Base URL

```
https://apple-passkit.svc-nue.pushwoosh.com
```

All endpoints are served over HTTPS. Requests and responses use `application/json` unless noted otherwise.

## Authentication

Every request must include an `Authorization` header with your [Pushwoosh API access token](/developer/api-reference/api-access-token/):

```
Authorization: Token <api-token>
```

The account that owns the token must own the application referenced by `applicationCode`. A request for an application that belongs to another account returns `403 Forbidden`.

## Conventions

* **Field naming:** JSON fields use `lowerCamelCase` (for example, `passTypeIdentifier`, `serialNumber`, `backgroundColor`).
* **Unpopulated fields:** responses include all fields, even when empty or zero-valued.
* **Binary data:** `bytes` fields such as `pkpassData` and image `data` are Base64-encoded strings in JSON.
* **Serial numbers:** the `serialNumber` is always assigned by the server when a pass is created. Any value you send on create is ignored; it identifies the pass for all later operations.

### Error responses

The API maps internal status codes to HTTP status codes:

| HTTP status | Meaning |
| :---- | :---- |
| `400 Bad Request` | Invalid argument—a required field is missing or malformed. |
| `401 Unauthorized` | Missing or invalid `Authorization` header. |
| `403 Forbidden` | The application does not belong to the caller's account. |
| `404 Not Found` | The pass, template, or application was not found. |
| `503 Service Unavailable` | The service is at capacity or temporarily unavailable. |

## Endpoints

| Method | Path | Description |
| :---- | :---- | :---- |
| `POST` | `/api/pass/validate` | Validate a pass configuration |
| `POST` | `/api/pass/create` | Create a new `.pkpass` |
| `POST` | `/api/pass/update/{serialNumber}` | Update an existing pass and notify devices |
| `GET` | `/api/passes` | List all passes for an application |
| `GET` | `/api/pass/{applicationCode}/{serialNumber}` | Get a single pass |
| `GET` | `/api/pass/{applicationCode}/{serialNumber}/download` | Download the `.pkpass` of an existing pass |
| `DELETE` | `/api/pass/{applicationCode}/{serialNumber}` | Delete a pass |
| `GET` | `/api/pass/{serialNumber}/registrations` | List devices registered for a pass |
| `GET` | `/api/config` | Get the application's PassKit configuration |
| `GET` | `/api/templates` | List available pass templates |
| `GET` | `/api/templates/{filename}` | Get a single template |


## Create a pass

Generates, signs, and stores a new pass, then returns its server-assigned serial number. 

`POST` `/api/pass/create`

<Aside type="tip">
To obtain the `.pkpass` file itself, call [Download a pass](#download-a-pass) (or build an [install link / QR code](#share-a-pass-as-a-qr-code)) with the returned serial.
</Aside>


### Request body

| Parameter | Type | Required | Description |
| :---- | :---- | :---- | :---- |
| `pass` | object | Yes | The [pass object](#pass-object) describing the pass. |
| `images` | array of objects | No | [Pass images](#pass-image-object) (icon, logo, etc.). `icon` and `logo` are required for a valid pass. |
| `userId` | string | Yes | The Pushwoosh User ID the pass is issued to. |
| `applicationCode` | string | Yes | The [Pushwoosh application code](/developer/api-reference/api-identifiers/#application-code). |

<Aside type="note">
On create, if `teamIdentifier`, `passTypeIdentifier`, or `organizationName` are omitted, they default to the values from the application's configured certificate. `formatVersion` defaults to `1`. The `serialNumber` is assigned server-side.
</Aside>

##### Request example

```json
{
  "applicationCode": "XXXXX-XXXXX",
  "userId": "user-123",
  "pass": {
    "description": "Acme loyalty card",
    "logoText": "Acme",
    "backgroundColor": "rgb(60, 65, 76)",
    "foregroundColor": "rgb(255, 255, 255)",
    "labelColor": "rgb(255, 255, 255)",
    "storeCard": {
      "primaryFields": [
        { "key": "balance", "label": "BALANCE", "value": "1200 pts" }
      ],
      "secondaryFields": [
        { "key": "member", "label": "MEMBER", "value": "Jane Doe" }
      ]
    },
    "barcodes": [
      {
        "format": "PKBarcodeFormatQR",
        "message": "1234567890",
        "messageEncoding": "iso-8859-1"
      }
    ]
  },
  "images": [
    { "imageType": "icon", "data": "<base64>", "contentType": "image/png" },
    { "imageType": "logo", "data": "<base64>", "contentType": "image/png" }
  ]
}
```

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `serialNumber` | string | Server-assigned unique identity of the created pass. Use it to fetch the pass ([Get a pass](#get-a-pass)) or download the `.pkpass` ([Download a pass](#download-a-pass)). |
| `message` | string | Result message. |

##### Response example

```json
{
  "serialNumber": "a1b2c3d4-1234-5678-9abc-def012345678",
  "message": "Pass created successfully"
}
```

## Validate a pass

Checks a pass configuration against Apple's specifications without creating a file. Useful before calling create.

`POST` `/api/pass/validate`

### Request body

| Parameter | Type | Required | Description |
| :---- | :---- | :---- | :---- |
| `pass` | object | Yes | The [pass object](#pass-object) to validate. |

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `valid` | boolean | Whether the pass passes validation. |
| `errors` | array of strings | Blocking problems that must be fixed. |
| `warnings` | array of strings | Non-blocking advisories. |



## Update a pass

Regenerates the pass with new content, re-signs it, increments its update tag, and sends a **silent push notification** to every device that registered the pass. iOS then fetches and installs the updated version in the background.

`POST` `/api/pass/update/{serialNumber}`

### Path parameters

| Parameter | Type | Description |
| :---- | :---- | :---- |
| `serialNumber` | string | The serial number returned when the pass was created. |

### Request body

| Parameter | Type | Required | Description |
| :---- | :---- | :---- | :---- |
| `updates` | object | Yes | The full [pass object](#pass-object) with the new content. |
| `applicationCode` | string | Yes | The Pushwoosh application code. |

The `serialNumber` (from the path) and the pass's authentication token are preserved by the server regardless of what you send.

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `success` | boolean | Whether the update succeeded. |
| `updateTag` | integer | New update tag (a Unix timestamp). |
| `message` | string | Result message. |



## List passes

Returns a paginated, sorted list of the passes stored for an application.

`GET` `/api/passes?applicationCode=XXXXX-XXXXX&page=0&perPage=20`

### Query parameters

| Parameter | Type | Required | Description |
| :---- | :---- | :---- | :---- |
| `applicationCode` | string | Yes | The Pushwoosh application code. |
| `orderBy` | string | No | Sort field: `UPDATED` (default) or `CREATED`. |
| `orderDirection` | string | No | Sort direction: `DESC` (default, newest first) or `ASC`. |
| `page` | integer | No | Zero-based page index. Defaults to `0`. |
| `perPage` | integer | No | Page size. `0` or omitted uses the server default. |

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `passes` | array of objects | The current page of [pass records](#pass-record-object). |
| `page` | integer | The returned page index. |
| `perPage` | integer | The page size used for this response. |
| `total` | integer | Total number of passes for the application across all pages. |

##### Response example

```json
{
  "passes": [ /* pass records */ ],
  "page": 0,
  "perPage": 20,
  "total": 137
}
```


## Get a pass

Returns a single stored pass, including its full pass object.

`GET` `/api/pass/{applicationCode}/{serialNumber}`

### Path parameters

| Parameter | Type | Description |
| :---- | :---- | :---- |
| `applicationCode` | string | The Pushwoosh application code. |
| `serialNumber` | string | The pass serial number. |

### Response

Returns `{ "pass": { ... } }`, a single [pass record](#pass-record-object).


## Download a pass

Returns the stored `.pkpass` file of an existing pass.

`GET` `/api/pass/{applicationCode}/{serialNumber}/download`

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `pkpassData` | string (Base64) | The `.pkpass` file. |
| `filename` | string | Suggested file name. |


## Delete a pass

Removes a pass record and its stored `.pkpass` file.

`DELETE` `/api/pass/{applicationCode}/{serialNumber}`

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `success` | boolean | Whether the pass was deleted. |
| `message` | string | Result message. |



## Get pass registrations

Lists the devices that have added the pass and are registered for updates.

`GET` `/api/pass/{serialNumber}/registrations?applicationCode=XXXXX-XXXXX`

### Response

Returns `{ "registrations": [ ... ] }`, where each item has:

| Field | Type | Description |
| :---- | :---- | :---- |
| `deviceLibraryIdentifier` | string | Apple device library identifier. |
| `pushToken` | string | The pass push token for the device. |



## Get configuration

Returns the PassKit configuration resolved for an application from its certificate.

`GET` `/api/config?applicationCode=XXXXX-XXXXX`

### Response

| Field | Type | Description |
| :---- | :---- | :---- |
| `teamIdentifier` | string | Apple Team ID from the certificate. |
| `passTypeIdentifier` | string | Pass Type ID from the certificate. |
| `organizationName` | string | Organization name from the certificate. |
| `hasCertificate` | boolean | Whether a certificate is configured. |
| `webServiceUrl` | string | Base URL of the pass web service. Clients build an install link by appending `/v1/passes/{passType}/{serial}?token={authToken}`. |



## Templates

List the available pass templates, or fetch one as a [pass object](#pass-object) you can use as a starting point.

`GET` `/api/templates` — returns `{ "templates": [ { "filename", "name", "description", "style" } ] }`.

`GET` `/api/templates/{filename}` — returns `{ "template": { ...pass object... } }`.



## Share a pass as a QR code

To let users add a pass by scanning a QR code (or tapping a link), encode the pass **install URL** into a QR code. The URL is built from values you already get back from the API:

```
{webServiceUrl}/v1/passes/{passTypeIdentifier}/{serialNumber}?token={authenticationToken}
```

| URL part | Where to get it |
| :---- | :---- |
| `webServiceUrl` | [`GET /api/config`](#get-configuration) → `webServiceUrl` |
| `passTypeIdentifier` | [pass record](#pass-record-object) → `pass.passTypeIdentifier` (from list/get) |
| `serialNumber` | [pass record](#pass-record-object) → `serialNumber` |
| `authenticationToken` | [pass record](#pass-record-object) → `pass.authenticationToken` |

Example:

```
https://apple-passkit.svc-nue.pushwoosh.com/v1/passes/pass.com.acme.loyalty/a1b2c3d4-1234-5678-9abc-def012345678?token=AbC123XyZ
```

Render this URL as a QR code with any QR library. When a user scans it, their device opens the link, downloads the latest `.pkpass`, and Wallet prompts them to add it—which also registers the device for updates.



## Object reference

### Pass object

| Field | Type | Description |
| :---- | :---- | :---- |
| `formatVersion` | integer | Pass format version. Defaults to `1`. |
| `passTypeIdentifier` | string | Apple Pass Type ID (`pass.com.yourcompany.passtype`). Defaults from the certificate. |
| `serialNumber` | string | Assigned by the server on create; identifies the pass. |
| `teamIdentifier` | string | Apple Team ID. Defaults from the certificate. |
| `organizationName` | string | Organization shown on the pass. Defaults from the certificate. |
| `description` | string | Human-readable description (required by Apple). |
| `boardingPass` / `coupon` / `eventTicket` / `storeCard` / `generic` | object | The pass style. **Exactly one** must be set. See [field groups](#field-group-object). |
| `backgroundColor` | string | Background color, `rgb(r, g, b)`. |
| `foregroundColor` | string | Foreground (text) color, `rgb(r, g, b)`. |
| `labelColor` | string | Field label color, `rgb(r, g, b)`. |
| `logoText` | string | Text shown next to the logo. |
| `suppressStripShine` | boolean | Disable the shine effect on the strip image. |
| `barcodes` | array | [Barcodes](#barcode-object) shown on the pass. |
| `locations` | array | [Locations](#location-object) that make the pass relevant. |
| `beacons` | array | [Beacons](#beacon-object) that make the pass relevant. |
| `relevantDate` | string | ISO 8601 date when the pass becomes relevant. |
| `maxDistance` | integer | Max distance (meters) for location relevance. |
| `expirationDate` | string | ISO 8601 expiration date. |
| `voided` | boolean | Marks the pass as void. |
| `groupingIdentifier` | string | Groups related passes (event tickets/boarding passes). |
| `userInfo` | object (map) | Arbitrary key/value app data. |

<Aside type="note">
`authenticationToken` and `webServiceUrl` are managed by the service and don't need to be set by API clients.
</Aside>

### Field group object

Each pass style (`boardingPass`, `coupon`, `eventTicket`, `storeCard`, `generic`) groups [fields](#field-object) into areas:

| Field | Type | Description |
| :---- | :---- | :---- |
| `headerFields` | array | Shown in the pass header (visible when stacked in Wallet). |
| `primaryFields` | array | Most prominent fields. |
| `secondaryFields` | array | Below the primary fields. |
| `auxiliaryFields` | array | Additional fields below secondary. |
| `backFields` | array | Shown on the back of the pass. |

`boardingPass` additionally has `transitType` (`PKTransitTypeAir`, `PKTransitTypeTrain`, `PKTransitTypeBus`, `PKTransitTypeBoat`, or `PKTransitTypeGeneric`).

### Field object

| Field | Type | Description |
| :---- | :---- | :---- |
| `key` | string | Unique field key within the pass. |
| `label` | string | Field label. |
| `value` | string | Field value (text or number as string). |
| `changeMessage` | string | Message shown when the value changes (use `%@` as the placeholder). |
| `textAlignment` | string | `PKTextAlignment` value. |
| `dateStyle` / `timeStyle` | string | `PKDateStyle` for date/time formatting. |
| `isRelative` | boolean | Show the date relative to now. |
| `numberStyle` | string | `PKNumberStyle` for number formatting. |
| `currencyCode` | string | ISO 4217 currency code. |
| `dataDetectorTypes` | array of strings | Data detectors to apply to the value. |

### Barcode object

| Field | Type | Description |
| :---- | :---- | :---- |
| `format` | string | `PKBarcodeFormatQR`, `PKBarcodeFormatPDF417`, `PKBarcodeFormatAztec`, or `PKBarcodeFormatCode128`. |
| `message` | string | Data encoded in the barcode. |
| `messageEncoding` | string | Text encoding, typically `iso-8859-1`. |
| `altText` | string | Text shown below the barcode. |

### Location object

| Field | Type | Description |
| :---- | :---- | :---- |
| `latitude` | number | Latitude. |
| `longitude` | number | Longitude. |
| `altitude` | number | Altitude in meters. |
| `relevantText` | string | Text shown on the lock screen near this location. |

### Beacon object

| Field | Type | Description |
| :---- | :---- | :---- |
| `proximityUuid` | string | iBeacon proximity UUID. |
| `major` | integer | Major value. |
| `minor` | integer | Minor value. |
| `relevantText` | string | Text shown on the lock screen near this beacon. |

### Pass image object

| Field | Type | Description |
| :---- | :---- | :---- |
| `imageType` | string | One of `icon`, `logo`, `strip`, `background`, `footer`, `thumbnail`. `icon` and `logo` are required. |
| `data` | string (Base64) | Image bytes. |
| `contentType` | string | MIME type, for example `image/png`. |

### Pass record object

Returned by list/get endpoints.

| Field | Type | Description |
| :---- | :---- | :---- |
| `serialNumber` | string | Pass serial number. |
| `passTypeIdentifier` | string | Pass Type ID. |
| `organizationName` | string | Organization name. |
| `description` | string | Pass description. |
| `createdAt` | string | Creation timestamp (RFC 3339). |
| `updatedAt` | string | Last update timestamp (RFC 3339). |
| `updateTag` | integer | Current update tag. |
| `pass` | object | The full [pass object](#pass-object), for editing. |
| `userId` | string | Pushwoosh User ID the pass was issued to. |