Create boarding passes, event tickets, and loyalty cards in Revolut Wallet via the Partner API.
When a customer books a flight, buys a concert ticket, or joins a loyalty program, you want their pass in their Revolut Wallet immediately - no separate app, no manual steps.
Create a pass with a single server-to-server API call: your backend sends the semantic content and a template_id, Revolut renders the pass in the customer's wallet.
How it works
This is a server-to-server integration. Your backend calls the Revolut-hosted Partner API. Revolut validates, stores, and renders the pass in the customer's Revolut Wallet.
The customer only sees the rendered pass in the Revolut app - your business controls the content; Revolut handles the presentation.
The following components come together in this flow:
| Component | Role in this flow |
|---|---|
Partner API POST /passes | The endpoint your backend calls to create a pass |
partner_reference | Your own key for the pass (booking ref, membership number, ticket number) - you set it at creation, Revolut echoes it back |
template_id | Visual branding and layout, obtained during onboarding - included at creation, fixed thereafter |
semantics | Structured data for the pass type (passenger info, flight details, event venue, loyalty balance, etc.) |
Pass id (UUID) | Revolut-assigned identifier, returned after creation - use it to update the pass later |
Pass creation flow
- Your backend sends a
POST /passesrequest with the pass type,partner_reference,template_id, andsemantics. - Revolut validates the request and creates the pass.
- Revolut renders the pass in the customer's wallet.
- Revolut returns the pass
id(UUID) for future updates.
Before you begin
- Complete Get started to get your Partner ID, API credentials, and
template_id - Have your
partner_referenceready (booking ref, membership number, ticket number)
Create passes
This section walks through the server-to-server call to create a pass: the request structure, body parameters, and idempotency. For the full error reference, see the Partner API.
1. Call the create pass endpoint
Choose your pass type (boarding_pass, event_pass, or loyalty_pass) and provide the matching semantics. See the API reference for the full schema of each type.
POST https://partner.wallet.revolut.com/passes
Revolut-Api-Version: 2026-07-01
Idempotency-Key: {uuid}
Content-Type: application/json
{
"partner_reference": "skyjet-2241-R7K92M",
"type": "boarding_pass",
"version": 1,
"template_id": "tmpl_skyjet_boarding",
"semantics": {
"passenger": { "full_name": "Sarah Connor" },
"flight": {
"flight_number": "2241",
"carrier_code": "SJ",
"departure_airport": { "iata": "LTN" },
"arrival_airport": { "iata": "OTP" },
"scheduled_departure_at": "2026-08-02T06:15:00.000Z",
"scheduled_arrival_at": "2026-08-02T09:40:00.000Z"
},
"booking": { "pnr": "R7K92M" }
}
}Header parameters:
| Parameter | Description |
|---|---|
Revolut-Api-Version | API version of the request, e.g. 2026-07-01. |
Idempotency-Key | UUID for safe retries. See Idempotency below. |
Body parameters:
| Parameter | Description | Required |
|---|---|---|
partner_reference | Your internal key for this pass - used to match it in your system and to address it in poll-based updates and transaction results calls | Yes |
type | Determines the semantic structure - choose from boarding_pass, event_pass, or loyalty_pass | Yes |
version | Start at 1; bump on every subsequent update so Revolut can detect stale data | Yes |
template_id | Links the pass to the visual design Revolut set up for you during onboarding - fixed at creation, not accepted on updates | No - recommended |
semantics | The structured content for your chosen type (e.g. passenger + flight + booking for a boarding pass) | Yes |
relevant_at | When the pass becomes time-relevant (departure time, event start) - drives when Revolut starts polling you for updates | No |
actions | Buttons rendered on the pass (e.g. "Open website", "Get directions") | No |
triggers | Context-aware notifications (e.g. proximity alert, time before event) that nudge the customer | No |
While template_id is technically optional, we strongly recommend always including it. If omitted, Revolut falls back to the default template for your partner account, which may not match your brand.
The example above uses IATA airport codes (LTN = London Luton, OTP = Bucharest Otopeni) and a PNR (R7K92M = Passenger Name Record, the booking reference from the airline's reservation system). These are standard aviation industry identifiers.
Idempotency
Send an Idempotency-Key header (UUID) to safely retry without creating duplicate passes. Revolut matches the key against the request body to determine the outcome:
| Idempotency-Key | Request body | Result |
|---|---|---|
| Same key | Same body | Returns the original 201 response (idempotent replay) |
| Same key | Different body | Returns 409 (key reuse with mismatched payload) |
| Different key | Same body | Creates a duplicate pass (or 409 if partner_reference already exists) |
| No key | Any | Creates a pass; retries are not safe |
2. Store the returned pass identifiers
Revolut returns two identifiers in the response. Store both in your system, mapped to your internal record for this pass:
| Field | Why you need it |
|---|---|
id | Use it to push updates via PUT /passes/{id} - this is the primary address for any pass you created |
partner_reference | Revolut echoes it back so you can confirm the match. You'll also need it for poll-based updates (GET /passes/{partner_reference}) and transaction results (ref:<partner_reference> for auto-provisioned passes) |
If you lose the id, you can still address the pass by ref:<partner_reference> - but storing both avoids the indirection.
Implementation checklist
Work through these checks in order - implement, test in sandbox, then validate on production before going live.
- Complete onboarding and receive your Partner ID, credentials, and
template_id - Choose your pass type(s) and prepare the semantic content
- Set your
partner_referencescheme (booking ref, membership number, etc.) - Send a
POST /passesrequest withIdempotency-Key - Store the returned pass
idfor future updates - Test idempotency by replaying the same request
Sandbox testing:
- Create a pass in the sandbox environment and verify it renders correctly
- Replay the same request with the same
Idempotency-Keyand confirm you get the original201(not a duplicate) - Send a request with the same key but a different body and confirm you get
409 - Verify the returned
idandpartner_referencematch your expectations
Production validation before go-live:
- Create a pass against the production API and confirm it appears in a real Revolut Wallet
- Verify the pass renders with the correct template and semantic content