This article applies to you if you want to:

  • Take action in real-time when key events happen in PassKit.

  • Be notified when your customers install or uninstall their passes.

  • Update data in your systems when a pass is issued, installed, uninstalled or updated.

  • Feed data into your reporting database -or analytics dashboards as it happens real-time in PassKit.

  • Send an email, SMS or other form of notification to your customers when they first visit a SmartPass link and a PassKit record is created.

  • Update a pass record in PassKit when a SmartPass link is first visited, and a pass record is created. This ensures data stays in sync, and your customer views the latest data in their wallet.

So, what exactly is a webhook?

A webhook (also called a callback, or HTTP push API) is a way for an application to provide other applications with real-time data and information.

PassKit webhooks instantly deliver data to other applications, as soon as the event happens in PassKit. This is extremely powerful, and very different from typical APIs where you would need to poll data frequently to get a similar outcome.

This makes webhooks extremely efficient for both the provider and the consumer, as it refrains from generating unnecessary traffic and API calls. If setup correctly, you will only receive data that you are 'subscribed' too.

Event Types

PassKit fires off webhooks on the following events that take place in our platform. All our webhooks are sent as a HTTP POST, PUT or DELETE requests (depending on the type of webhook).

  • Pass Created (HTTP POST): fired every time a new pass record is created in the PassKit database (membership card, loyalty card, coupon, ticket, boarding pass, etc). Contains information about where and when the pass was issued.

  • Pass Installed (HTTP PUT): fired every time a user installs a pass in a Mobile Wallet. Contains information about the wallet type, IP address, and time when the pass was installed.

  • Pass Uninstalled (HTTP PUT): fired every time a user removes a pass from a Mobile Wallet. Contains information about the wallet type, IP address, and country where the pass was installed in.

  • Pass Updated (HTTP PUT): fired every time the pass record is updated in the PassKit database.

  • Pass Deleted (HTTP DELETE): fired when a pass record is deleted from the PassKit database.

See the below details for the exact request payloads that are sent. Webhooks are instant, and you can expect to receive them within seconds of the event happening. It is important that your webhook implementation returns a HTTP 200 OK response.

Pass Created

This is a useful event to use in combination with SmartPass links. Because the first time a SmartPass link is clicked, it results in a pass record being created in the PassKit database, so you can use this even to for example:

  • update the pass record with the latest record data from your system.

  • send a welcome email / SMS to your customer containing their real pass link or welcome message.

  • store the unique PassKit ID or URL against your customer record in a CRM or POS.

  • 'activate' or provision a coupon SKU in your POS or coupon software.

  • 'activate' or set a ticket as 'issued' in your ticketing system.

Payload example:

{
"event": "PASS_EVENT_RECORD_CREATED",
"pass": {
"id": "5u5EO18473CDVG0Vw0VgPV",
"classId": "24hmYozRggBJTtPt0Y2e3X",
"protocol": 100,
"personDetails": {
"displayName": "Patrick Kosterman",
"emailAddress": "patrick@passkit.com"
},
"metadata": {
"utm": {},
"issueIpAddress": "92.237.10.176",
"issueAt": {
"seconds": 1608644518,
"nanos": 743534000
}
},
"recordData": {
"design.pointsType": "int",
"members.member.externalId": "ABC123",
"members.member.points": "10.000000",
"members.member.secondaryPoints": "0.000000",
"members.member.status": "ACTIVE",
"members.member.tierPoints": "0",
"members.program.id": "24hmYozRggBJTtPt0Y2e3X",
"members.program.name": "CodeREADR Points \u0026 Tier Demo",
"members.tier.id": "bronze",
"members.tier.name": "Bronze",
"person.displayName": "Patrick Kosterman",
"person.emailAddress": "patrick@passkit.com",
"universal.issued": "2020-12-22T13:41:58Z",
"universal.optOut": "no",
"universal.status": "PASS_ISSUED"
}
}
}

Pass Installed

This is a useful event if you are tracking the pass 'status' in your own CRM or system and want to know which of your customers have installed the pass in wallet, when and in which wallet.

Payload example:

{
"event": "PASS_EVENT_INSTALLED",
"pass": {
"id": "5u5EO18473CDVG0Vw0VgPV",
"classId": "24hmYozRggBJTtPt0Y2e3X",
"protocol": 100,
"personDetails": {
"displayName": "Patrick Kosterman",
"emailAddress": "patrick@passkit.com"
},
"metadata": {
"status": 1,
"lifecycleEvents": [1, 2],
"utm": {},
"altId": "5u5EO18473CDVG0Vw0VgPV",
"issueIpAddress": "92.237.10.176",
"installIpAddress": "92.237.10.176",
"renderLocation": {
"country": "GB",
"city": "Islington",
"state": "England",
"latitude": 51.536,
"longitude": -0.0925
},
"renderIpAddress": "92.237.10.176",
"installUserAgent": "PassKitCore/1.0 CFNetwork/1206 Darwin/20.1.0",
"renderUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15",
"installDeviceAttributes": [1, 512],
"renderDeviceAttributes": [4, 128, 1024],
"issueAt": {
"seconds": 1608644518,
"nanos": 743534000
},
"renderedAt": {
"seconds": 1608644536,
"nanos": 416327000
},
"firstInstalledAt": {
"seconds": 1608644748,
"nanos": 43410000
},
"lastInstalledAt": {
"seconds": 1608644748,
"nanos": 43410000
}
},
"recordData": {
"design.pointsType": "int",
"members.member.externalId": "ABC123",
"members.member.points": "10.000000",
"members.member.secondaryPoints": "0.000000",
"members.member.status": "ACTIVE",
"members.member.tierPoints": "0",
"members.program.id": "24hmYozRggBJTtPt0Y2e3X",
"members.program.name": "CodeREADR Points \u0026 Tier Demo",
"members.tier.id": "bronze",
"members.tier.name": "Bronze",
"person.displayName": "Patrick Kosterman",
"person.emailAddress": "patrick@passkit.com",
"universal.issued": "2020-12-22T13:41:58Z",
"universal.optOut": "no",
"universal.status": "PASS_INSTALLED"
}
}
}

Pass Uninstalled

This is a useful event if you are tracking the pass 'status' in your own CRM or system and want to know which of your customers have removed the pass from their wallet.

Payload example:

{
"event": "PASS_EVENT_RECORD_UPDATED",
"pass": {
"id": "5u5EO18473CDVG0Vw0VgPV",
"classId": "24hmYozRggBJTtPt0Y2e3X",
"protocol": 100,
"personDetails": {
"displayName": "Patrick Kosterman",
"emailAddress": "patrick@passkit.com"
},
"metadata": {
"status": 2,
"lifecycleEvents": [1, 2, 1024],
"utm": {},
"altId": "5u5EO18473CDVG0Vw0VgPV",
"issueIpAddress": "92.237.10.176",
"installIpAddress": "92.237.10.176",
"renderLocation": {
"country": "GB",
"city": "Islington",
"state": "England",
"latitude": 51.536,
"longitude": -0.0925
},
"renderIpAddress": "92.237.10.176",
"installUserAgent": "PassKitCore/1.0 CFNetwork/1206 Darwin/20.1.0",
"renderUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15",
"installDeviceAttributes": [1, 512],
"renderDeviceAttributes": [4, 128, 1024],
"issueAt": {
"seconds": 1608644518,
"nanos": 743534000
},
"renderedAt": {
"seconds": 1608644536,
"nanos": 416327000
},
"firstInstalledAt": {
"seconds": 1608644748,
"nanos": 43410000
},
"lastInstalledAt": {
"seconds": 1608644748,
"nanos": 43410000
},
"firstUninstalledAt": {
"seconds": 1608645679,
"nanos": 83822000
},
"lastUninstalledAt": {
"seconds": 1608645679,
"nanos": 83822000
}
},
"recordData": {
"design.pointsType": "int",
"members.member.externalId": "ABC123",
"members.member.id": "5u5EO18473CDVG0Vw0VgPV",
"members.member.points": "100.000000",
"members.member.secondaryPoints": "0.000000",
"members.member.status": "ENROLLED",
"members.member.tierPoints": "0",
"members.program.id": "24hmYozRggBJTtPt0Y2e3X",
"members.program.name": "CodeREADR Points \u0026 Tier Demo",
"members.tier.id": "bronze",
"members.tier.name": "Bronze",
"person.displayName": "Patrick Kosterman",
"person.emailAddress": "patrick@passkit.com",
"universal.issued": "2020-12-22T13:41:58Z",
"universal.optOut": "no",
"universal.status": "PASS_UNINSTALLED"
}
}
}

Pass Updated

This is a useful event if you have implemented external applications or integrations in your processes that directly update the state of the pass record in PassKit (for example through our CodeREADr scanning integration), and you want to then propagate this change through into your CRM.

Payload example:

{
"event": "PASS_EVENT_RECORD_UPDATED",
"pass": {
"id": "5u5EO18473CDVG0Vw0VgPV",
"classId": "24hmYozRggBJTtPt0Y2e3X",
"protocol": 100,
"personDetails": {
"displayName": "Patrick Kosterman",
"emailAddress": "patrick@passkit.com"
},
"metadata": {
"status": 1,
"lifecycleEvents": [1, 2],
"utm": {},
"altId": "5u5EO18473CDVG0Vw0VgPV",
"issueIpAddress": "92.237.10.176",
"installIpAddress": "92.237.10.176",
"renderLocation": {
"country": "GB",
"city": "Islington",
"state": "England",
"latitude": 51.536,
"longitude": -0.0925
},
"renderIpAddress": "92.237.10.176",
"installUserAgent": "PassKitCore/1.0 CFNetwork/1206 Darwin/20.1.0",
"renderUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15",
"installDeviceAttributes": [1, 512],
"renderDeviceAttributes": [4, 128, 1024],
"issueAt": {
"seconds": 1608644518,
"nanos": 743534000
},
"renderedAt": {
"seconds": 1608644536,
"nanos": 416327000
},
"firstInstalledAt": {
"seconds": 1608644748,
"nanos": 43410000
},
"lastInstalledAt": {
"seconds": 1608644748,
"nanos": 43410000
}
},
"recordData": {
"design.pointsType": "int",
"members.member.externalId": "ABC123",
"members.member.id": "5u5EO18473CDVG0Vw0VgPV",
"members.member.points": "100.000000",
"members.member.secondaryPoints": "0.000000",
"members.member.status": "ENROLLED",
"members.member.tierPoints": "0",
"members.program.id": "24hmYozRggBJTtPt0Y2e3X",
"members.program.name": "CodeREADR Points \u0026 Tier Demo",
"members.tier.id": "bronze",
"members.tier.name": "Bronze",
"person.displayName": "Patrick Kosterman",
"person.emailAddress": "patrick@passkit.com",
"universal.issued": "2020-12-22T13:41:58Z",
"universal.optOut": "no",
"universal.status": "PASS_INSTALLED"
}
}
}

Setup

Webhooks are setup on a project level. It is supported to setup multiple webhooks to different endpoints for different events. The settings can be found under "Your Project" >> "Settings" >> "Integrations" >> "Webhooks":

Use our requestbin tool for testing webhooks with your projects and inspect the payloads that are sent for your particular use cases:

Webhook Request Body Explained

Main Structure

{
// The webhook event type, one of the below:
// PASS_EVENT_RECORD_CREATED
// PASS_EVENT_INSTALLED
// PASS_EVENT_RECORD_UPDATED
// PASS_EVENT_RECORD_UPDATED
"event": "PASS_EVENT_RECORD_UPDATED",
// The pass record details
"pass": {
// The unique 22 character PassKit ID.
"id": "5u5EO18473CDVG0Vw0VgPV",
// The id of the project which the pass belongs to.
"classId": "24hmYozRggBJTtPt0Y2e3X",
// The protocol, which signifies the project type.
// For a list of possible ENUM values see below.
"protocol": 100,
// PII data of the pass holder. Full object details can be found in our member -or coupon documentation in the 'person' object:
// https://docs.passkit.io/protocols/member/#operation/Members_enrolMember
"personDetails": {
"displayName": "Patrick Kosterman",
"emailAddress": "patrick@passkit.com"
...
},
// All the system generated pass meta data. Full object details can be found in our member -or coupon documentation in the 'metaData' object:
// For a list of possible ENUM values in this object see below.
"metaData": {
"status": 1,
"lifecycleEvents": [1, 2],
"utm": {},
"altId": "5u5EO18473CDVG0Vw0VgPV",
"issueIpAddress": "92.237.10.176"
...
}
// Holds protocol specific data for the pass record (e.g. tier points for Membership protocol, flight number for flight protocol)
"recordData": {
"members.member.externalId": "ABC123",
"members.member.id": "5u5EO18473CDVG0Vw0VgPV",
"members.member.points": "100.000000"
...
}
}
}

Pass Meta Data ENUM Values

PassProtocol

enum PassProtocol {
// Flights protocol: https://docs.passkit.io/protocols/boarding/
FLIGHT_PROTOCOL = 3;
// Generic Membership protocol: https://docs.passkit.io/protocols/member/
MEMBERSHIP = 100;
// Single Use Coupon protocol: https://docs.passkit.io/protocols/coupon/
SINGLE_USE_COUPON = 101;
// Event Ticket protocol: https://docs.passkit.io/protocols/event/
EVENT_TICKETING = 102;
// Values 1000 onwards are for proprietary protocols
}

Status

// Status is the best determined status of the pass.
enum Status {
// Pass has been issued.
PASS_ISSUED = 0;
// Pass has been installed in a wallet.
PASS_INSTALLED = 1;
// Pass has been uninstalled (possibly deleted) from a wallet.
PASS_UNINSTALLED = 2;
// Pass has been invalidated.
PASS_INVALIDATED = 3;
}

LifeCycleEvents

// Statuses of the pass. A pass will collect multiple statuses as it passes through its lifecycle.
enum LifecycleEvents {
NO_STATUS = 0;
// Pass has been created and presented to the user to install.
RENDERED = 0x1;
// Pass has been installed in at least one Apple device.
INSTALLED_APPLE = 0x2;
// Pass has been installed in at least one Google Pay account.
INSTALLED_GOOGLE = 0x4;
// Pass has been installed in at least one Android wallet app.
INSTALLED_ANDROID_OTHER = 0x8;
// Pass has been uninstalled from at least one Apple device.
UNINSTALLED_APPLE = 0x400;
// Pass has been uninstalled from at least one Google Pay account.
UNINSTALLED_GOOGLE = 0x800;
// Pass has been uninstalled from at least one Android wallet app.
UNINSTALLED_ANDROID_OTHER = 0x1000;
// An Apple pass bundle has been created.
APPLE_PASS_CREATED = 0x2000;
// A Google Pay record has been created.
GOOGLE_PAY_RECORD_CREATED = 0x4000;
// Invalidation request sent to pass.
INVALIDATE_REQUESTED = 0x40000;
// Pass has been invalidated.
INVALIDATE_CONFIRMED = 0x80000;
}

DeviceAttributes:

enum DeviceAttributes {
NoAttributes = 0;
Ios = 0x1;
Android = 0x2;
SupportWallet = 0x4;
WalletScanner = 0x8;
WalletDaemon = 0x10;
WalletPasses = 0x20;
Windows = 0x40;
OSX = 0x80;
Linux = 0x100;
Mobile = 0x200;
Desktop = 0x400;
Tablet = 0x800;
UnsupportedIos = 0x1000;
}

Security

If you need to whitelist our IP addresses, or need other security measures in place, please contact us about your use-case, and one of our solution engineers will contact you asap to discuss your needs.

Did this answer your question?