Wallet passes
Orbit can issue digital passes for Apple Wallet and Google Wallet: loyalty cards, coupons, and event tickets your customers save to the wallet app on their phone. Issue them through the API or from the dashboard’s issuance builder, and deliver them by putting the pass’s save link in any message you send — SMS, WhatsApp, or email. Three pass types are supported today:- Loyalty cards — points balance, tier, or membership number behind a scannable barcode.
- Coupons — an offer with a redemption barcode and an optional expiry date.
- Event tickets — a ticket with seat, gate, or order details.
The pass lifecycle
Every pass moves through the same lifecycle:- Issue —
POST /wallet-passes/issuecreates the pass and returns both platform payloads (an Applepass.jsonstructure and a Google “Save to Wallet” link). New passes startactive. - Update —
POST /wallet-passes/:id/updatepatches an active pass’s content (points balance, tier, coupon expiry, ticket seat). Each accepted update bumps the pass’sgenerationcounter, which is the signal that the holder should refresh the pass on their phone. - Void —
POST /wallet-passes/:id/voidpermanently revokes an active pass. Voiding is terminal: a voided pass reportsstatus: "voided"and rejects any further update or re-void with a409 CONFLICTerror.
Issuing a pass
Response
idempotency_key (or an Idempotency-Key header) and a retry returns the original pass with replayed: true instead of minting a second one. The replayed response reflects the pass’s current state — so a delayed retry after an update or void never reports stale content.
Platform status
Before issuing, check which platforms are live:apple—configured: truewhen the Apple Wallet pass-type id and team id are connected. Until thenpass_jsonisnull, because there is no valid certificate identity to stamp the pass with.google—configured: truewhen the Google Wallet issuer id and service-account credentials are connected. Until thensave_urlisnull.types/barcode_formats— the enums the issuance form can offer; use these to drive your own UI validation.
Signed issuance links
Each platform has its own signing mechanism:- Apple Wallet builds the pass as a signed
.pkpassbundle: a PKCS#7 signature over a manifest of the pass files, using the Apple-issued pass signing certificate tied to your pass type. Orbit generates the unsignedpass.jsoncontent (platforms.apple.pass_json); the final binary signing step runs on the transport that holds the certificate material, once the Apple credentials are connected. - Google Wallet builds a signed “Save to Google Wallet” link (
platforms.google.save_url): the pass is wrapped in a Google generic object and encoded as an RS256-signed token appended tohttps://pay.google.com/gp/v/save/.... Opening that link on an Android device or in a browser adds the pass to the holder’s Google Wallet account.
Listing, updating, and voiding passes
List issued passes (newest first) with optional filters:generation. To clear a field, send it as explicit null.
Void a pass (optionally with a reason):
status: "voided", renders as expired in the wallet, and cannot be updated.
Example: enroll a loyalty pass from an SMS deep link
The most common onboarding flow: a customer joins your loyalty program, and you text them their wallet pass.-
Issue the pass tied to the enrolling contact:
-
Pick the save link from the response —
data.platforms.google.save_urlfor Google Wallet holders (the Apple Wallet equivalent is the signed pass the.pkpasstransport serves once Apple credentials are connected). -
Send the link over SMS using the standard messaging endpoint:
Keep the message brand-clean — save links are long, so route them through Orbit link shortening if you want a short URL. The same deep-link pattern works on SMS, WhatsApp, or email; pick whichever channel the customer opted into.
The dashboard issuance builder
Operators can run the whole lifecycle without the API. In the dashboard, open Marketing → Wallet passes (also reachable at Outbound → Wallet passes). The surface is gated to owner, admin, and developer roles.- Issue a pass — the New pass form offers exactly the pass types and barcode formats
GET /wallet-passes/platformsreports, and flags when a platform is not yet connected. - Update content — edit points, tiers, or other fields on an active pass; each accepted edit bumps the pass generation.
- Void a pass — revoke through a confirmation dialog; voided passes remain visible in the list for audit.
- Copy save links — copy the Google save link (or read the Apple payload status) to drop into a message.
How issuance state is stored
Wallet-pass state lives as events in the same append-only customer-data ledger that powers loyalty programs and incentive issuance. Issuing appends an issuance event; updates and voids append overlay events; and the current state of a pass is folded from its event stream on every read. There is no separate wallet-passes table to migrate, and nothing external to keep in sync — which is also what makes idempotent replays safe: the replayed response folds to the pass’s current lifecycle state. All wallet-pass endpoints are scoped withcontacts:read (list/get/platforms) and contacts:write (issue/update/void) — a pass is customer-facing collateral tied to a contact.