Sandbox
Help

Revolut Wallet Partner Callbacks2026-07-01

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 what passes that 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

Security scheme type:mutualTLS

Mutual 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 (the passes array may be empty).
  • 202: transaction not ready yet (settlement lag); we retry, honouring Retry-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, honouring Retry-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

Header parameters
Revolut-Api-Version
stringrequired
Request-Id
string
Request body
transaction_context
objectrequired

Response

Transaction matched. Returns the outcomes it produced.

Headers
Request-Id
string
Body
object
passes
arrayrequired
post/transaction-outcomes/search
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 supplied ETag.
  • 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

Header parameters
Revolut-Api-Version
stringrequired
Request-Id
string
If-None-Match
string
Path parameters
partner_reference
stringrequired

Response

Current pass state. Excludes template_id (immutable, set at creation).

Headers
Request-Id
string
ETag
string
Body
partner_reference
stringrequired
type
stringrequired
version
integer(int64)required
relevant_at
string(date-time)
actions
array
triggers
array
type
string
semantics
objectrequired
get/passes/{partner_reference}
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"
    }
  }
}