openapi: 3.1.0
info:
  title: Revolut Wallet Partner Callbacks
  version: 2026-07-01
  description: |
    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.

    :::info
    Start with the [Revolut Wallet guide](https://developer.revolut.com/docs/guides/revolut-wallet/introduction) and [Get started](https://developer.revolut.com/docs/guides/revolut-wallet/get-started) to onboard your business.
    :::
  contact:
    name: Revolut Wallet partner onboarding
    email: revwallet-partner-onboarding@revolut.com
servers:
  - url: https://passes.partner.example/revolut-wallet
    description: Your registered base URL (example)
security:
  - mtls: []
  - mtls: []
    jws: []
  - jws: []
  - oauth2:
      - passes.read
  - oauth2:
      - passes.read
    mtls: []
tags:
  - name: Transaction outcomes
    description: Return what a Revolut-card transaction produced.
  - name: Passes
    description: Return the current state of a pass on request.
paths:
  /transaction-outcomes/search:
    post:
      tags:
        - Transaction outcomes
      operationId: searchTransactionOutcomes
      summary: Fetch transaction outcomes for a transaction
      description: |
        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`.

        :::note
        Validate Revolut's credentials (mTLS, JWS, or OAuth 2.0) and reject any unauthenticated request with `401`.
        :::

        :::info
        See [Auto-provision transaction results](https://developer.revolut.com/docs/guides/revolut-wallet/operations/transaction-results) for matching logic and examples.
        :::
      parameters:
        - $ref: "#/components/parameters/ApiVersion"
        - $ref: "#/components/parameters/RequestId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TransactionOutcomesSearchRequest"
            examples:
              lookup:
                value:
                  transaction_context:
                    rrn: "123456789012"
                    merchant_id: mer_example_01
                    transaction_at: 2026-07-01T12:00:00.000Z
                    total:
                      amount: "72.40"
                      currency: GBP
      responses:
        "200":
          description: Transaction matched. Returns the outcomes it produced.
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionOutcomes"
              examples:
                boarding_pass:
                  summary: A single boarding pass produced by the transaction
                  value:
                    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
                none:
                  summary: Transaction matched, but produced no passes
                  value:
                    passes: []
        "202":
          description: >
            Transaction accepted but its outcome is not ready yet (settlement
            lag). Revolut retries,

            honouring `Retry-After`.


            :::note

            Return no body with `202`.

            :::
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
            Retry-After:
              $ref: "#/components/headers/RetryAfter"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: Transaction definitively not found. Revolut will stop retrying.
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                transaction_not_found:
                  value:
                    code: transaction_not_found
                    message: No transaction found for this rrn and merchant_id.
        "410":
          description: Transaction outcome is void (refund/cancellation). Revolut will
            stop retrying.
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                transaction_void:
                  value:
                    code: transaction_void
                    message: The transaction outcome is void due to a refund or cancellation.
        "429":
          $ref: "#/components/responses/TooManyRequests"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
  /passes/{partner_reference}:
    get:
      tags:
        - Passes
      operationId: fetchPass
      summary: Retrieve a pass
      description: |
        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.

        :::note
        Validate Revolut's credentials (mTLS, JWS, or OAuth 2.0) and reject any unauthenticated request with `401`.
        :::

        :::info
        See [Update a pass](https://developer.revolut.com/docs/guides/revolut-wallet/operations/update-pass) for the push-vs-poll model and polling cadence.
        :::
      parameters:
        - $ref: "#/components/parameters/ApiVersion"
        - $ref: "#/components/parameters/RequestId"
        - name: partner_reference
          in: path
          required: true
          description: >
            Your own reference for the pass, as set when you created it (Partner
            API `POST /passes`)

            or returned in a transaction-outcomes response. Send the **bare
            value** here — do not use

            the `ref:` prefix (that form is only for the Partner API `PUT
            /passes/{id}`).
          schema:
            type: string
            maxLength: 128
          examples:
            - skyjet-2241-R7K92M
        - name: If-None-Match
          in: header
          required: false
          description: >
            An `ETag` previously returned by your `200` response to this
            endpoint. Revolut sends it

            back so you can skip re-sending an unchanged pass. Return `304 Not
            Modified` if the

            pass state is the same as when you issued this `ETag`.
          schema:
            type: string
          examples:
            - '"v3"'
      responses:
        "200":
          description: >
            Current pass state. Excludes `template_id` (immutable, set at
            creation).
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
            ETag:
              $ref: "#/components/headers/ETag"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PassUpdate"
              examples:
                boarding_pass:
                  summary: A boarding pass with updated gate
                  value:
                    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
        "304":
          description: Pass unchanged since the supplied `ETag`.
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
            ETag:
              $ref: "#/components/headers/ETag"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: Pass not found. Revolut stops polling it.
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                pass_not_found:
                  value:
                    code: pass_not_found
                    message: No pass found for this partner_reference.
        "410":
          description: Pass permanently gone. Revolut stops polling it.
          headers:
            Request-Id:
              $ref: "#/components/headers/RequestId"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                pass_void:
                  value:
                    code: pass_void
                    message: The pass has been voided or refunded.
        "429":
          $ref: "#/components/responses/TooManyRequests"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
components:
  securitySchemes:
    mtls:
      type: mutualTLS
      description: >
        **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.
    jws:
      type: apiKey
      in: header
      name: Jws-Signature
      description: >
        **Message signing (JWS).** Revolut signs the request body together with
        a timestamp (to

        prevent replay) as a detached JWS (`RS256`/`ES256`) using the Revolut
        Partner signing key

        whose certificate you registered during onboarding, and sends the
        compact JWS in the

        `Jws-Signature` header. You verify it against the registered Revolut
        certificate. May be

        used on its own or together with mTLS.
    oauth2:
      type: oauth2
      description: >
        OAuth 2.0 **client credentials**. Revolut requests a short-lived access
        token from your

        token endpoint (authenticating with its onboarding credential:
        `client_secret`,

        `private_key_jwt`, or its mTLS certificate) and sends it as
        `Authorization: Bearer <token>`.

        The token carries the `passes.read` scope. May be used on its own or
        together with mTLS.
      flows:
        clientCredentials:
          tokenUrl: https://your-token-endpoint.example/oauth/token
          scopes:
            passes.read: Read transaction outcomes and pass state.
  parameters:
    ApiVersion:
      name: Revolut-Api-Version
      in: header
      required: true
      description: |
        Contract version Revolut is calling with, e.g. `2026-07-01`.

        :::note
        If you receive a version you do not implement, respond with `400`.
        :::
      schema:
        type: string
        pattern: ^\d{4}-\d{2}-\d{2}$
      examples:
        - 2026-07-01
    RequestId:
      name: Request-Id
      in: header
      required: false
      description: Revolut's correlation id for this request. Echo it back in your response.
      schema:
        type: string
      examples:
        - 01970c4c-5790-7fb5-8331-84dfa075bbe9
  headers:
    RequestId:
      description: Correlation id for the response. Echo the incoming `Request-Id`
        when present.
      schema:
        type: string
    ETag:
      description: >
        Opaque strong entity tag for the current pass state. Do not use the `W/`
        weak validator

        prefix. Return a fresh value with every `200` response.
      schema:
        type: string
      examples:
        - '"v4"'
    RetryAfter:
      description: >
        Integer seconds Revolut should wait before retrying (not the HTTP-date
        form).

        `0` means retry immediately.
      schema:
        type: integer
        minimum: 0
      examples:
        - 30
  schemas:
    TransactionOutcomesSearchRequest:
      type: object
      description: >
        Request body for `POST /transaction-outcomes/search`. Contains the
        transaction context

        Revolut sends for you to match.
      required:
        - transaction_context
      properties:
        transaction_context:
          $ref: "#/components/schemas/TransactionContext"
    TransactionContext:
      type: object
      description: Identifiers Revolut supplies so you can match the originating
        transaction.
      required:
        - rrn
        - merchant_id
        - transaction_at
      properties:
        rrn:
          type: string
          description: ISO 8583 Retrieval Reference Number of the original payment.
          examples:
            - "123456789012"
        merchant_id:
          type: string
          description: Card acceptor identifier (DE 42 in ISO 8583 messaging); identifies
            the sub-merchant for aggregators.
          examples:
            - mer_example_01
        transaction_at:
          type: string
          format: date-time
          description: Timestamp of the purchase, UTC, ISO 8601.
          examples:
            - 2026-07-01T12:00:00.000Z
        total:
          description: Transaction total, supplied for stronger matching. You may choose
            not to validate it.
          $ref: "#/components/schemas/Money"
    TransactionOutcomes:
      type: object
      description: >
        What a Revolut-card transaction produced. Currently the passes tied to
        the transaction.

        Revolut ignores unknown fields in this response, so you may add fields
        without breaking

        compatibility.
      required:
        - passes
      properties:
        passes:
          type: array
          maxItems: 50
          items:
            $ref: "#/components/schemas/PassCreate"
    Error:
      type: object
      description: Standard error body for 4xx/5xx responses.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable snake_case error code.
        message:
          type: string
          description: Human-readable explanation.
        error_id:
          type: string
          description: Your trace id
          if you have one.: null
    Money:
      type: object
      description: ISO 4217 monetary amount, represented as strings to preserve
        decimal precision.
      required:
        - amount
        - currency
      properties:
        amount:
          type: string
          pattern: ^-?\d+(\.\d+)?$
          description: Decimal amount as a string (e.g. "72.40").
          examples:
            - "72.40"
        currency:
          type: string
          pattern: ^[A-Z]{3}$
          description: ISO 4217 currency code (e.g. GBP, EUR, USD).
          examples:
            - GBP
    LocalisedText:
      type: object
      description: Text with optional localisation support.
      required:
        - default
      properties:
        default:
          type: string
          description: Fallback text when no localisation matches.
        localisation_key:
          type: string
          description: Key resolved against Revolut's localisation catalogue at render time.
    Action:
      type: object
      description: A button rendered on the pass (e.g. "Open website", "Get directions").
      required:
        - id
        - type
      properties:
        id:
          type: string
          description: Unique identifier for the action within this pass.
        type:
          type: string
          description: "Documented values: `open_external_url`. External URL domain needs
            to be registered at onboarding."
        label:
          description: Display label for the button, with optional localisation.
          $ref: "#/components/schemas/LocalisedText"
        url:
          type: string
          format: uri
          description: Target URL for `open_external_url` actions.
        importance:
          type: integer
          minimum: 1
          maximum: 5
          description: Relative prominence of this action (1 = primary, 5 = least
            prominent).
    Coordinates:
      type: object
      description: Geographic coordinates (WGS 84).
      required:
        - lat
        - lng
      properties:
        lat:
          type: number
          format: double
          description: Latitude in decimal degrees.
        lng:
          type: number
          format: double
          description: Longitude in decimal degrees.
    Presentation:
      type: object
      description: How a trigger is presented to the customer.
      properties:
        presentation_type:
          type: string
          description: "Documented values: `notification`, `tile`."
        title:
          description: Title text for the notification or tile, with optional localisation.
          $ref: "#/components/schemas/LocalisedText"
        description:
          description: Body text for the notification or tile, with optional localisation.
          $ref: "#/components/schemas/LocalisedText"
    Trigger:
      type: object
      description: A context-aware notification that nudges the customer (e.g.
        proximity alert, time before event).
      required:
        - id
        - type
      properties:
        id:
          type: string
          description: Unique identifier for the trigger within this pass.
        type:
          type: string
          description: "Documented values: `proximity_time`, `proximity_geo_location`,
            `field_change`."
        importance:
          type: integer
          minimum: 1
          maximum: 5
          description: Relative prominence of this trigger (1 = high, 5 = low).
        time_target:
          type: string
          description: Reference to a datetime field (e.g. `flight.scheduled_departure_at`).
        time_offset:
          type: string
          description: ISO 8601 duration before the target (e.g. `PT1H` for 1 hour before
            departure).
        location_targets:
          type: array
          description: Geographic coordinates for proximity-based triggers.
          items:
            $ref: "#/components/schemas/Coordinates"
        radius_meters:
          type: integer
          minimum: 0
          description: Radius in meters around the `location_targets` coordinates for the
            proximity alert.
        field_target:
          type: string
          description: Name of the semantic field to watch for changes (e.g.
            `boarding.gate`).
        presentation:
          description: How the trigger is presented to the customer (notification, tile).
          $ref: "#/components/schemas/Presentation"
    PassBase:
      type: object
      description: Fields common to every pass type.
      required:
        - type
        - partner_reference
        - version
      properties:
        partner_reference:
          type: string
          maxLength: 128
          description: Your own reference for the pass; use it to match the pass in your
            system.
          examples:
            - skyjet-2241-R7K92M
        type:
          type: string
          description: >
            Pass type discriminator. Selects the `semantics` structure.
            Documented values:

            `boarding_pass`, `event_pass`, `loyalty_pass`. New pass types are
            introduced in new API versions.
        version:
          type: integer
          format: int64
          minimum: 1
          description: Your monotonically increasing version; bump on every change.
          examples:
            - 1
        relevant_at:
          type: string
          format: date-time
          description: When the pass becomes time-relevant (departure, event start);
            drives polling cadence.
        actions:
          type: array
          description: Buttons rendered on the pass.
          items:
            $ref: "#/components/schemas/Action"
        triggers:
          type: array
          description: Context-aware notifications that nudge the customer.
          items:
            $ref: "#/components/schemas/Trigger"
    Passenger:
      type: object
      description: Passenger details for a boarding pass.
      required:
        - full_name
      properties:
        full_name:
          type: string
          description: Full name of the passenger as it appears on the boarding pass.
          examples:
            - Sarah Connor
        fare_class:
          type: string
          description: Human-readable fare class (e.g. Economy, Business, First).
          examples:
            - Economy
        fare_class_code:
          type: string
          description: IATA fare class code (single letter, e.g. Y for Economy, J for
            Business).
          examples:
            - Y
        frequent_flyer_program:
          type: string
          description: Name of the frequent flyer program the passenger belongs to.
        frequent_flyer_number:
          type: string
          description: Membership number within the frequent flyer program.
    Airport:
      type: object
      description: Airport details for a flight.
      required:
        - iata
      properties:
        iata:
          type: string
          description: IATA airport code (3 uppercase letters).
          pattern: ^[A-Z]{3}$
          examples:
            - LTN
        name:
          type: string
          description: Full name of the airport (e.g. London Luton Airport).
        city:
          type: string
          description: City where the airport is located.
        country_code:
          type: string
          description: ISO 3166-1 alpha-2 country code.
          pattern: ^[A-Z]{2}$
        terminal:
          type: string
          description: Terminal identifier at the airport.
          examples:
            - "1"
    Flight:
      type: object
      description: Flight details for a boarding pass.
      required:
        - flight_number
        - carrier_code
        - departure_airport
        - arrival_airport
        - scheduled_departure_at
        - scheduled_arrival_at
      properties:
        flight_number:
          type: string
          description: Flight number without the carrier code (e.g. 2241, not SJ2241).
          examples:
            - "2241"
        carrier_code:
          type: string
          description: IATA or ICAO carrier code (2 alphanumeric characters).
          pattern: ^[A-Z0-9]{2}$
          examples:
            - W6
        carrier_name:
          type: string
          description: Display name of the operating carrier.
          examples:
            - SkyJet Airlines
        operating_carrier_code:
          type: string
          description: Carrier code of the actual operating carrier (for codeshare
            flights, this may differ from `carrier_code`).
          pattern: ^[A-Z0-9]{2}$
        departure_airport:
          description: Departure airport.
          $ref: "#/components/schemas/Airport"
        arrival_airport:
          description: Arrival airport.
          $ref: "#/components/schemas/Airport"
        scheduled_departure_at:
          type: string
          format: date-time
          description: Scheduled departure time, UTC, ISO 8601.
        scheduled_arrival_at:
          type: string
          format: date-time
          description: Scheduled arrival time, UTC, ISO 8601.
        aircraft_type:
          type: string
          description: IATA aircraft type code (e.g. A320, B738).
          examples:
            - A320
    Boarding:
      type: object
      description: Boarding details for a flight — gate, seat, and boarding time.
      properties:
        gate:
          type: string
          description: Boarding gate at the departure airport.
          examples:
            - B22
        boarding_at:
          type: string
          format: date-time
          description: Scheduled boarding time, UTC, ISO 8601.
        boarding_group:
          type: string
          description: Boarding group or zone (airline-specific, e.g. A, B, 1, 2).
        sequence_number:
          type: string
          description: Boarding sequence number assigned to the passenger.
        seat:
          type: string
          description: Assigned seat number (e.g. 14C, 22A).
          examples:
            - 14C
        seat_class:
          type: string
          description: Seat class label (e.g. Economy, Premium Economy, Business).
          examples:
            - Economy
    Booking:
      type: object
      description: Booking details for a boarding pass.
      required:
        - pnr
      properties:
        pnr:
          type: string
          description: Passenger Name Record — the booking reference from the airline's
            reservation system.
          examples:
            - R7K92M
        ticket_number:
          type: string
          description: 13-digit IATA ticket number.
          pattern: ^[0-9]{13}$
        booking_reference:
          type: string
          description: Alternative booking reference (e.g. agency or GDS reference), if
            different from the PNR.
    Validity:
      type: object
      description: Validity window for a pass — when it becomes active and when it expires.
      properties:
        valid_from:
          type: string
          format: date-time
          description: Start of the pass validity period, UTC, ISO 8601.
        valid_until:
          type: string
          format: date-time
          description: End of the pass validity period, UTC, ISO 8601.
    BoardingPassSemantics:
      type: object
      description: Semantic tags for a boarding pass.
      required:
        - passenger
        - flight
        - booking
      properties:
        passenger:
          description: Passenger details.
          $ref: "#/components/schemas/Passenger"
        flight:
          description: Flight details.
          $ref: "#/components/schemas/Flight"
        boarding:
          description: Boarding details (gate, seat, boarding time).
          $ref: "#/components/schemas/Boarding"
        booking:
          description: Booking details (PNR, ticket number).
          $ref: "#/components/schemas/Booking"
        validity:
          description: Optional validity window for the pass.
          $ref: "#/components/schemas/Validity"
    BoardingPass:
      allOf:
        - $ref: "#/components/schemas/PassBase"
        - type: object
          required:
            - semantics
          properties:
            type:
              type: string
              enum:
                - boarding_pass
            semantics:
              $ref: "#/components/schemas/BoardingPassSemantics"
    BoardingPassCreate:
      description: A boarding pass being created, comprising the pass content plus its
        render template.
      allOf:
        - $ref: "#/components/schemas/BoardingPass"
        - type: object
          properties:
            template_id:
              type: string
              description: >
                Identifier of a pre-registered branding/layout template to
                render this pass with.

                If omitted, Revolut uses the default template for your partner
                account, which may

                not match your brand. Including it ensures your pass is rendered
                with the correct

                visual design. Set at creation and immutable; not accepted when
                updating a pass.
              examples:
                - tmpl_skyjet_boarding
    Event:
      type: object
      description: Event details for an event pass.
      required:
        - name
        - held_on
        - starts_at
      properties:
        name:
          type: string
          description: Name of the event.
          examples:
            - "The Blue Lights: Live"
        category:
          type: string
          description: "Documented values: `concert`, `sport`, `conference`, `theatre`,
            `festival`, `race`, `other`."
        edition:
          type: string
          description: Edition or iteration of a recurring event (e.g. 2026, Season 5).
        held_on:
          type: string
          format: date
          description: Calendar day of the event (use `starts_at` for the precise start
            time).
        starts_at:
          type: string
          format: date-time
          description: Start time of the event, UTC, ISO 8601.
        ends_at:
          type: string
          format: date-time
          description: End time of the event, UTC, ISO 8601.
        doors_open_at:
          type: string
          format: date-time
          description: Time the venue doors open, UTC, ISO 8601.
    Venue:
      type: object
      description: Venue details for an event.
      required:
        - name
      properties:
        name:
          type: string
          description: Name of the venue.
          examples:
            - Grand Arena
        address:
          type: string
          description: Street address of the venue.
        city:
          type: string
          description: City where the venue is located.
        country_code:
          type: string
          description: ISO 3166-1 alpha-2 country code.
          pattern: ^[A-Z]{2}$
        coordinates:
          description: Geographic coordinates of the venue.
          $ref: "#/components/schemas/Coordinates"
        gate:
          type: string
          description: Entrance gate at the venue.
        section:
          type: string
          description: Section or block within the venue (e.g. Block 112, Section C).
        row:
          type: string
          description: Row identifier within the section.
        seat:
          type: string
          description: Seat number within the row.
    Ticket:
      type: object
      description: Ticket details for an event pass.
      properties:
        number:
          type: string
          description: Ticket number or barcode value.
        booking_reference:
          type: string
          description: Booking or order reference for the ticket purchase.
        type:
          type: string
          description: "Documented values: `general_admission`, `seated`, `vip`,
            `backstage`, `staff`."
    Participant:
      type: object
      description: Participant details for an event pass (e.g. conference attendee).
      properties:
        full_name:
          type: string
          description: Full name of the participant.
        company:
          type: string
          description: Company or organisation the participant represents.
        role:
          type: string
          description: Role or title at the event (e.g. Speaker, Attendee, Volunteer).
    Organiser:
      type: object
      description: Organiser of the event.
      properties:
        name:
          type: string
          description: Name of the organising company or individual.
    EventPassSemantics:
      type: object
      description: Semantic tags for an event pass.
      required:
        - event
        - venue
      properties:
        event:
          description: Event details (name, category, dates).
          $ref: "#/components/schemas/Event"
        venue:
          description: Venue details (name, address, seat).
          $ref: "#/components/schemas/Venue"
        ticket:
          description: Ticket details (number, type, booking reference).
          $ref: "#/components/schemas/Ticket"
        participant:
          description: Participant details (name, company, role).
          $ref: "#/components/schemas/Participant"
        organiser:
          description: Organiser details.
          $ref: "#/components/schemas/Organiser"
        validity:
          description: Optional validity window for the pass.
          $ref: "#/components/schemas/Validity"
    EventPass:
      allOf:
        - $ref: "#/components/schemas/PassBase"
        - type: object
          required:
            - semantics
          properties:
            type:
              type: string
              enum:
                - event_pass
            semantics:
              $ref: "#/components/schemas/EventPassSemantics"
    EventPassCreate:
      description: An event pass being created, comprising the pass content plus its
        render template.
      allOf:
        - $ref: "#/components/schemas/EventPass"
        - type: object
          properties:
            template_id:
              type: string
              description: >
                Identifier of a pre-registered branding/layout template to
                render this pass with.

                If omitted, Revolut uses the default template for your partner
                account, which may

                not match your brand. Including it ensures your pass is rendered
                with the correct

                visual design. Set at creation and immutable; not accepted when
                updating a pass.
              examples:
                - tmpl_acmeconcerts_event
    Member:
      type: object
      description: Member details for a loyalty pass.
      required:
        - full_name
        - member_id
      properties:
        full_name:
          type: string
          description: Full name of the loyalty program member.
          examples:
            - Stefan Pantic
        member_id:
          type: string
          description: Membership number or ID within the loyalty program.
          examples:
            - "9988776655"
        member_since_on:
          type: string
          format: date
          description: Date the member joined the programme.
    TierProgress:
      type: object
      description: Progress towards the next loyalty tier.
      properties:
        current:
          type: string
          description: Current progress value as a string (e.g. points earned this period).
        target:
          type: string
          description: Target value required to reach the next tier, as a string.
        unit:
          type: string
          description: Unit of measurement for the progress values (e.g. points, stays,
            flights).
          examples:
            - points
    PointsBalance:
      type: object
      description: Points balance for a loyalty pass.
      properties:
        value:
          type: string
          description: Current points balance as a string (to preserve integer precision).
          examples:
            - "1500"
        unit:
          type: string
          description: Unit label for the balance (e.g. points, miles).
          examples:
            - points
        monetary_value:
          description: Optional monetary equivalent of the points balance.
          $ref: "#/components/schemas/Money"
    NextReward:
      type: object
      description: Next reward the member can unlock with their points.
      properties:
        description:
          type: string
          description: Human-readable description of the reward (e.g. "Free coffee
            voucher").
        points_required:
          type: string
          description: Points required to unlock the reward, as a string.
          examples:
            - "5000"
    Loyalty:
      type: object
      description: Loyalty program details for a pass.
      required:
        - program_name
      properties:
        program_name:
          type: string
          description: Display name of the loyalty program.
          examples:
            - BrightPoints
        tier:
          type: string
          description: Current tier level of the member (e.g. Gold, Silver, Bronze).
          examples:
            - Gold
        tier_progress:
          description: Progress towards the next tier.
          $ref: "#/components/schemas/TierProgress"
        points_balance:
          description: Current points balance.
          $ref: "#/components/schemas/PointsBalance"
        next_reward:
          description: Next reward the member can unlock.
          $ref: "#/components/schemas/NextReward"
    LoyaltyPassSemantics:
      type: object
      description: Semantic tags for a loyalty pass.
      required:
        - member
        - loyalty
      properties:
        member:
          description: Member details (name, ID, join date).
          $ref: "#/components/schemas/Member"
        loyalty:
          description: Loyalty program details (tier, balance, next reward).
          $ref: "#/components/schemas/Loyalty"
        validity:
          description: Optional validity window for the pass.
          $ref: "#/components/schemas/Validity"
    LoyaltyPass:
      allOf:
        - $ref: "#/components/schemas/PassBase"
        - type: object
          required:
            - semantics
          properties:
            type:
              type: string
              enum:
                - loyalty_pass
            semantics:
              $ref: "#/components/schemas/LoyaltyPassSemantics"
    LoyaltyPassCreate:
      description: A loyalty pass being created, comprising the pass content plus its
        render template.
      allOf:
        - $ref: "#/components/schemas/LoyaltyPass"
        - type: object
          properties:
            template_id:
              type: string
              description: >
                Identifier of a pre-registered branding/layout template to
                render this pass with.

                If omitted, Revolut uses the default template for your partner
                account, which may

                not match your brand. Including it ensures your pass is rendered
                with the correct

                visual design. Set at creation and immutable; not accepted when
                updating a pass.
              examples:
                - tmpl_brightpoints_loyalty
    PassCreate:
      description: >
        A pass as created/provisioned, i.e. a concrete pass type plus the
        `template_id` that renders it.

        Used when a pass is created (`POST /passes`) or provisioned from a
        transaction outcome. New pass types

        may be added over time and are available in all supported API versions.
      oneOf:
        - $ref: "#/components/schemas/BoardingPassCreate"
        - $ref: "#/components/schemas/EventPassCreate"
        - $ref: "#/components/schemas/LoyaltyPassCreate"
      discriminator:
        propertyName: type
        mapping:
          boarding_pass: "#/components/schemas/BoardingPassCreate"
          event_pass: "#/components/schemas/EventPassCreate"
          loyalty_pass: "#/components/schemas/LoyaltyPassCreate"
    PassUpdate:
      description: >
        The updatable state of a pass, i.e. one of the concrete types selected
        by `type`. Used both when you

        push an update and when Revolut polls you for the latest state. Excludes
        `template_id`, which is

        fixed at creation. New pass types may be added over time and are
        available in all supported API versions.
      oneOf:
        - $ref: "#/components/schemas/BoardingPass"
        - $ref: "#/components/schemas/EventPass"
        - $ref: "#/components/schemas/LoyaltyPass"
      discriminator:
        propertyName: type
        mapping:
          boarding_pass: "#/components/schemas/BoardingPass"
          event_pass: "#/components/schemas/EventPass"
          loyalty_pass: "#/components/schemas/LoyaltyPass"
  responses:
    BadRequest:
      description: Malformed request or invalid body.
      headers:
        Request-Id:
          $ref: "#/components/headers/RequestId"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          examples:
            validation_error:
              value:
                code: validation_error
                message: Request validation failed.
    Unauthorized:
      description: >
        Missing or invalid Revolut credentials: no or failed mTLS certificate,
        an invalid

        JWS signature, or a missing/invalid OAuth 2.0 access token.
      headers:
        Request-Id:
          $ref: "#/components/headers/RequestId"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          examples:
            invalid_credentials:
              value:
                code: invalid_credentials
                message: Missing or invalid Revolut credentials.
    Forbidden:
      description: >
        Authenticated, but the credential lacks the required scope/permission
        (e.g. an OAuth token

        without `passes.read`).
      headers:
        Request-Id:
          $ref: "#/components/headers/RequestId"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          examples:
            insufficient_scope:
              value:
                code: insufficient_scope
                message: The credential does not have the passes.read scope.
    TooManyRequests:
      description: Rate limit exceeded. Revolut retries, honouring `Retry-After`.
      headers:
        Request-Id:
          $ref: "#/components/headers/RequestId"
        Retry-After:
          $ref: "#/components/headers/RetryAfter"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          examples:
            rate_limited:
              value:
                code: rate_limited
                message: Rate limit exceeded. Retry after the specified delay.
    ServiceUnavailable:
      description: Temporary capacity issue. Revolut retries, honouring `Retry-After`.
      headers:
        Request-Id:
          $ref: "#/components/headers/RequestId"
        Retry-After:
          $ref: "#/components/headers/RetryAfter"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          examples:
            temporarily_unavailable:
              value:
                code: temporarily_unavailable
                message: Service temporarily unavailable. Please retry.
x-ext-urls: {}
