Endpoints you host and Revolut calls. Implement them to this contract so we can pull data on demand. Revolut is always the client; you are the server.
- Fetch transaction outcomes:
POST /transaction-outcomes/search. Called after a customer pays with a Revolut card, we ask whatpassesthat transaction produced. - Fetch a pass update:
GET /passes/{partner_reference}. We poll for the current state of a pass so we can refresh it in the customer's wallet.
Passes are identified by your own partner_reference, which is the value you set when you return a
pass here, and that Revolut echoes back when it calls the companion Revolut-hosted API
(/docs/api/revolut-wallet-partner).
The base URL in servers is illustrative; you register your real base URL during onboarding.
Start with the Revolut Wallet guide and Get started to onboard your business.
Authentication
mutualTLSMutual TLS. Revolut presents a client certificate signed by the Revolut Partner CA. Validate it against the Revolut CA chain from onboarding and reject any request without a valid Revolut certificate. Your Partner ID is bound to it. Can be used on its own, or layered on top of JWS for defence in depth.
Transaction outcomes
Return what a Revolut-card transaction produced.
Fetch transaction outcomes for a transaction
Revolut calls this after detecting a Revolut-card transaction at your business. Match the
transaction from the transaction_context and return what it produced.
Despite using POST, this is a safe lookup with no side effects: POST is used only to
carry the match criteria in the body (keeping rrn out of URLs/logs and allowing the key to
grow). No Idempotency-Key is required.
Status semantics (these drive our retry behaviour):
200: transaction matched; return the outcomes (thepassesarray may be empty).202: transaction not ready yet (settlement lag); we retry, honouringRetry-After.404: transaction definitively not found; we stop retrying.410: transaction existed but its outcome is void (refund/cancellation); we stop.429/503: temporary capacity issue; we retry, honouringRetry-After.
Validate Revolut's credentials (mTLS, JWS, or OAuth 2.0) and reject any unauthenticated request with 401.
See Auto-provision transaction results for matching logic and examples.
Request
Response
Transaction matched. Returns the outcomes it produced.
curl -X POST "https://passes.partner.example/revolut-wallet/transaction-outcomes/search" \
-H "Content-Type: application/json" \
-H "Revolut-Api-Version: string" \
-H "Request-Id: string" \
-d '{
"transaction_context": {
"rrn": "123456789012",
"merchant_id": "mer_example_01",
"transaction_at": "2026-07-01T12:00:00.000Z",
"total": {
"amount": "72.40",
"currency": "GBP"
}
}
}'Request body samples
{
"transaction_context": {
"rrn": "123456789012",
"merchant_id": "mer_example_01",
"transaction_at": "2026-07-01T12:00:00.000Z",
"total": {
"amount": "72.40",
"currency": "GBP"
}
}
}Response body samples
{
"passes": [
{
"partner_reference": "skyjet-2241-R7K92M",
"type": "boarding_pass",
"version": 1,
"template_id": "tmpl_skyjet_boarding",
"relevant_at": "2026-08-02T06:15:00.000Z",
"semantics": {
"passenger": {
"full_name": "Sarah Connor"
},
"flight": {
"flight_number": "2241",
"carrier_code": "SJ",
"departure_airport": {
"iata": "LTN",
"terminal": "1"
},
"arrival_airport": {
"iata": "OTP"
},
"scheduled_departure_at": "2026-08-02T06:15:00.000Z",
"scheduled_arrival_at": "2026-08-02T09:40:00.000Z"
},
"boarding": {
"gate": "B22",
"seat": "14C"
},
"booking": {
"pnr": "R7K92M"
}
}
}
]
}Passes
Return the current state of a pass on request.
Retrieve a pass
Return the latest state of the pass identified by partner_reference (the reference you
assigned). Revolut calls this on a schedule and on demand to refresh what the customer sees.
Support conditional requests. You generate and return an ETag header with every 200
response. It is an opaque token representing the current state of the pass. Revolut stores
it and sends it back as If-None-Match on subsequent calls. If the pass is unchanged since
that ETag, reply 304 Not Modified (no body). If it has changed, return 200 with the
full pass and a fresh ETag.
Status semantics:
200: pass returned.304: unchanged since the suppliedETag.404/410: pass gone. Revolut stops polling it.
Validate Revolut's credentials (mTLS, JWS, or OAuth 2.0) and reject any unauthenticated request with 401.
See Update a pass for the push-vs-poll model and polling cadence.
Request
Response
Current pass state. Excludes template_id (immutable, set at creation).
curl -X GET "https://passes.partner.example/revolut-wallet/passes/string" \
-H "Revolut-Api-Version: string" \
-H "Request-Id: string" \
-H "If-None-Match: string"Response body samples
{
"partner_reference": "skyjet-2241-R7K92M",
"type": "boarding_pass",
"version": 4,
"relevant_at": "2026-08-02T06:15:00.000Z",
"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"
},
"boarding": {
"gate": "C14",
"seat": "14C"
},
"booking": {
"pnr": "R7K92M"
}
}
}