openapi: 3.1.0
info:
  title: Bilt Partner API
  version: 1.0.0
  description: |
    # Introduction

    The Bilt Partner API ("Cart SDK") lets a partner app (for example, a
    checkout inside a partner's mobile app) hand a customer off to a
    Bilt-hosted checkout without building any payment, card, or
    identity UI itself.

    The integration has three parts:

    1. **Open a checkout session** — your backend makes one
       server-to-server call to `POST /partner/cart/v1/checkout-sessions`
       and receives a short-lived handoff `token`.
    2. **Hand the token to the Bilt checkout** — your app gives that token
       to the Bilt checkout surface, which exchanges it for the session by
       calling `POST /public/cart/v1/checkout-sessions/redeem`, renders
       Bilt-hosted checkout, and reports a navigation outcome.
    3. **Receive webhooks** — Bilt posts signed checkout events to your
       backend.

    ## Model

    - Your **backend** talks to Bilt. Your **app never calls the partner
      endpoints** and never handles cards, one-time codes, partner
      credentials, or cookies.
    - The handoff `token` (prefix `cst_`) is **short-lived** — it expires
      with the session at `expiresAt` (30 minutes by default, configurable
      per partner). It is returned **only** in the create response; Bilt
      persists only its SHA-256 hash, so a lost token cannot be recovered.
    - Redeeming the token does **not** consume it. It stays usable until
      the session expires or reaches a terminal status (`COMPLETED`,
      `CANCELLED`, `EXPIRED`), so the checkout surface may redeem more than
      once within the session's lifetime.
    - Bilt owns authentication and payment. The Bilt-hosted page
      recognizes returning customers automatically and, when needed, shows
      an inline one-time-code prompt — **your app renders none of this**.
    - No Bilt user token or reusable Bilt credential is ever returned to
      the partner. Authorization travels in the handoff `token`, which is
      scoped to that one checkout session.

    ## Base URLs

    The two path families sit behind different gateways: your backend calls
    the third-party partner gateway, and the checkout surface calls the
    consumer gateway.

    | Paths | Caller | Gateway | Staging | Production |
    | ----- | ------ | ------- | ------- | ---------- |
    | `/partner/cart/v1/…` | Your backend | Partner (third-party) | `https://staging.partnerapi.biltrewards.com` | `https://partnerapi.biltrewards.com` |
    | `/public/cart/v1/…` | Bilt checkout surface | Consumer | `https://staging.api.biltrewards.com` | `https://api.biltrewards.com` |

    The `servers` list for this document is the partner gateway; the
    `/public/cart/v1/…` operations carry their own `servers` block.

    ## Rate limits

    Requests traverse a Bilt API gateway that may shed load. Treat `429 Too
    Many Requests` as retryable with backoff, honouring `Retry-After` when
    it is present; Bilt shares per-partner quotas during onboarding when
    your volume warrants one.

    ## Testing

    Integration testing happens against Bilt's **staging** environment
    using the hosts above, with a staging client id and secret issued
    during onboarding.

    ## Merchant-ID mapping

    The merchant is resolved by Bilt from the `lookupUrl` you supply when
    creating the session, and returned as `merchantId` on the session — you
    do not map venues to Bilt merchant ids yourself.

    ## Onboarding

    1. Bilt registers your backend as a confidential client in the
       `enterprise-partner` Keycloak realm and issues your **client id**
       and **client secret**.
    2. You mint access tokens with the client-credentials grant and
       implement server-to-server checkout-session creation with an
       `Idempotency-Key` per attempt.
    3. Your app hands the returned `token` to the Bilt checkout surface and
       handles the terminal outcome it reports.
    4. You stand up your webhook receiver and verify the Standard Webhooks
       signature (`webhook-signature`) with the `whpk_` Ed25519 public key
       Bilt provides.
    5. Both teams complete end-to-end testing in staging.

    ## Authentication

    Partner endpoints are authenticated server-to-server with **OAuth 2.0
    client credentials**, not an API key. Bilt registers your backend as a
    confidential client in the `enterprise-partner` Keycloak realm and
    issues a client id and client secret during onboarding (for example,
    `partner-example-merchant`).

    Mint an access token, then send it as `Authorization: Bearer
    <access_token>` on every `/partner/cart/v1/…` request:

    ```bash
    curl -s -X POST \
      'https://staging.biltrewards.com/realms/enterprise-partner/protocol/openid-connect/token' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -d 'grant_type=client_credentials' \
      -d 'client_id=partner-example-merchant' \
      --data-urlencode "client_secret=$BILT_CLIENT_SECRET" \
      -d 'scope=cart:sessions:read cart:sessions:write'
    ```

    | | |
    | --- | --- |
    | Grant type | `client_credentials` |
    | Token endpoint (staging) | `https://staging.biltrewards.com/realms/enterprise-partner/protocol/openid-connect/token` |
    | Token endpoint (production) | `https://www.bilt.com/realms/enterprise-partner/protocol/openid-connect/token` |
    | Audience | `bilt-cart-partner-api` |
    | Scopes | `cart:sessions:read`, `cart:sessions:write` |
    | Access-token lifetime | 15 minutes |

    The gateway validates the token's issuer and its `bilt-cart-partner-api`
    audience, so a credential issued for a different Bilt partner API is
    rejected on these routes. Cache the token and refresh it shortly before
    expiry. Keep the client secret server-side only; the app and the
    checkout surface never see it.

    The `/public/cart/v1/…` routes take no partner credential — they are
    authorized by the session handoff `token` itself.

servers:
  - url: https://partnerapi.biltrewards.com
    description: Production — partner (third-party) gateway
  - url: https://staging.partnerapi.biltrewards.com
    description: Staging — partner (third-party) gateway

x-tagGroups:
  - name: API
    tags:
      - partner
      - Checkout Sessions
      - Webhooks
      - Pay with points
  - name: Checkout Kit (Mobile SDK)
    tags:
      - Embedding the checkout
      - Checkout Kit · iOS
      - Checkout Kit · Android
      - Checkout Kit · React Native

tags:
  - name: partner
    x-displayName: Authentication
    description: |
      Partner endpoints use **OAuth 2.0 client credentials**. Bilt issues a
      client id and secret for a confidential client in the
      `enterprise-partner` Keycloak realm; exchange them at the realm's
      token endpoint for an access token with the `bilt-cart-partner-api`
      audience and the `cart:sessions:read` / `cart:sessions:write` scopes,
      then send `Authorization: Bearer <access_token>` on every
      `/partner/cart/v1/…` request. See **Introduction › Authentication**
      for the token request and per-environment endpoints.

      The SDK-facing `/public/cart/v1/…` routes carry no partner
      credential; the session handoff `token` authorizes them.
  - name: Checkout Sessions
    description: |
      Create and manage Bilt-hosted checkout sessions.

      Your backend creates a session on the partner gateway and receives a
      handoff `token`; the Bilt checkout surface exchanges that token for
      the session context on the consumer gateway. Session statuses are
      `OPEN`, `COMPLETED`, `CANCELLED`, `EXPIRED`, and `REVERSED`.
  - name: Webhooks
    x-displayName: Webhooks
    description: |
      ## Receiving webhooks

      Bilt delivers checkout events to one or more HTTPS endpoints you
      register with Bilt (for example
      `POST https://partner.example.com/webhooks/bilt`). Each endpoint is
      subscribed to a set of event types, and an event is delivered to every
      endpoint subscribed to its type. Webhooks are the **source of truth** for
      payment state.

      Delivery follows the [Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md)
      specification (v1.0.0) for headers, signing, and retries, so any
      Standard Webhooks verification library works unchanged.

      ### Delivery contract

      - **Method / body** — Every event is a `POST` with
        `Content-Type: application/json`. The body is a Standard Webhooks
        envelope with `type`, `timestamp` (RFC 3339), and `data` for every
        event type. Checkout session lifecycle events use the
        `CheckoutSessionWebhookEvent` schema; `orderClosed` and
        `closedOrderUpdated` use `WebhookEvent`. See the event-specific
        [webhook entries](#tag/webhooks) below:
        [checkout.session.completed](#tag/webhooks/webhook/POST/checkoutsessioncompleted),
        [checkout.session.cancelled](#tag/webhooks/webhook/POST/checkoutsessioncancelled),
        [checkout.session.expired](#tag/webhooks/webhook/POST/checkoutsessionexpired),
        [checkout.session.reversed](#tag/webhooks/webhook/POST/checkoutsessionreversed),
        [orderClosed](#tag/webhooks/webhook/POST/orderclosed), and
        [closedOrderUpdated](#tag/webhooks/webhook/POST/closedorderupdated).
      - **Body bytes** — the body is delivered byte for byte as the
        producing service serialized it (UTF-8 JSON, at most 256 KiB).
        Verify the signature over the raw bytes before parsing.
      ### Signing and authentication

      The signature **is** the authentication: webhooks carry no bearer token,
      and you must not accept an unsigned or badly-signed delivery. Every
      delivery carries three headers:

      | Header | Value |
      | ------ | ----- |
      | `webhook-id` | Stable per-event message id (for example `msg_2KWPBgLlAfxdpx2AI54pPJ85f4W`), formed from `msg_` plus a hash of the event identity. The same event redelivered has the same `webhook-id` — use it as your idempotency key. |
      | `webhook-timestamp` | Unix timestamp in **seconds** at which this delivery attempt was signed. |
      | `webhook-signature` | Space-separated list of `v1a,<base64>` Ed25519 signatures (Standard Webhooks *asymmetric* scheme). Accept the delivery if **any** of them verifies. |

      To verify:

      1. Take the **raw** request body bytes — do not parse and re-serialize.
      2. Build the signed content `"{webhook-id}.{webhook-timestamp}.{rawBody}"`.
      3. Verify each `v1a,<base64>` entry as an Ed25519 signature over that
         string with Bilt's public key. Bilt hands you the key in the
         Standard Webhooks form `whpk_<base64>`; the key is the 32 raw bytes
         base64-decoded from after the `whpk_` prefix.
      4. Reject if `webhook-timestamp` is more than **5 minutes** from your
         clock (replay protection).
      5. Process each `webhook-id` at most once.

      Bilt issues one signing key per partner. Rotation is zero-downtime:
      Bilt hands you the new public key first and only then switches
      signing to it, so accept a signature that verifies against either
      key during the rotation window. Deliveries are only ever made over
      HTTPS.

      - **Idempotency** — deduplicate on the `webhook-id` header. For
        `checkout.session.*` events the producer mints one event id per
        `(sessionId, type)`, so a re-run of the same transition reuses the
        same `webhook-id` and is delivered once.
      - **Acknowledgement** — respond `2xx` promptly. Any retryable failure
        (see below) triggers retries with backoff.

      ### Delivery guarantees

      - Delivery is **at least once**. Deduplicate on `webhook-id`.
      - Acknowledge with any `2xx` **before** doing slow work; Bilt times an
        attempt out after **10 seconds** by default (configurable per
        partner between 1 and 30 seconds).
      - A timeout, a transport error, or a `408`, `425`, `429`, or `5xx`
        response is retried with exponential backoff (10 seconds up to
        1 hour between attempts) for **48 hours** after the event was first
        accepted; `Retry-After` on those responses is recorded and honoured
        on a best-effort basis; it is not a strict delay guarantee. After 48
        hours the delivery is recorded
        as failed and can be replayed by Bilt on request.
      - Any other `3xx` or `4xx` response is treated as a **rejection** of
        that event and is not retried. Do not return `4xx` for transient
        problems on your side.
      - Bilt does **not** follow redirects; a `3xx` is a rejection.
      - Bilt may send a **test delivery** from its operator console. It has
        the same headers and signature and a body
        `{"type": "<one of your subscribed types>", "timestamp": ..., "data": {"id": "example"}}`.
        Its `data` deliberately does **not** match the event schema, so check
        for `data.id == "example"` after verifying the signature and before
        schema validation: return `2xx` and do nothing else.
      - Ordering is not guaranteed. Order all events on the body `timestamp`.

      ### Event types

      | `type`                | Meaning                                             |
      | --------------------- | --------------------------------------------------- |
      | `checkout.session.completed` | Payment succeeded for the session.                  |
      | `checkout.session.cancelled` | The checkout was cancelled (no successful payment). |
      | `checkout.session.expired`   | The session expired before completion.              |
      | `checkout.session.reversed`  | A completed session's payment was reversed (refund / abort). |
      | `orderClosed`                | The check was first detected as closed.              |
      | `closedOrderUpdated`         | A previously closed check was updated.               |

      ### Checkout session lifecycle events

      Every `checkout.session.*` event is published **after** the status
      change it announces has been committed, so you may act on it at once.
      A session emits at most one event per type: `completed` is published
      once when payment is captured, and `reversed` follows it only if the
      payment is later reversed. `cancelled` and `expired` are terminal
      for a session that never completed. Sessions that are still `OPEN`,
      or that failed before a payment was captured, emit no webhook.

      ### Order events

      The event names are generic across merchant types; for dining merchants
      the order is the check, delivered as `data.check`. `orderClosed` is sent
      once per order when Bilt first detects it is closed (`checkState:
      completed`), typically when activity on it is done. `closedOrderUpdated`
      is sent when an order that was already closed is updated afterwards, such
      as a tip adjustment, late payment, or item or amount correction. Each
      payload is the full current snapshot, not a diff. `orderClosed` fires at
      most once per `check.id`; `closedOrderUpdated` may fire zero or more times
      after it, and each delivery has its own `webhook-id`. Deliveries are not
      ordered (see above), so receivers should upsert on `check.id` and replace
      the stored snapshot only when the incoming body `timestamp` is strictly
      later than the stored one; an event whose `timestamp` is equal to or
      earlier than the stored snapshot is stale and should be acknowledged and
      dropped.

      All four share one body shape:

      ```json
      {
        "type": "checkout.session.cancelled",
        "timestamp": "2026-09-10T14:34:18.986759998Z",
        "data": {
          "sessionId": "2dfdb0f5-a072-4114-a8ee-7b1f2872886a",
          "status": "CANCELLED",
          "orderId": "955648d7-1926-4b0e-82ba-0b5b2a664de6",
          "configId": "0c164cc0-9aa4-4054-b999-472ed4b75bc5",
          "merchantCatalogId": null,
          "checkoutPaymentId": null
        }
      }
      ```

      | Field | Type | Description |
      | ----- | ---- | ----------- |
      | `type` | string | The event type. Always equal to the `event_type` Bilt routed the event on. |
      | `timestamp` | RFC 3339 UTC string | When the status transition happened (nanosecond precision, `Z` suffix). Order events on it. |
      | `data.sessionId` | UUID | The Bilt checkout session. |
      | `data.status` | `COMPLETED` \| `CANCELLED` \| `EXPIRED` \| `REVERSED` | The session status after the transition; matches `type`. |
      | `data.orderId` | UUID | The Bilt-assigned order id of the session (always present; correlate on `sessionId`). |
      | `data.configId` | UUID | The Bilt merchant configuration the session was created against. |
      | `data.merchantCatalogId` | UUID or `null` | The Bilt merchant-catalog id of that merchant, when one is configured. |
      | `data.checkoutPaymentId` | UUID or `null` | The Bilt payment attached to the session. Always set on `completed` and `reversed`; `null` when no payment was ever attached. |

      Every key is always present; a value that does not apply is `null`,
      never omitted. The payload is reference-only — it carries no customer
      PII, amounts, or line items. Fetch anything else you need with the
      session id.

      ### Event → payload matrix

      The `orderClosed` entry has selectable examples for a non-split check, an even split, a per-item split, and a member points payment.

      | Event | When it fires | Key payload fields |
      | ----- | ------------- | ------------------ |
      | `checkout.session.completed` | Payment captured for the session. [checkout.session.completed](#tag/webhooks/webhook/POST/checkoutsessioncompleted). | `type`, `timestamp`, `data.sessionId`, `data.status=COMPLETED`, `data.orderId`, `data.configId`, `data.merchantCatalogId`, `data.checkoutPaymentId` |
      | `checkout.session.cancelled` | The checkout was cancelled without a successful payment. [checkout.session.cancelled](#tag/webhooks/webhook/POST/checkoutsessioncancelled). | same fields, `data.status=CANCELLED` |
      | `checkout.session.expired` | The checkout expired before completion. [checkout.session.expired](#tag/webhooks/webhook/POST/checkoutsessionexpired). | same fields, `data.status=EXPIRED` |
      | `checkout.session.reversed` | A completed session's payment was reversed. [checkout.session.reversed](#tag/webhooks/webhook/POST/checkoutsessionreversed). | same fields, `data.status=REVERSED` |
      | `orderClosed` | The order (check) was first detected as closed. [orderClosed](#tag/webhooks/webhook/POST/orderclosed). | `type`, `timestamp`, `data.sessionId`, `data.partnerUserId`, `data.check`, `data.merchantId` |
      | `closedOrderUpdated` | A previously closed order (check) was updated. [closedOrderUpdated](#tag/webhooks/webhook/POST/closedorderupdated). | `type`, `timestamp`, `data.sessionId`, `data.partnerUserId`, `data.check`, `data.merchantId` |

      The webhook entries above are the payload reference for each event.
      `orderClosed` and `closedOrderUpdated` echo the partner's stable
      `partnerUserId` supplied during session creation. Both carry the full
      current check snapshot, and guest payments have no identity fields while
      member identity fields are present only when the diner paid while signed
      in to Bilt and the merchant is enabled for member data sharing.

      ### Order event field dictionary

      The availability column describes the normal payload shape:
      **always present** means the field is required by the schema;
      **present when available** means the field may be omitted or empty;
      **always present when a payment exists** means the field is required
      on each payment object, when that payment exists;
      **guest payments only** means the field is present on guest payment
      entries and absent from member payment entries;
      **member-only** means it is populated only for linked Bilt member
      payments and is absent on guest payments; and
      **present when available; deprecated** means the field may be present
      but is retained only for backward compatibility.

      | Field | Type | Availability | Description |
      | ----- | ---- | ------------ | ----------- |
      | `type` | string | always present | Event type; `orderClosed` or `closedOrderUpdated`. |
      | `timestamp` | date-time string | always present | Time the event happened, in UTC with a `Z` suffix. |
      | `data.sessionId` | string | always present | The Bilt checkout session. |
      | `data.partnerUserId` | string | always present | The partner's diner/user identifier supplied at session creation; the join key for attaching reservation context. |
      | `data.check` | `Check` object | always present | Check from the POS system. Monetary amounts are in cents. |
      | `data.merchantId` | UUID string | present when available | Bilt merchant identifier for the merchant location. |
      | `check.id` | UUID string | always present | Unique Bilt-generated identifier for the check; see `thirdPartyIds` for the POS's own id. |
      | `check.thirdPartyIds` | object | present when available | Opaque identifiers assigned by the merchant's POS for reconciliation against POS exports. |
      | `check.checkState` | string | always present | State of the check: `open` or `completed`. |
      | `check.checkAmounts` | `CheckAmounts` object | always present | Check amounts, in cents. |
      | `check.checkAmounts.subtotalAmountCents` | integer | always present | Check subtotal, including item costs, discounts, and non-required service charges. |
      | `check.checkAmounts.preDiscountSubtotalAmountCents` | integer | present when available | Subtotal before item-level discounts. |
      | `check.checkAmounts.preCheckDiscountSubtotalAmountCents` | integer | present when available | Subtotal before check-level discounts, inclusive of item-level discounts. |
      | `check.checkAmounts.checkDiscountsTotalAmountCents` | integer | present when available | Total amount of check-level discounts. |
      | `check.checkAmounts.taxAmountCents` | integer | always present | Check tax amount. |
      | `check.checkAmounts.requiredTipsTotalAmountCents` | integer | always present | Required tips on the check. |
      | `check.checkAmounts.requiredTotalAmountCents` | integer | always present | Required total amount for the check. |
      | `check.items[]` | array of `CheckItem` | always present | Items on the check. Payment item references join to these item IDs. |
      | `check.items[].id` | UUID string | always present | Unique Bilt-generated check-item identifier; see `thirdPartyItemId` for the POS's own id. |
      | `check.items[].thirdPartyItemId` | string | present when available | POS identifier of the item line. |
      | `check.items[].name` | string | present when available | Item name from the POS system. |
      | `check.items[].quantity` | integer | always present | Quantity of the item. |
      | `check.items[].amounts` | `ItemAmounts` object | present when available | Item monetary amounts. |
      | `check.items[].discounts[]` | array of `PriceModifier` | present when available | Discounts applied to the item. |
      | `check.items[].modifiers[]` | array of `PriceModifier` | present when available | Modifiers associated with the item. |
      | `check.discounts[]` | array of `PriceModifier` | always present | Check-level discounts. |
      | `check.requiredTips[]` | array of `PriceModifier` | always present | Required-tip or auto-gratuity service charges. |
      | `check.otherServiceCharges[]` | array of `PriceModifier` | always present | Check-level service charges other than required gratuity. |
      | `check.payments` | `CheckPayments` object | always present | Payments associated with the check. |
      | `check.payments.mobileCheckoutGuestPayments[]` | array of `MobileCheckoutGuestPayment` | always present | Payments made by anonymous checkout guests. |
      | `check.payments.mobileCheckoutMemberPayments[]` | array of `MobileCheckoutMemberPayment` | present when available | Payments made by linked Bilt members. |
      | `check.payments.thirdPartyCardPayments[]` | array of `ThirdPartyCardPayment` | present when available | Third-party card payments on the check. |
      | `check.payments.thirdPartyCashPayments[]` | array of `ThirdPartyCashPayment` | present when available | Third-party cash payments on the check. |
      | `check.payments.thirdPartyUncategorizedPayments[]` | array of `ThirdPartyUncategorizedPayment` | present when available | Third-party payments without a more specific category. |
      | `check.payments.houseAccountPayments[]` | array of `HouseAccountPayment` | present when available | House-account payments on the check. |
      | `check.payments.payForGuestPayments[]` | array of `PayForGuestPayment` | present when available | Payments made on behalf of another guest. |
      | `payments.*.amountDetails` | `PaymentAmountDetails` object | always present when a payment exists | Amounts paid by that payment. |
      | `payments.*.status` | `DiningPaymentStatus` | always present when a payment exists | Status of that payment. |
      | `payments.*.paymentId` | UUID string | always present when a payment exists | Unique payment identifier. |
      | `payments.*.anonymousUserId` | UUID string | guest payments only | Identifier of the guest's anonymous checkout profile. It is scoped to the guest's device/card enrolment and is **not a stable diner identifier** across visits; use `partnerUserId` to correlate diners. |
      | `payments.*.biltMemberId` | string | member-only | Bilt member identifier for a linked member payment. |
      | `payments.*.guestPaymentMethodDetails` | `GuestPaymentMethodDetails` object | guest payments only | Guest payment method type. |
      | `payments.mobileCheckoutMemberPayments.*.member.*` | object fields | member-only | Identity of the Bilt member who made the payment: first and last names; phone, email, and reward tier. |
      | `payments.*.cardPaymentDetails` | `CardPaymentDetails` object | member-only | Member card payment details when available. |
      | `payments.*.pointPaymentDetails` | `PointPaymentDetails` object | member-only | Member points payment details when available. |
      | `payments.*.creditPaymentsDetails` | `CreditPaymentDetails` object | member-only | Member credit payment details when available. |
      | `payments.*.items[]` | array of `ItemDetailEntry` | present when available | Item attribution for the payment. Each entry contains `checkItemId` and `quantity`; `checkItemId` references `check.items[].id`. |
      | `payments.*.addOns[]` | array of `PaymentAddOnLineItem` | present when available | Add-on line items associated with the payment. |
      | `check.dueAmountCents` | integer | always present | Required amount that has not been paid. |
      | `check.openTime` | date-time string | always present | Time the check was opened. |
      | `check.amountToTipOnCents` | integer | always present | Amount used to calculate tip options. |
      | `check.tipOptions[]` | array of `TipOption` | always present | Preset tip options. |
      | `check.points` | integer | always present | Estimated points earned for the check. |
      | `check.isPayable` | boolean | always present | Whether the check can be paid on the POS terminal. |
      | `check.isBarTab` | boolean | always present | Whether the check is part of the bar-tab flow. |
      | `check.displayNumber` | string | present when available | POS display number for the check. |
      | `check.tableNumber` | string | present when available | Table number from the POS system. |
      | `check.splitMode` | enum | present when available | How the check was split among payers. |
      | `check.paymentIntents[]` | array of `PaymentIntent` | present when available | Payment intents associated with the check. |
      | `check.houseAccounts[]` | array of `HouseAccount` | present when available | House accounts associated with the check. |
      | `check.amount`, `amountCents`, `taxAmount`, `taxAmountCents` | number/integer | present when available; deprecated | Legacy monetary fields. Use `checkAmounts` instead. |

      For an even split, guest `items[]` arrays are empty because no guest
      claimed specific items. For a per-item split, join each payment's
      `items[].checkItemId` to `check.items[].id`; `quantity` identifies the
      claimed quantity. Member-only fields are absent from guest payment
      entries, not merely empty placeholders.

      ### Identity and card data

      **Members only** (present when the diner paid signed in to Bilt):

      - Name, phone, email, and reward tier under
        `payments.mobileCheckoutMemberPayments.*.member`.

      **Never sent**:

      - Residence address, residence ZIP, billing/AVS ZIP, card BIN, or full
        PAN — not collected or retained by Bilt checkout.
      - Card brand/last four, and POS employee name/id, are not included.

      **Guests**:

      - No identity fields; correlate on `partnerUserId`.

      > **Note:** `orderClosed` and `closedOrderUpdated` are webhook-only
      > events. They are never surfaced as in-app SDK events.
  - name: Pay with points
    x-displayName: Pay with points
    description: |
      ## Pay with points

      This is an **optional** capability for partners that operate their
      own loyalty-points program. The intended flow is:

      - Your backend calls `POST /partner/cart/v1/checkout-sessions` with
        `user.partnerUserId`.
      - Bilt runs the embedded checkout experience.
      - Bilt calls the three partner-hosted endpoints documented in the
        `createCheckoutSession` callbacks below, server-to-server, keyed on
        that same `partnerUserId`.

      Configure the receiver URLs out of band with Bilt; they are not sent
      in the checkout-session request.

      ### Endpoints you implement

      #### `POST {$partnerPointsBalanceUrl}` — fetch points balance

      Bilt calls this server-to-server to load the partner user's current
      points balance and redemption rules for the checkout session.

      ```json
      {
        "partnerUserId": "ot-user-12345",
        "sessionId": "cs_9f3a",
        "currency": "USD"
      }
      ```

      ```json
      {
        "partnerUserId": "ot-user-12345",
        "pointsBalance": 12500,
        "conversionRate": {
          "points": 1000,
          "amountCents": 1000,
          "currency": "USD"
        },
        "minimumRedemptionPoints": 100,
        "maximumRedemptionPoints": 10000,
        "incrementPoints": 100,
        "expiresAt": "2026-07-21T12:05:00Z"
      }
      ```

      #### `POST {$partnerPointsSpendUrl}` — spend points

      Bilt calls this server-to-server, keyed on `partnerUserId`, to
      immediately debit points after the customer confirms checkout.

      ```json
      {
        "partnerUserId": "ot-user-12345",
        "sessionId": "cs_9f3a",
        "biltPaymentId": "pay_7f3b2a1c",
        "merchantId": "merchant-soho",
        "pointsToSpend": 2500,
        "redemptionValue": {
          "amountCents": 2500,
          "currency": "USD"
        },
        "idempotencyKey": "pts-spend-cs-9f3a-1"
      }
      ```

      ```json
      {
        "status": "succeeded",
        "partnerPointsTransactionId": "ot-pts-txn-789",
        "pointsSpent": 2500,
        "redemptionValue": {
          "amountCents": 2500,
          "currency": "USD"
        },
        "remainingPointsBalance": 10000
      }
      ```

      #### `POST {$partnerPointsRefundUrl}` — refund points

      Bilt calls this server-to-server, keyed on `partnerUserId`, to
      reverse points after a payment refund, failed payment, check
      cancellation, or support-issued adjustment.

      ```json
      {
        "partnerUserId": "ot-user-12345",
        "sessionId": "cs_9f3a",
        "biltPaymentId": "pay_7f3b2a1c",
        "originalPartnerPointsTransactionId": "ot-pts-txn-789",
        "pointsToRefund": 2500,
        "refundValue": {
          "amountCents": 2500,
          "currency": "USD"
        },
        "reason": "payment_failed_after_points_spend",
        "idempotencyKey": "pts-refund-cs-9f3a-1"
      }
      ```

      ```json
      {
        "status": "succeeded",
        "partnerPointsRefundTransactionId": "ot-pts-refund-456",
        "pointsRefunded": 2500,
        "refundValue": {
          "amountCents": 2500,
          "currency": "USD"
        },
        "updatedPointsBalance": 12500
      }
      ```

      ### Redemption flow

      1. The partner creates and launches a checkout session.
      2. Bilt fetches the partner user's points balance and conversion rate.
      3. If eligible, Bilt renders points as a tender. The customer applies
         some or all of their points, and the remainder can be paid with
         card, wallet, Bilt Cash, or Bilt Points.
      4. After the customer confirms, Bilt spends the points and records the
         returned partner transaction ID.
      5. Bilt processes the remaining amount and completes checkout.
      6. Full or partial refunds, payment failures after points were spent,
         merchant adjustments, check cancellations, and operational support
         refunds call the refund endpoint. Reconcile using the shared Bilt
         payment ID and partner transaction IDs.

      ### Payment sequencing

      Bilt spends points **first**, then processes the card portion for the
      remainder. There is no hold/capture model for partner points. If the
      card payment fails after points were spent, Bilt immediately calls the
      refund endpoint to reverse the points debit.

      Partial redemption is supported. For example, on an $80 order, the
      customer can pay $25 in points and the remaining $55 by card.

      ### Balance and eligibility

      The balance, conversion rate, minimum, maximum, and increment returned
      by the balance endpoint are the single source of truth. Do not send a
      pre-computed redeemable dollar amount that could disagree with those
      values. There is no separate `redeemable` balance; express caps with
      `maximumRedemptionPoints`.

      If eligibility varies by merchant, user, reservation, or market,
      return the final eligible amount from the balance endpoint. Bilt does
      not replicate partner eligibility logic.

      Bilt calls the balance endpoint when the checkout session loads,
      possibly again before final confirmation, and possibly after a failed
      spend. Spend and refund requests must be idempotent and support
      deterministic retries. Use the returned transaction IDs and shared
      `biltPaymentId` for reconciliation.
  - name: Embedding the checkout
    description: |
      ## Embedding the Bilt checkout in your app

      Your app never builds checkout UI. After your backend returns the
      handoff `token`, hand it to the Bilt checkout sheet and react to a
      single terminal outcome. Everything else — recognition, one-time
      codes, saved cards, Bilt credits/points, new-card entry, Apple Pay,
      3DS — is rendered and handled by the Bilt-hosted page.

      ### Handing over the token

      `POST /partner/cart/v1/checkout-sessions` returns
      `{ sessionId, token, expiresAt }` — there is no checkout URL. The
      checkout surface exchanges the `token` for the session context with
      `POST /public/cart/v1/checkout-sessions/redeem` on the consumer
      gateway, and the token stays valid until `expiresAt` or a terminal
      session status, so a redeem can be repeated inside that window.

      The Checkout Kit entry points shown below take the checkout **URL**
      form used by the Checkout SDK. Ask Bilt for the kit version whose
      entry point accepts a `cst_` handoff token when you wire the mobile
      layer.

      ### Recommended: Bilt Checkout SDK

      Bilt provides a native kit for **iOS** (`BiltCheckoutKit` — Swift
      Package / CocoaPods), **Android**
      (`com.biltrewards:checkout-sheet-kit` — Maven), and **React Native**
      (`@biltorg/checkout-kit` — npm). Each presents the checkout as a
      native sheet, projects cookies, passes through camera permissions
      (scan-to-pay / 3DS), handles `mailto:`/`tel:`/bank-app deep links,
      keeps a stable User-Agent, and is Apple Pay-safe (no injected
      JavaScript).

      Pick your platform for install/setup steps, a quick start, and the
      API — each has its own section below:

      - **Checkout Kit · iOS** — Swift Package Manager / CocoaPods
      - **Checkout Kit · Android** — Gradle / Maven Central
      - **Checkout Kit · React Native** — npm

      The same content is also in `docs/mobile-sdk.md`. The outcome model
      below is shared by all three platforms.

      ### Outcome vocabulary

      The SDK surfaces exactly these events. Treat webhooks — not these
      events — as the source of truth for payment state.

      | SDK event   | Meaning                                                        |
      | ----------- | -------------------------------------------------------------- |
      | `completed` | Payment succeeded. Carries `sessionId`, `orderId`.             |
      | `cancelled` | The customer cancelled the payment inside the sheet.              |
      | `expired`   | The session expired or reached a terminal status.              |
      | `error`     | The sheet failed to load or hit an unrecoverable error.        |
      | `close`     | The sheet was dismissed **without** a terminal outcome (swipe-down / hardware back). Distinct from `cancelled`. |

      ### UX notes

      - The one-time-code prompt (when shown) is an **inline module
        inside the checkout page**, not a screen your app renders or
        gates on.
      - `close` (sheet dismissed) is not the same as `cancelled` (payment
        cancelled). Decide your navigation for each.
      - The handoff `token` is not consumed by being presented, so the
        sheet can be reopened while the session is still `OPEN` and the
        token has not expired. Once the session expires or reaches a
        terminal status, request a **new** session from your backend.

      ### If you cannot use the SDK

      If you cannot adopt the kit on any platform, you may host the
      Bilt-hosted checkout page in a platform WebView yourself and bridge
      the `BILT_CHECKOUT_OUTCOME` `postMessage` to the same outcomes above —
      but the SDK is strongly recommended because it handles the WebView
      traps (camera passthrough, deep links, Apple Pay, stable UA)
      correctly. See `docs/mobile-sdk.md` for the bridge contract.

      ### WebView hardening

      If you host the checkout in your own WebView, enable JavaScript,
      restrict navigation to secure HTTPS origins, and disable external
      navigation so the customer remains within checkout. The Checkout SDK
      handles most of these protections for you.

      ### Licensing & attribution

      The Bilt Checkout Kits (React Native `@biltorg/checkout-kit` and the
      native iOS and Android layers) are derived from Shopify's
      [Checkout Sheet Kit](https://github.com/Shopify/checkout-sheet-kit-swift),
      which is distributed under the MIT License. In line with that
      license, the MIT permission text and the upstream copyright notice
      (`Copyright 2023 - Present, Shopify Inc.`) accompany the kits in
      their `LICENSE` and `NOTICE` files, alongside Bilt's own copyright
      for the portions it modified.

      Bilt Rewards is not affiliated with, sponsored by, or endorsed by
      Shopify Inc. "Shopify" is a trademark of Shopify Inc. and appears
      here solely to attribute the upstream project.

  - name: Checkout Kit · iOS
    description: |
      Presents Bilt-hosted checkout as a native sheet in a Swift app and
      reports the outcome through a delegate. **Requirements:** iOS 13+,
      Swift 5.9+.

      ## Installation

      **Swift Package Manager — `Package.swift`**

      ```swift
      dependencies: [
        .package(url: "https://github.com/biltrewards/checkout-kit-swift", from: "0.1.0")
      ]
      ```

      **Swift Package Manager — Xcode**

      1. Open your Xcode project.
      2. Choose `File` › `Add Package Dependencies…`.
      3. Paste `https://github.com/biltrewards/checkout-kit-swift` into the search field.
      4. Click **Add Package**.

      **CocoaPods — `Podfile`**

      ```ruby
      pod "BiltCheckoutKit", "~> 0.1"
      ```

      Then run `pod install`.

      ## Usage

      Configure once at app start (behavior only — the sheet's appearance is
      kit-controlled, with no title or color customization):

      ```swift
      import BiltCheckoutKit

      BiltCheckoutKit.configure {
          $0.logLevel = .error
          $0.autoDismissOnCompleted = true
      }
      ```

      Present from any view controller and handle outcomes through a delegate
      (every method has a default no-op — implement only what you need):

      ```swift
      BiltCheckoutKit.preload(checkout: checkoutURL)   // optional — warms the page
      BiltCheckoutKit.present(checkout: checkoutURL, from: self, delegate: self)

      extension CheckoutCoordinator: BiltCheckoutDelegate {
          func checkoutDidComplete(sessionId: String, orderId: String?) { showConfirmation(orderId) }
          func checkoutDidCancel(sessionId: String) { goBack() }
          func checkoutDidExpire(sessionId: String) { showFailure() }
          func checkoutDidClose() { goBack() }
          func checkoutDidFail(code: String, message: String, statusCode: Int?) { showFailure() }
      }
      ```

      ## Deep links (bank apps / 3DS)

      `canOpenURL` returns `false` for schemes your app has not declared. If
      your flow relies on specific bank apps, add their schemes to
      `LSApplicationQueriesSchemes` in `Info.plist`, or the handoff silently
      falls back to the page's web flow.

      ## API

      | Member | Description |
      | --- | --- |
      | `BiltCheckoutKit.configure(_:)` / `.configuration` | Behavior config; set once at app start. |
      | `present(checkout:from:delegate:)` | Present the sheet; returns the `BiltCheckoutViewController`. |
      | `preload(checkout:)` | Warm the URL in a background WebView. |
      | `invalidate()` | Discard the preloaded WebView, if any. |
      | `version` | SDK version string (e.g. `"0.1.0"`). |

  - name: Checkout Kit · Android
    description: |
      Presents Bilt-hosted checkout as a managed sheet and reports the
      outcome through a `CheckoutEventProcessor`. **Requirements:** Android
      SDK 23+, Java 8+.

      ## Installation

      **Gradle — `build.gradle`**

      ```groovy
      dependencies {
          implementation "com.biltrewards:checkout-sheet-kit:0.1.0"
      }
      ```

      **Maven — `pom.xml`**

      ```xml
      <dependency>
        <groupId>com.biltrewards</groupId>
        <artifactId>checkout-sheet-kit</artifactId>
        <version>0.1.0</version>
      </dependency>
      ```

      Ensure `minSdkVersion` is at least `23`:

      ```diff
      // app/build.gradle
      android {
          defaultConfig {
      -       minSdkVersion 21
      +       minSdkVersion 23
          }
      }
      ```

      ## Usage

      Configure once at app start (optional):

      ```kotlin
      BiltCheckoutSheetKit.configure {
          it.logLevel = LogLevel.ERROR
          it.autoDismissOnCompleted = true
      }
      ```

      Subclass `DefaultCheckoutEventProcessor` — it supplies sensible
      defaults for external links and camera/mic permissions — and override
      the outcomes you care about:

      ```kotlin
      class CheckoutActivity : ComponentActivity() {

          private val processor = object : DefaultCheckoutEventProcessor(this) {
              override fun onCheckoutCompleted(sessionId: String, orderId: String?) { /* confirmation UI */ }
              override fun onCheckoutCancelled(sessionId: String?) { goBack() }
              override fun onCheckoutExpired(sessionId: String?) { showFailure() }
              override fun onCheckoutClosed() { goBack() }
              override fun onCheckoutFailed(error: BiltCheckoutError) { showFailure() }
          }

          fun startCheckout(checkoutUrl: String) {
              BiltCheckoutSheetKit.preload(checkoutUrl, this)   // optional
              BiltCheckoutSheetKit.present(checkoutUrl, this, processor)
          }
      }
      ```

      ## Deep links (bank apps / 3DS)

      Android 11+ package-visibility rules apply to intent resolution. If
      your flow relies on specific bank apps, declare the relevant schemes in
      a `<queries>` element in your `AndroidManifest.xml`.

      ## API

      All entry points live on the `BiltCheckoutSheetKit` object:

      | Member | Description |
      | --- | --- |
      | `present(url, activity, processor)` | Present the sheet; returns a `BiltCheckoutSheetDialog` handle for programmatic dismissal. |
      | `preload(url, activity)` | Warm the URL in a background WebView. |
      | `invalidate()` | Discard the preloaded WebView, if any. |
      | `configure { }` / `getConfiguration()` | Apply / read behavioral configuration. |
      | `version` | SDK version string. |

  - name: Checkout Kit · React Native
    description: |
      Presents Bilt-hosted checkout as a native sheet with typed lifecycle
      events, using the native iOS/Android layers underneath.
      **Requirements:** React Native 0.76+ with the **New Architecture**
      (TurboModules); iOS 13+; Android SDK 23+.

      ## Installation

      ```sh
      npm install @biltorg/checkout-kit
      # or: pnpm add @biltorg/checkout-kit  /  yarn add @biltorg/checkout-kit
      ```

      ### Minimum Android version

      Ensure `minSdkVersion` is at least `23` in `android/build.gradle`:

      ```diff
      buildscript {
          ext {
      -       minSdkVersion = 21
      +       minSdkVersion = 23
          }
      }
      ```

      ### Minimum iOS version, then install pods

      Ensure `platform :ios` in `ios/Podfile` is at least `13`:

      ```diff
      # ios/Podfile
      - platform :ios, min_ios_version_supported
      + platform :ios, 13
      ```

      ```sh
      cd ios && pod install
      ```

      ## Usage

      Construct once and reuse it — a configuration change invalidates the
      preload cache, so a per-screen instance would discard warmed checkouts.

      ```tsx
      import { BiltCheckoutKit } from '@biltorg/checkout-kit';

      export const checkout = new BiltCheckoutKit({ logLevel: 'error' });
      ```

      Present and handle outcomes:

      ```tsx
      useEffect(() => {
        const subs = [
          checkout.addEventListener('completed', e => showConfirmation(e.orderId)),
          checkout.addEventListener('cancelled', () => goBack()),
          checkout.addEventListener('expired',   () => showFailure()),
          checkout.addEventListener('error',     e => reportError(e.code, e.message)),
          checkout.addEventListener('close',     () => goBack()),
        ];
        return () => subs.forEach(s => s.remove());
      }, []);

      checkout.preload(checkoutUrl); // optional
      checkout.present(checkoutUrl);
      ```

      ## API

      | Member | Description |
      | --- | --- |
      | `new BiltCheckoutKit(config?)` | Construct once. `config`: `{ logLevel?, autoDismissOnCompleted?, legacyWebViewBridgeCompat? }`. |
      | `present(checkoutUrl)` | Present the sheet; reuses a matching preloaded WebView. |
      | `preload(checkoutUrl)` | Warm the URL in a background WebView. |
      | `invalidate()` / `dismiss()` | Drop the preload / dismiss the sheet. |
      | `addEventListener(event, cb)` | Subscribe; returns a subscription with `.remove()`. |
      | `removeEventListeners(event)` / `teardown()` | Remove listeners for one / all events. |
      | `version` | Native SDK version string. |

paths:
  /partner/cart/v1/checkout-sessions:
    post:
      summary: Open a checkout session
      description: |
        Creates a Bilt-hosted checkout session for a customer and returns the
        short-lived handoff `token` your app passes to the Bilt checkout.

        Call this server-to-server from your backend when the customer is
        ready to pay. Recognition of a returning customer happens inside the
        Bilt-hosted page; the request and response shape are identical
        whether or not the customer already has a Bilt account.

        Session TTL is configurable per partner and defaults to 30 minutes.
        The returned `expiresAt` is when both the session and its handoff
        token expire. The raw `token` is returned **only** in this response —
        Bilt stores only its SHA-256 hash.

        **Check resolution.** Supply `lookupUrl` (the table/QR check-lookup
        URL) for the scan-to-pay flow, or
        `metadata.reservationExternalId` when the checkout starts from a
        partner reservation. Bilt resolves the check and the merchant from
        whichever you send.

        Bilt delivers the outcome asynchronously via the webhooks listed under **Webhooks**.

        **Idempotency.** Supply an `Idempotency-Key` header carrying a
        fresh UUID per checkout attempt. A retry with the same key returns
        the same session with a freshly minted handoff token rather than
        creating a new one; reusing a key for a different
        `user.partnerUserId` is rejected with `409 IDEMPOTENCY_KEY_REUSED`.

        **Error codes.** Error responses use these machine-readable codes:

        - `INVALID_REQUEST` (`400`) — the request is invalid (for example a
          missing `Idempotency-Key` or `user.partnerUserId`).
        - `UNAUTHORIZED` (`401`) — the access token is missing, expired, or
          not issued for this API.
        - `IDEMPOTENCY_KEY_REUSED` (`409`) — the key was already used for a
          different user.
        - `SESSION_TERMINAL` (`409`) — the session the key identifies is
          already in a terminal state.
        - `MERCHANT_NOT_ALLOWED` (`403`) — the merchant is not enabled for
          this partner.
        - `NO_ACTIVE_CHECK` (`404`) — no open check was found for the
          supplied `lookupUrl` or reservation.
      operationId: createCheckoutSession
      tags:
        - Checkout Sessions
      security:
        - partnerOAuth:
            - cart:sessions:write
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCheckoutSessionRequest'
      responses:
        '201':
          description: Checkout session created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckoutSession'
        '400':
          description: Invalid request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: INVALID_REQUEST
                  message: user.partnerUserId is required
        '401':
          description: Missing, expired, or wrong-audience access token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: UNAUTHORIZED
                  message: Missing or invalid access token
        '403':
          description: |
            The access token lacks the required scope, or the merchant is not
            enabled for this partner.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: MERCHANT_NOT_ALLOWED
                  message: Merchant is not enabled for this partner
        '404':
          description: No open check was found to pay
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: NO_ACTIVE_CHECK
                  message: No active check found for this customer
        '409':
          description: Idempotency-Key conflict, or the session is terminal
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                idempotencyKeyReused:
                  value:
                    error:
                      code: IDEMPOTENCY_KEY_REUSED
                      message: Idempotency-Key was already used for a different user
                sessionTerminal:
                  value:
                    error:
                      code: SESSION_TERMINAL
                      message: Checkout session is already in a terminal state
        '429':
          description: |
            Too many requests. Gateway-enforced; no per-partner quota is
            published — retry with backoff, honouring `Retry-After` when it
            is present.
          headers:
            Retry-After:
              description: Number of seconds to wait before retrying.
              schema:
                type: integer
                format: int32
                minimum: 1
      callbacks:
        partnerPointsBalance:
          '{$partnerPointsBalanceUrl}':
            post:
              summary: Fetch partner points balance
              security: []
              description: |
                Bilt calls this partner-hosted endpoint when the checkout
                session loads, possibly again before final confirmation,
                and possibly after a failed spend. Configure the receiver
                URL out of band with Bilt; it is not sent in the checkout
                session request.

                Return the final balance, conversion rate, minimum,
                maximum, and increment for this user and context. These
                values are the single source of truth. Do not return a
                pre-computed redeemable dollar amount that could disagree
                with them. There is no separate redeemable balance;
                express caps through `maximumRedemptionPoints`.
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/PartnerPointsBalanceRequest'
              responses:
                '200':
                  description: Current points balance and redemption rules
                  content:
                    application/json:
                      schema:
                        $ref: '#/components/schemas/PartnerPointsBalanceResponse'
        partnerPointsSpend:
          '{$partnerPointsSpendUrl}':
            post:
              summary: Spend partner points
              security: []
              description: |
                Bilt calls this partner-hosted endpoint to immediately debit
                points after the customer confirms. Partner points use no
                hold/capture model. The request must be idempotent and
                retries with the same `idempotencyKey` must have a
                deterministic result.

                Bilt spends points before processing the card portion. If
                the card payment fails after points were spent, Bilt
                immediately calls the refund endpoint. If the balance
                changed, return a structured
                `declined_insufficient_balance` response so Bilt can
                refresh the displayed balance.
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/PartnerPointsSpendRequest'
              responses:
                '200':
                  description: Point spend result
                  content:
                    application/json:
                      schema:
                        $ref: '#/components/schemas/PartnerPointsSpendResponse'
        partnerPointsRefund:
          '{$partnerPointsRefundUrl}':
            post:
              summary: Refund partner points
              security: []
              description: |
                Bilt calls this partner-hosted endpoint for full or partial
                payment refunds, payment failures after points were spent,
                merchant adjustments or check cancellations, and operational
                support refunds. Configure the receiver URL out of band with
                Bilt; it is not sent in the checkout session request.

                The request must be idempotent and support partial refunds.
                When a refund is initiated, Bilt sends the refund request to
                the partner immediately; there is no delay on Bilt's side.
                The partner decides when the refunded points are redeposited
                to the customer's balance. Refunds reverse points at the same
                conversion rate as the original redemption.
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/PartnerPointsRefundRequest'
              responses:
                '200':
                  description: Point refund result
                  content:
                    application/json:
                      schema:
                        $ref: '#/components/schemas/PartnerPointsRefundResponse'

  /partner/cart/v1/checkout-sessions/{sessionId}/cancel:
    post:
      summary: Cancel a checkout session
      description: |
        Cancels an active checkout session, for example when the customer
        abandons checkout before completing payment. A session that
        is already in a terminal state cannot be cancelled. Sessions you do
        not cancel expire on their own at `expiresAt`.
      operationId: cancelCheckoutSession
      tags:
        - Checkout Sessions
      security:
        - partnerOAuth:
            - cart:sessions:write
      parameters:
        - name: sessionId
          in: path
          required: true
          description: The `sessionId` to cancel.
          schema:
            type: string
            example: cs_9f3a
      responses:
        '200':
          description: Checkout session cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckoutSessionStatus'
              example:
                sessionId: cs_9f3a
                status: CANCELLED
        '401':
          description: Missing, expired, or wrong-audience access token
        '404':
          description: No session with that id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: SESSION_NOT_FOUND
                  message: No checkout session found for sessionId
        '409':
          description: Session is already in a terminal state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: SESSION_TERMINAL
                  message: Checkout session is already in a terminal state
        '429':
          description: |
            Too many requests. Gateway-enforced; no per-partner quota is
            published — retry with backoff, honouring `Retry-After` when it
            is present.
          headers:
            Retry-After:
              description: Number of seconds to wait before retrying.
              schema:
                type: integer
                format: int32
                minimum: 1

  /public/cart/v1/checkout-sessions/redeem:
    post:
      summary: Redeem a handoff token
      description: |
        Exchanges the handoff `token` from the create response for the
        checkout session context. **The Bilt checkout surface calls this —
        your backend and your app do not.** It is documented here so the
        handoff is fully described.

        The token travels in the body, not the URL, to keep it out of access
        logs, browser history, and `Referer` headers. The call is authorized
        solely by the token: no partner credential and no user identity are
        accepted. Redemption does **not** consume the token — it stays valid
        until `expiresAt` or a terminal session status, after which the call
        fails with `401`.

        This route is on the consumer gateway, not the partner gateway.
      operationId: redeemCheckoutSession
      tags:
        - Checkout Sessions
      security: []
      servers:
        - url: https://api.biltrewards.com
          description: Production — consumer gateway
        - url: https://staging.api.biltrewards.com
          description: Staging — consumer gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RedeemSessionRequest'
      responses:
        '200':
          description: Session redeemed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CartSessionDetails'
        '401':
          description: Unknown token, or the session is expired or terminal
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: SESSION_INVALID_TOKEN
                  message: Invalid session token

  /public/cart/v1/checkout-sessions/{sessionId}:
    get:
      summary: Get a checkout session
      description: |
        Reads the session context by id, authorized with the session token as
        `Authorization: Bearer <token>`.

        The Bilt-hosted checkout page uses this route. Partners do not call
        it — track state through the checkout outcome and webhooks rather
        than by polling.
      operationId: getCheckoutSession
      tags:
        - Checkout Sessions
      security: []
      parameters:
        - name: sessionId
          in: path
          required: true
          description: The opaque `cs_` session id.
          schema:
            type: string
            example: cs_9f3a
        - name: Authorization
          in: header
          required: true
          description: The session handoff token as `Bearer <token>`.
          schema:
            type: string
      responses:
        '200':
          description: Session found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CartSessionDetails'
        '401':
          description: The token does not match the session
        '404':
          description: No session with that id

webhooks:
  checkoutSessionCompleted:
    post:
      summary: checkout.session.completed
      operationId: webhookCheckoutSessionCompleted
      tags:
        - Webhooks
      security: []
      description: |
        Published once, after the session's payment has been captured and
        the session is committed as `COMPLETED`. Bilt POSTs it to the HTTPS
        endpoint you register. See the Webhooks section above for
        signature, idempotency, and retry rules.
      parameters:
        - $ref: '#/components/parameters/WebhookId'
        - $ref: '#/components/parameters/WebhookTimestamp'
        - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutSessionWebhookEvent'
            examples:
              completed:
                summary: Completed checkout session
                value:
                  type: checkout.session.completed
                  timestamp: '2026-09-10T14:31:02.418206311Z'
                  data:
                    sessionId: 7c1f4d2e-9a3b-4c5d-8e6f-0a1b2c3d4e5f
                    status: COMPLETED
                    orderId: 3f9e8d7c-6b5a-4b3c-9d2e-1f0a9b8c7d6e
                    configId: 0c164cc0-9aa4-4054-b999-472ed4b75bc5
                    merchantCatalogId: 5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a
                    checkoutPaymentId: 9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d
      responses:
        '2xx':
          description: |
            Acknowledged. A timeout, transport error, `408`, `425`, `429`, or
            `5xx` is retried for 48 hours; any other non-2xx is treated as a
            rejection and not retried.
  checkoutSessionCancelled:
    post:
      summary: checkout.session.cancelled
      operationId: webhookCheckoutSessionCancelled
      tags:
        - Webhooks
      security: []
      description: |
        Published after the session is committed as `CANCELLED` (the
        customer or your backend cancelled it, or the payment attempt was
        abandoned) without a successful payment. Bilt POSTs it to the HTTPS
        endpoint you register. See the Webhooks section above for
        signature, idempotency, and retry rules.
      parameters:
        - $ref: '#/components/parameters/WebhookId'
        - $ref: '#/components/parameters/WebhookTimestamp'
        - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutSessionWebhookEvent'
            examples:
              cancelled:
                summary: Cancelled checkout session
                value:
                  type: checkout.session.cancelled
                  timestamp: '2026-09-10T14:34:18.986759998Z'
                  data:
                    sessionId: 2dfdb0f5-a072-4114-a8ee-7b1f2872886a
                    status: CANCELLED
                    orderId: 955648d7-1926-4b0e-82ba-0b5b2a664de6
                    configId: 0c164cc0-9aa4-4054-b999-472ed4b75bc5
                    merchantCatalogId: null
                    checkoutPaymentId: null
      responses:
        '2xx':
          description: |
            Acknowledged. A timeout, transport error, `408`, `425`, `429`, or
            `5xx` is retried for 48 hours; any other non-2xx is treated as a
            rejection and not retried.
  checkoutSessionExpired:
    post:
      summary: checkout.session.expired
      operationId: webhookCheckoutSessionExpired
      tags:
        - Webhooks
      security: []
      description: |
        Published after the session passes `expiresAt` without completing
        and is committed as `EXPIRED`. Bilt POSTs it to the HTTPS endpoint
        you register. See the Webhooks section above for signature,
        idempotency, and retry rules.
      parameters:
        - $ref: '#/components/parameters/WebhookId'
        - $ref: '#/components/parameters/WebhookTimestamp'
        - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutSessionWebhookEvent'
            examples:
              expired:
                summary: Expired checkout session
                value:
                  type: checkout.session.expired
                  timestamp: '2026-09-10T14:36:23.032713842Z'
                  data:
                    sessionId: 6b1aa2d2-04cb-4960-ae13-2d4b23e04517
                    status: EXPIRED
                    orderId: 85eecc35-81f7-48b4-81c6-c482854a16ce
                    configId: 0c164cc0-9aa4-4054-b999-472ed4b75bc5
                    merchantCatalogId: null
                    checkoutPaymentId: null
      responses:
        '2xx':
          description: |
            Acknowledged. A timeout, transport error, `408`, `425`, `429`, or
            `5xx` is retried for 48 hours; any other non-2xx is treated as a
            rejection and not retried.
  checkoutSessionReversed:
    post:
      summary: checkout.session.reversed
      operationId: webhookCheckoutSessionReversed
      tags:
        - Webhooks
      security: []
      description: |
        Published after a previously completed session's payment has been
        reversed (a refund or abort through the integrator refund API) and
        the session is committed as `REVERSED`. It always follows an
        earlier `checkout.session.completed` for the same `sessionId` and
        carries the same `checkoutPaymentId`. Bilt POSTs it to the HTTPS
        endpoint you register. See the Webhooks section above for
        signature, idempotency, and retry rules.
      parameters:
        - $ref: '#/components/parameters/WebhookId'
        - $ref: '#/components/parameters/WebhookTimestamp'
        - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutSessionWebhookEvent'
            examples:
              reversed:
                summary: Reversed checkout session
                value:
                  type: checkout.session.reversed
                  timestamp: '2026-09-11T09:12:44.107553019Z'
                  data:
                    sessionId: 7c1f4d2e-9a3b-4c5d-8e6f-0a1b2c3d4e5f
                    status: REVERSED
                    orderId: 3f9e8d7c-6b5a-4b3c-9d2e-1f0a9b8c7d6e
                    configId: 0c164cc0-9aa4-4054-b999-472ed4b75bc5
                    merchantCatalogId: 5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a
                    checkoutPaymentId: 9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d
      responses:
        '2xx':
          description: |
            Acknowledged. A timeout, transport error, `408`, `425`, `429`, or
            `5xx` is retried for 48 hours; any other non-2xx is treated as a
            rejection and not retried.
  orderClosed:
    post:
      summary: orderClosed
      operationId: webhookOrderClosed
      tags:
        - Webhooks
      security: []
      description: |
        Bilt POSTs this event to the HTTPS endpoint you register with Bilt.
        See the Webhooks section above for signature, idempotency, and retry
        rules.
      parameters:
        - $ref: '#/components/parameters/WebhookId'
        - $ref: '#/components/parameters/WebhookTimestamp'
        - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEvent'
            examples:
              singlePayer:
                summary: "Non-split check \u2014 single member card payment"
                description: One diner pays the full check while signed in to Bilt. `member` carries the diner identity
                  fields shared with the merchant; `mobileCheckoutGuestPayments` is empty.
                value:
                  type: orderClosed
                  timestamp: '2025-10-20T16:37:43Z'
                  data:
                    sessionId: cs_check_closed_example
                    partnerUserId: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
                    check:
                      id: 07d09ebb-44f8-4dac-86a8-85e0184d00f7
                      thirdPartyIds:
                        platform: TOAST
                        locationId: 1a2b3c4d-5e6f-4789-a012-3456789abcde
                        orderId: 2b3c4d5e-6f70-489a-b123-456789abcdef
                        checkId: 3c4d5e6f-7081-49ab-c234-56789abcdef0
                      checkState: completed
                      splitMode: NONE
                      checkAmounts:
                        subtotalAmountCents: 22400
                        taxAmountCents: 1988
                        requiredTipsTotalAmountCents: 0
                        requiredTotalAmountCents: 24388
                        preDiscountSubtotalAmountCents: 22400
                      items:
                      - id: 84a0a20f-3bde-44b4-a1fc-d1ad831e4669
                        thirdPartyItemId: 47bac383-f81b-5f1e-928a-e9804c2d8a4b
                        name: Club Soda
                        quantity: 1
                        amounts:
                          netCostCents: 500
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 5
                        cost: 5.0
                        costCents: 500
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: c99d01c7-9d8b-42c4-84bc-11ffebdedc1f
                        thirdPartyItemId: 05aaa8b8-ef68-5042-a36e-f747262b5f81
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43986da9-9093-4b56-a33e-fdef62bdef20
                        thirdPartyItemId: 5d589921-a3da-5f9a-be69-8abfe0f5d5ac
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 704a4a70-419a-477c-a847-28a3142ed97e
                        thirdPartyItemId: 760e7988-f82e-51a3-bf57-c3c05e62cb56
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 3fc8aa56-f03c-4ac4-87fd-fe5a9ff0dc19
                        thirdPartyItemId: 06d366fa-73f8-51c6-8c2c-cfed7bb819b0
                        name: Baba Ghannouge
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: b9308a50-6d2c-4431-a761-cd7fb4308527
                        thirdPartyItemId: b35d2db4-f1cc-5e15-92c9-21a2903db8fb
                        name: Hommus
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: cb116c7d-54c3-4cb4-9a6b-eba19458ca74
                        thirdPartyItemId: ff4a0583-de67-5f32-8f42-fc39a48f09a5
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: bb3c8f9a-0b9e-49cf-b9bf-9ae5fffc079f
                        thirdPartyItemId: 750b85c5-ef47-579e-9a65-71a6dd6a3b30
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: ecb66e00-27de-4352-8b24-d3591e0eca40
                        thirdPartyItemId: 648a7cbf-3ca4-5d3c-9730-d91d74b54a8c
                        name: Bread
                        quantity: 2
                        amounts:
                          netCostCents: 0
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 0
                        cost: 0.0
                        costCents: 0
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: d7a7663d-46d5-4e55-8e10-ed71293b58b9
                        thirdPartyItemId: a5825b12-92f1-5814-8ac0-ed49b1c27cc4
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43f160b5-742a-4f02-acf0-fcc2a0d8fe83
                        thirdPartyItemId: 05a78766-d7a8-5eb8-a701-1d5a7ab4814e
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: e55b7f47-da57-4d20-b148-ca127a9a47c1
                        thirdPartyItemId: d890b23f-6e44-5bb7-abf7-2130c0ce8c45
                        name: Gl Breuil
                        quantity: 3
                        amounts:
                          netCostCents: 6300
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 63
                        cost: 63.0
                        costCents: 6300
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 98d3c225-5659-42d0-b840-936fe0e18cc9
                        thirdPartyItemId: 0679068b-75c2-51ca-a5e3-414816745d68
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      discounts: []
                      requiredTips: []
                      otherServiceCharges: []
                      payments:
                        mobileCheckoutMemberPayments:
                        - amountDetails:
                            paidTotalAmountCents: 29316
                            paidRequiredAmountCents: 24388
                            paidElectiveTipAmountCents: 4928
                            paidEstimatedSubtotalAmountCents: 22400
                            paidEstimatedTaxAmountCents: 1988
                          cardPaymentDetails:
                            isBiltCard: true
                          pointPaymentDetails:
                            points: 0
                          creditPaymentsDetails: []
                          biltMemberId: 4e6a2d91-7b35-4c08-a9f2-1d6e8b3c5a70
                          member:
                            firstName: Jordan
                            lastName: Lee
                            phone: '+14155550123'
                            email: jordan.lee@example.com
                            rewardTier: GOLD
                          estimatedPointsEarned: 293
                          status: Completed
                          paymentId: 7c3e6e20-2c44-4fd3-9c6c-9b8ec1f4a7d2
                          addOns: []
                          items: []
                        mobileCheckoutGuestPayments: []
                        thirdPartyCardPayments: []
                        thirdPartyCashPayments: []
                        thirdPartyUncategorizedPayments: []
                        houseAccountPayments: []
                        payForGuestPayments: []
                      dueAmountCents: 0
                      openTime: '2025-10-20T16:37:43Z'
                      amountToTipOnCents: 22400
                      tipOptions:
                      - displayName: 20%
                        tipPercent: 20
                        tipAmountCents: 4480
                        isDefault: false
                      - displayName: 22%
                        tipPercent: 22
                        tipAmountCents: 4928
                        isDefault: true
                      - displayName: 25%
                        tipPercent: 25
                        tipAmountCents: 5600
                        isDefault: false
                      points: 224
                      isPayable: false
                      isBarTab: false
                      displayNumber: '1940'
                      paymentIntents: []
                      houseAccounts: []
                      tableNumber: '61'
                      amount: 224.0
                      amountCents: 22400
                      taxAmount: 19.88
                      taxAmountCents: 1988
                    merchantId: 59fa7945-29a0-409b-8202-e8e4e817d304
              evenSplit:
                summary: Even split check
                description: Each guest payment has an empty items array because no guest claimed specific items.
                value:
                  type: orderClosed
                  timestamp: '2025-10-20T16:37:43Z'
                  data:
                    sessionId: cs_check_closed_example
                    partnerUserId: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
                    check:
                      id: 07d09ebb-44f8-4dac-86a8-85e0184d00f7
                      thirdPartyIds:
                        platform: TOAST
                        locationId: 1a2b3c4d-5e6f-4789-a012-3456789abcde
                        orderId: 2b3c4d5e-6f70-489a-b123-456789abcdef
                        checkId: 3c4d5e6f-7081-49ab-c234-56789abcdef0
                      checkState: completed
                      splitMode: EVEN_SPLIT
                      checkAmounts:
                        subtotalAmountCents: 22400
                        taxAmountCents: 1988
                        requiredTipsTotalAmountCents: 0
                        requiredTotalAmountCents: 24388
                        preDiscountSubtotalAmountCents: 22400
                      items:
                      - id: 84a0a20f-3bde-44b4-a1fc-d1ad831e4669
                        thirdPartyItemId: 47bac383-f81b-5f1e-928a-e9804c2d8a4b
                        name: Club Soda
                        quantity: 1
                        amounts:
                          netCostCents: 500
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 5
                        cost: 5.0
                        costCents: 500
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: c99d01c7-9d8b-42c4-84bc-11ffebdedc1f
                        thirdPartyItemId: 05aaa8b8-ef68-5042-a36e-f747262b5f81
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43986da9-9093-4b56-a33e-fdef62bdef20
                        thirdPartyItemId: 5d589921-a3da-5f9a-be69-8abfe0f5d5ac
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 704a4a70-419a-477c-a847-28a3142ed97e
                        thirdPartyItemId: 760e7988-f82e-51a3-bf57-c3c05e62cb56
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 3fc8aa56-f03c-4ac4-87fd-fe5a9ff0dc19
                        thirdPartyItemId: 06d366fa-73f8-51c6-8c2c-cfed7bb819b0
                        name: Baba Ghannouge
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: b9308a50-6d2c-4431-a761-cd7fb4308527
                        thirdPartyItemId: b35d2db4-f1cc-5e15-92c9-21a2903db8fb
                        name: Hommus
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: cb116c7d-54c3-4cb4-9a6b-eba19458ca74
                        thirdPartyItemId: ff4a0583-de67-5f32-8f42-fc39a48f09a5
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: bb3c8f9a-0b9e-49cf-b9bf-9ae5fffc079f
                        thirdPartyItemId: 750b85c5-ef47-579e-9a65-71a6dd6a3b30
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: ecb66e00-27de-4352-8b24-d3591e0eca40
                        thirdPartyItemId: 648a7cbf-3ca4-5d3c-9730-d91d74b54a8c
                        name: Bread
                        quantity: 2
                        amounts:
                          netCostCents: 0
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 0
                        cost: 0.0
                        costCents: 0
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: d7a7663d-46d5-4e55-8e10-ed71293b58b9
                        thirdPartyItemId: a5825b12-92f1-5814-8ac0-ed49b1c27cc4
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43f160b5-742a-4f02-acf0-fcc2a0d8fe83
                        thirdPartyItemId: 05a78766-d7a8-5eb8-a701-1d5a7ab4814e
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: e55b7f47-da57-4d20-b148-ca127a9a47c1
                        thirdPartyItemId: d890b23f-6e44-5bb7-abf7-2130c0ce8c45
                        name: Gl Breuil
                        quantity: 3
                        amounts:
                          netCostCents: 6300
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 63
                        cost: 63.0
                        costCents: 6300
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 98d3c225-5659-42d0-b840-936fe0e18cc9
                        thirdPartyItemId: 0679068b-75c2-51ca-a5e3-414816745d68
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      discounts: []
                      requiredTips: []
                      otherServiceCharges: []
                      payments:
                        mobileCheckoutMemberPayments: []
                        mobileCheckoutGuestPayments:
                        - amountDetails:
                            paidTotalAmountCents: 14658
                            paidRequiredAmountCents: 12194
                            paidElectiveTipAmountCents: 2464
                            paidEstimatedSubtotalAmountCents: 11200
                            paidEstimatedTaxAmountCents: 994
                          guestPaymentMethodDetails:
                            type: APPLE_PAY
                          status: Completed
                          paymentId: 1a75f0e0-1f5d-4379-b56f-23b66fb541a0
                          anonymousUserId: 45171b6d-e844-4c6f-85af-0fa1ebed0ad7
                          addOns: []
                          items: []
                        - amountDetails:
                            paidTotalAmountCents: 14658
                            paidRequiredAmountCents: 12194
                            paidElectiveTipAmountCents: 2464
                            paidEstimatedSubtotalAmountCents: 11200
                            paidEstimatedTaxAmountCents: 994
                          guestPaymentMethodDetails:
                            type: CREDIT_CARD
                          status: Completed
                          paymentId: edf506b5-0c0a-453e-ade4-a6d222bac5bb
                          anonymousUserId: 84ce9f8a-12cb-4fac-a6ac-6d415413841d
                          addOns: []
                          items: []
                        thirdPartyCardPayments: []
                        thirdPartyCashPayments: []
                        thirdPartyUncategorizedPayments: []
                        houseAccountPayments: []
                        payForGuestPayments: []
                      dueAmountCents: 0
                      openTime: '2025-10-20T16:37:43Z'
                      amountToTipOnCents: 22400
                      tipOptions:
                      - displayName: 20%
                        tipPercent: 20
                        tipAmountCents: 4480
                        isDefault: false
                      - displayName: 22%
                        tipPercent: 22
                        tipAmountCents: 4928
                        isDefault: true
                      - displayName: 25%
                        tipPercent: 25
                        tipAmountCents: 5600
                        isDefault: false
                      points: 224
                      isPayable: false
                      isBarTab: false
                      displayNumber: '1940'
                      paymentIntents: []
                      houseAccounts: []
                      tableNumber: '61'
                      amount: 224.0
                      amountCents: 22400
                      taxAmount: 19.88
                      taxAmountCents: 1988
                    merchantId: 59fa7945-29a0-409b-8202-e8e4e817d304
              perItemSplit:
                summary: Per-item split check
                description: Each guest payment identifies claimed quantities by checkItemId, joined to check.items[].id.
                value:
                  type: orderClosed
                  timestamp: '2025-10-20T16:37:43Z'
                  data:
                    sessionId: cs_check_closed_example
                    partnerUserId: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
                    check:
                      id: 07d09ebb-44f8-4dac-86a8-85e0184d00f7
                      thirdPartyIds:
                        platform: TOAST
                        locationId: 1a2b3c4d-5e6f-4789-a012-3456789abcde
                        orderId: 2b3c4d5e-6f70-489a-b123-456789abcdef
                        checkId: 3c4d5e6f-7081-49ab-c234-56789abcdef0
                      checkState: completed
                      splitMode: BY_ITEM
                      checkAmounts:
                        subtotalAmountCents: 22400
                        taxAmountCents: 1988
                        requiredTipsTotalAmountCents: 0
                        requiredTotalAmountCents: 24388
                        preDiscountSubtotalAmountCents: 22400
                      items:
                      - id: 84a0a20f-3bde-44b4-a1fc-d1ad831e4669
                        thirdPartyItemId: 47bac383-f81b-5f1e-928a-e9804c2d8a4b
                        name: Club Soda
                        quantity: 1
                        amounts:
                          netCostCents: 500
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 5
                        cost: 5.0
                        costCents: 500
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: c99d01c7-9d8b-42c4-84bc-11ffebdedc1f
                        thirdPartyItemId: 05aaa8b8-ef68-5042-a36e-f747262b5f81
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43986da9-9093-4b56-a33e-fdef62bdef20
                        thirdPartyItemId: 5d589921-a3da-5f9a-be69-8abfe0f5d5ac
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 704a4a70-419a-477c-a847-28a3142ed97e
                        thirdPartyItemId: 760e7988-f82e-51a3-bf57-c3c05e62cb56
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 3fc8aa56-f03c-4ac4-87fd-fe5a9ff0dc19
                        thirdPartyItemId: 06d366fa-73f8-51c6-8c2c-cfed7bb819b0
                        name: Baba Ghannouge
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: b9308a50-6d2c-4431-a761-cd7fb4308527
                        thirdPartyItemId: b35d2db4-f1cc-5e15-92c9-21a2903db8fb
                        name: Hommus
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: cb116c7d-54c3-4cb4-9a6b-eba19458ca74
                        thirdPartyItemId: ff4a0583-de67-5f32-8f42-fc39a48f09a5
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: bb3c8f9a-0b9e-49cf-b9bf-9ae5fffc079f
                        thirdPartyItemId: 750b85c5-ef47-579e-9a65-71a6dd6a3b30
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: ecb66e00-27de-4352-8b24-d3591e0eca40
                        thirdPartyItemId: 648a7cbf-3ca4-5d3c-9730-d91d74b54a8c
                        name: Bread
                        quantity: 2
                        amounts:
                          netCostCents: 0
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 0
                        cost: 0.0
                        costCents: 0
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: d7a7663d-46d5-4e55-8e10-ed71293b58b9
                        thirdPartyItemId: a5825b12-92f1-5814-8ac0-ed49b1c27cc4
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43f160b5-742a-4f02-acf0-fcc2a0d8fe83
                        thirdPartyItemId: 05a78766-d7a8-5eb8-a701-1d5a7ab4814e
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: e55b7f47-da57-4d20-b148-ca127a9a47c1
                        thirdPartyItemId: d890b23f-6e44-5bb7-abf7-2130c0ce8c45
                        name: Gl Breuil
                        quantity: 3
                        amounts:
                          netCostCents: 6300
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 63
                        cost: 63.0
                        costCents: 6300
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 98d3c225-5659-42d0-b840-936fe0e18cc9
                        thirdPartyItemId: 0679068b-75c2-51ca-a5e3-414816745d68
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      discounts: []
                      requiredTips: []
                      otherServiceCharges: []
                      payments:
                        mobileCheckoutMemberPayments: []
                        mobileCheckoutGuestPayments:
                        - amountDetails:
                            paidTotalAmountCents: 8892
                            paidRequiredAmountCents: 7512
                            paidElectiveTipAmountCents: 1380
                            paidEstimatedSubtotalAmountCents: 6900
                            paidEstimatedTaxAmountCents: 612
                          guestPaymentMethodDetails:
                            type: APPLE_PAY
                          status: Completed
                          paymentId: 1a75f0e0-1f5d-4379-b56f-23b66fb541a0
                          anonymousUserId: 45171b6d-e844-4c6f-85af-0fa1ebed0ad7
                          addOns: []
                          items:
                          - checkItemId: c99d01c7-9d8b-42c4-84bc-11ffebdedc1f
                            quantity: 1
                          - checkItemId: 43986da9-9093-4b56-a33e-fdef62bdef20
                            quantity: 1
                          - checkItemId: 704a4a70-419a-477c-a847-28a3142ed97e
                            quantity: 1
                          - checkItemId: 3fc8aa56-f03c-4ac4-87fd-fe5a9ff0dc19
                            quantity: 1
                          - checkItemId: b9308a50-6d2c-4431-a761-cd7fb4308527
                            quantity: 1
                        - amountDetails:
                            paidTotalAmountCents: 19976
                            paidRequiredAmountCents: 16876
                            paidElectiveTipAmountCents: 3100
                            paidEstimatedSubtotalAmountCents: 15500
                            paidEstimatedTaxAmountCents: 1376
                          guestPaymentMethodDetails:
                            type: CREDIT_CARD
                          status: Completed
                          paymentId: edf506b5-0c0a-453e-ade4-a6d222bac5bb
                          anonymousUserId: 84ce9f8a-12cb-4fac-a6ac-6d415413841d
                          addOns: []
                          items:
                          - checkItemId: 84a0a20f-3bde-44b4-a1fc-d1ad831e4669
                            quantity: 1
                          - checkItemId: cb116c7d-54c3-4cb4-9a6b-eba19458ca74
                            quantity: 1
                          - checkItemId: bb3c8f9a-0b9e-49cf-b9bf-9ae5fffc079f
                            quantity: 1
                          - checkItemId: ecb66e00-27de-4352-8b24-d3591e0eca40
                            quantity: 2
                          - checkItemId: d7a7663d-46d5-4e55-8e10-ed71293b58b9
                            quantity: 1
                          - checkItemId: 43f160b5-742a-4f02-acf0-fcc2a0d8fe83
                            quantity: 1
                          - checkItemId: e55b7f47-da57-4d20-b148-ca127a9a47c1
                            quantity: 3
                          - checkItemId: 98d3c225-5659-42d0-b840-936fe0e18cc9
                            quantity: 1
                        thirdPartyCardPayments: []
                        thirdPartyCashPayments: []
                        thirdPartyUncategorizedPayments: []
                        houseAccountPayments: []
                        payForGuestPayments: []
                      dueAmountCents: 0
                      openTime: '2025-10-20T16:37:43Z'
                      amountToTipOnCents: 22400
                      tipOptions:
                      - displayName: 20%
                        tipPercent: 20
                        tipAmountCents: 4480
                        isDefault: false
                      - displayName: 22%
                        tipPercent: 22
                        tipAmountCents: 4928
                        isDefault: true
                      - displayName: 25%
                        tipPercent: 25
                        tipAmountCents: 5600
                        isDefault: false
                      points: 224
                      isPayable: false
                      isBarTab: false
                      displayNumber: '1940'
                      paymentIntents: []
                      houseAccounts: []
                      tableNumber: '61'
                      amount: 224.0
                      amountCents: 22400
                      taxAmount: 19.88
                      taxAmountCents: 1988
                    merchantId: 59fa7945-29a0-409b-8202-e8e4e817d304
              memberPoints:
                summary: Member paying with Bilt Points
                description: The diner signed in to their Bilt account inside the checkout and redeemed points for the full
                  amount. Member payments carry `biltMemberId` and may include member identity when the merchant is enabled
                  for member data sharing; the tender breakdown is in `pointPaymentDetails`, `creditPaymentsDetails`, and
                  `cardPaymentDetails`.
                value:
                  type: orderClosed
                  timestamp: '2025-10-20T16:37:43Z'
                  data:
                    sessionId: cs_check_closed_example
                    partnerUserId: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
                    check:
                      id: 07d09ebb-44f8-4dac-86a8-85e0184d00f7
                      thirdPartyIds:
                        platform: TOAST
                        locationId: 1a2b3c4d-5e6f-4789-a012-3456789abcde
                        orderId: 2b3c4d5e-6f70-489a-b123-456789abcdef
                        checkId: 3c4d5e6f-7081-49ab-c234-56789abcdef0
                      checkState: completed
                      splitMode: NONE
                      checkAmounts:
                        subtotalAmountCents: 22400
                        taxAmountCents: 1988
                        requiredTipsTotalAmountCents: 0
                        requiredTotalAmountCents: 24388
                        preDiscountSubtotalAmountCents: 22400
                      items:
                      - id: 84a0a20f-3bde-44b4-a1fc-d1ad831e4669
                        thirdPartyItemId: 47bac383-f81b-5f1e-928a-e9804c2d8a4b
                        name: Club Soda
                        quantity: 1
                        amounts:
                          netCostCents: 500
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 5
                        cost: 5.0
                        costCents: 500
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: c99d01c7-9d8b-42c4-84bc-11ffebdedc1f
                        thirdPartyItemId: 05aaa8b8-ef68-5042-a36e-f747262b5f81
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43986da9-9093-4b56-a33e-fdef62bdef20
                        thirdPartyItemId: 5d589921-a3da-5f9a-be69-8abfe0f5d5ac
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 704a4a70-419a-477c-a847-28a3142ed97e
                        thirdPartyItemId: 760e7988-f82e-51a3-bf57-c3c05e62cb56
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 3fc8aa56-f03c-4ac4-87fd-fe5a9ff0dc19
                        thirdPartyItemId: 06d366fa-73f8-51c6-8c2c-cfed7bb819b0
                        name: Baba Ghannouge
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: b9308a50-6d2c-4431-a761-cd7fb4308527
                        thirdPartyItemId: b35d2db4-f1cc-5e15-92c9-21a2903db8fb
                        name: Hommus
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: cb116c7d-54c3-4cb4-9a6b-eba19458ca74
                        thirdPartyItemId: ff4a0583-de67-5f32-8f42-fc39a48f09a5
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                        cost: 12.0
                        costCents: 1200
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: bb3c8f9a-0b9e-49cf-b9bf-9ae5fffc079f
                        thirdPartyItemId: 750b85c5-ef47-579e-9a65-71a6dd6a3b30
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                        cost: 27.0
                        costCents: 2700
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: ecb66e00-27de-4352-8b24-d3591e0eca40
                        thirdPartyItemId: 648a7cbf-3ca4-5d3c-9730-d91d74b54a8c
                        name: Bread
                        quantity: 2
                        amounts:
                          netCostCents: 0
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 0
                        cost: 0.0
                        costCents: 0
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: d7a7663d-46d5-4e55-8e10-ed71293b58b9
                        thirdPartyItemId: a5825b12-92f1-5814-8ac0-ed49b1c27cc4
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 43f160b5-742a-4f02-acf0-fcc2a0d8fe83
                        thirdPartyItemId: 05a78766-d7a8-5eb8-a701-1d5a7ab4814e
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                        cost: 21.0
                        costCents: 2100
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: e55b7f47-da57-4d20-b148-ca127a9a47c1
                        thirdPartyItemId: d890b23f-6e44-5bb7-abf7-2130c0ce8c45
                        name: Gl Breuil
                        quantity: 3
                        amounts:
                          netCostCents: 6300
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 63
                        cost: 63.0
                        costCents: 6300
                        taxAmount: 0.0
                        taxAmountCents: 0
                      - id: 98d3c225-5659-42d0-b840-936fe0e18cc9
                        thirdPartyItemId: 0679068b-75c2-51ca-a5e3-414816745d68
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                        cost: 6.0
                        costCents: 600
                        taxAmount: 0.0
                        taxAmountCents: 0
                      discounts: []
                      requiredTips: []
                      otherServiceCharges: []
                      payments:
                        mobileCheckoutMemberPayments:
                        - amountDetails:
                            paidTotalAmountCents: 29316
                            paidRequiredAmountCents: 24388
                            paidElectiveTipAmountCents: 4928
                            paidEstimatedSubtotalAmountCents: 22400
                            paidEstimatedTaxAmountCents: 1988
                          pointPaymentDetails:
                            points: 29316
                          creditPaymentsDetails: []
                          biltMemberId: 4e6a2d91-7b35-4c08-a9f2-1d6e8b3c5a70
                          member:
                            firstName: Jordan
                            lastName: Lee
                            phone: '+14155550123'
                            email: jordan.lee@example.com
                            rewardTier: GOLD
                          estimatedPointsEarned: 0
                          status: Completed
                          paymentId: 9f1c4b72-6d08-4a35-b2e7-8c5d1f0a3e69
                          addOns: []
                          items: []
                        mobileCheckoutGuestPayments: []
                        thirdPartyCardPayments: []
                        thirdPartyCashPayments: []
                        thirdPartyUncategorizedPayments: []
                        houseAccountPayments: []
                        payForGuestPayments: []
                      dueAmountCents: 0
                      openTime: '2025-10-20T16:37:43Z'
                      amountToTipOnCents: 22400
                      tipOptions:
                      - displayName: 20%
                        tipPercent: 20
                        tipAmountCents: 4480
                        isDefault: false
                      - displayName: 22%
                        tipPercent: 22
                        tipAmountCents: 4928
                        isDefault: true
                      - displayName: 25%
                        tipPercent: 25
                        tipAmountCents: 5600
                        isDefault: false
                      points: 224
                      isPayable: false
                      isBarTab: false
                      displayNumber: '1940'
                      paymentIntents: []
                      houseAccounts: []
                      tableNumber: '61'
                      amount: 224.0
                      amountCents: 22400
                      taxAmount: 19.88
                      taxAmountCents: 1988
                    merchantId: 59fa7945-29a0-409b-8202-e8e4e817d304
      responses:
        '2xx':
          description: |
            Acknowledged. A timeout, transport error, `408`, `425`, `429`, or
            `5xx` is retried for 48 hours; any other non-2xx is treated as a
            rejection and not retried.
  closedOrderUpdated:
    post:
      summary: closedOrderUpdated
      operationId: webhookClosedOrderUpdated
      tags:
        - Webhooks
      security: []
      description: |
        Bilt POSTs this event when a previously closed check is updated, such
        as after a tip adjustment. The payload follows an earlier
        `orderClosed` for the same `check.id` and contains the full current
        check snapshot. See the Webhooks section above for signature,
        idempotency, and retry rules.
      parameters:
        - $ref: '#/components/parameters/WebhookId'
        - $ref: '#/components/parameters/WebhookTimestamp'
        - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEvent'
            examples:
              tipAdjustment:
                summary: Closed check updated after a tip adjustment
                description: The same check after the member's tip was adjusted; the payment snapshot, including
                  `member`, is re-sent in full.
                value:
                  type: closedOrderUpdated
                  timestamp: '2025-10-20T17:05:43Z'
                  data:
                    sessionId: cs_check_closed_example
                    partnerUserId: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
                    check:
                      id: 07d09ebb-44f8-4dac-86a8-85e0184d00f7
                      thirdPartyIds:
                        platform: TOAST
                        locationId: 1a2b3c4d-5e6f-4789-a012-3456789abcde
                        orderId: 2b3c4d5e-6f70-489a-b123-456789abcdef
                        checkId: 3c4d5e6f-7081-49ab-c234-56789abcdef0
                      checkState: completed
                      splitMode: NONE
                      checkAmounts:
                        subtotalAmountCents: 22400
                        taxAmountCents: 1988
                        requiredTipsTotalAmountCents: 0
                        requiredTotalAmountCents: 24388
                        preDiscountSubtotalAmountCents: 22400
                      items:
                      - id: 84a0a20f-3bde-44b4-a1fc-d1ad831e4669
                        thirdPartyItemId: 47bac383-f81b-5f1e-928a-e9804c2d8a4b
                        name: Club Soda
                        quantity: 1
                        amounts:
                          netCostCents: 500
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 5
                      - id: c99d01c7-9d8b-42c4-84bc-11ffebdedc1f
                        thirdPartyItemId: 05aaa8b8-ef68-5042-a36e-f747262b5f81
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                      - id: 43986da9-9093-4b56-a33e-fdef62bdef20
                        thirdPartyItemId: 5d589921-a3da-5f9a-be69-8abfe0f5d5ac
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                      - id: 704a4a70-419a-477c-a847-28a3142ed97e
                        thirdPartyItemId: 760e7988-f82e-51a3-bf57-c3c05e62cb56
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                      - id: 3fc8aa56-f03c-4ac4-87fd-fe5a9ff0dc19
                        thirdPartyItemId: 06d366fa-73f8-51c6-8c2c-cfed7bb819b0
                        name: Baba Ghannouge
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                      - id: b9308a50-6d2c-4431-a761-cd7fb4308527
                        thirdPartyItemId: b35d2db4-f1cc-5e15-92c9-21a2903db8fb
                        name: Hommus
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                      - id: cb116c7d-54c3-4cb4-9a6b-eba19458ca74
                        thirdPartyItemId: ff4a0583-de67-5f32-8f42-fc39a48f09a5
                        name: Fattoush
                        quantity: 1
                        amounts:
                          netCostCents: 1200
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 12
                      - id: bb3c8f9a-0b9e-49cf-b9bf-9ae5fffc079f
                        thirdPartyItemId: 750b85c5-ef47-579e-9a65-71a6dd6a3b30
                        name: Megalosalata - Shrimp
                        quantity: 1
                        amounts:
                          netCostCents: 2700
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 27
                      - id: ecb66e00-27de-4352-8b24-d3591e0eca40
                        thirdPartyItemId: 648a7cbf-3ca4-5d3c-9730-d91d74b54a8c
                        name: Bread
                        quantity: 2
                        amounts:
                          netCostCents: 0
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 0
                      - id: d7a7663d-46d5-4e55-8e10-ed71293b58b9
                        thirdPartyItemId: a5825b12-92f1-5814-8ac0-ed49b1c27cc4
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                      - id: 43f160b5-742a-4f02-acf0-fcc2a0d8fe83
                        thirdPartyItemId: 05a78766-d7a8-5eb8-a701-1d5a7ab4814e
                        name: Gl Breuil
                        quantity: 1
                        amounts:
                          netCostCents: 2100
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 21
                      - id: e55b7f47-da57-4d20-b148-ca127a9a47c1
                        thirdPartyItemId: d890b23f-6e44-5bb7-abf7-2130c0ce8c45
                        name: Gl Breuil
                        quantity: 3
                        amounts:
                          netCostCents: 6300
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 63
                      - id: 98d3c225-5659-42d0-b840-936fe0e18cc9
                        thirdPartyItemId: 0679068b-75c2-51ca-a5e3-414816745d68
                        name: Add Chicken
                        quantity: 1
                        amounts:
                          netCostCents: 600
                          netTaxAmountCents: 0
                        discounts: []
                        modifiers: []
                        points: 6
                      discounts: []
                      requiredTips: []
                      otherServiceCharges: []
                      payments:
                        mobileCheckoutMemberPayments:
                        - amountDetails:
                            paidTotalAmountCents: 29988
                            paidRequiredAmountCents: 24388
                            paidElectiveTipAmountCents: 5600
                            paidEstimatedSubtotalAmountCents: 22400
                            paidEstimatedTaxAmountCents: 1988
                          cardPaymentDetails:
                            isBiltCard: true
                          pointPaymentDetails:
                            points: 0
                          creditPaymentsDetails: []
                          biltMemberId: 4e6a2d91-7b35-4c08-a9f2-1d6e8b3c5a70
                          member:
                            firstName: Jordan
                            lastName: Lee
                            phone: '+14155550123'
                            email: jordan.lee@example.com
                            rewardTier: GOLD
                          estimatedPointsEarned: 299
                          status: Completed
                          paymentId: 7c3e6e20-2c44-4fd3-9c6c-9b8ec1f4a7d2
                          addOns: []
                          items: []
                        mobileCheckoutGuestPayments: []
                        thirdPartyCardPayments: []
                        thirdPartyCashPayments: []
                        thirdPartyUncategorizedPayments: []
                        houseAccountPayments: []
                        payForGuestPayments: []
                      dueAmountCents: 0
                      openTime: '2025-10-20T16:37:43Z'
                      amountToTipOnCents: 22400
                      tipOptions:
                      - displayName: 25%
                        tipPercent: 25
                        tipAmountCents: 5600
                        isDefault: true
                      points: 224
                      isPayable: false
                      isBarTab: false
                      displayNumber: '1940'
                      paymentIntents: []
                      houseAccounts: []
                      tableNumber: '61'
                      amount: 224.0
                      amountCents: 22400
                      taxAmount: 19.88
                      taxAmountCents: 1988
                    merchantId: 59fa7945-29a0-409b-8202-e8e4e817d304
      responses:
        '2xx':
          description: |
            Acknowledged. A timeout, transport error, `408`, `425`, `429`, or
            `5xx` is retried for 48 hours; any other non-2xx is treated as a
            rejection and not retried.

components:
  securitySchemes:
    partnerOAuth:
      type: oauth2
      description: |
        OAuth 2.0 client credentials against the `enterprise-partner`
        Keycloak realm. Bilt issues your client id and client secret during
        onboarding; tokens carry the `bilt-cart-partner-api` audience. Send
        the result as `Authorization: Bearer <access_token>`. The token URL
        below is **staging** — production is
        `https://www.bilt.com/realms/enterprise-partner/protocol/openid-connect/token`.
        Keep the client secret server-side only.
      flows:
        clientCredentials:
          tokenUrl: https://staging.biltrewards.com/realms/enterprise-partner/protocol/openid-connect/token
          scopes:
            cart:sessions:read: Read partner checkout sessions.
            cart:sessions:write: Create and cancel partner checkout sessions.

  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: |
        Fresh UUID per checkout attempt. A retry with the same key
        returns the originally created session rather than creating a
        new one. Keys are scoped to the partner account. A recommended
        format is `{reservationId}-{timestamp}` or a UUID.
      schema:
        type: string
        format: uuid
        example: 3f1a9c2e-6b4d-4a2f-9c7e-2b1d5a8e0f3c

    WebhookId:
      name: webhook-id
      in: header
      required: true
      description: |
        Unique message id, stable across redeliveries of the same event.
        Deduplicate on it.
      schema:
        type: string
        example: msg_2KWPBgLlAfxdpx2AI54pPJ85f4W

    WebhookTimestamp:
      name: webhook-timestamp
      in: header
      required: true
      description: |
        Unix timestamp in seconds of this delivery attempt. Reject deliveries
        more than 5 minutes from your clock.
      schema:
        type: integer
        format: int64
        example: 1787609712

    WebhookSignature:
      name: webhook-signature
      in: header
      required: true
      description: |
        Space-separated `v1a,<base64>` signatures, each an Ed25519
        signature over `"{webhook-id}.{webhook-timestamp}.{rawBody}"`
        verifiable with Bilt's `whpk_` public key. Bilt signs each delivery
        with exactly one key, so the header carries a single entry; during
        a key rotation verify it against both the old and the new public
        key and accept if either verifies.
      schema:
        type: string
        example: v1a,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=

  schemas:
    CreateCheckoutSessionRequest:
      type: object
      description: |
        Request to open a checkout session. `user` identifies the partner's
        customer, `lookupUrl` or `metadata.reservationExternalId` resolves
        the check, and `metadata` carries optional context. Exactly one of
        the two check locators is enough, but a request with neither is
        rejected.
      required:
        - user
      properties:
        user:
          $ref: '#/components/schemas/CheckoutUser'
        lookupUrl:
          type: string
          format: uri
          description: |
            The table/QR check-lookup URL for the customer's open check.
            Send this for the scan-to-pay flow; for a reservation-based
            checkout, send `metadata.reservationExternalId` instead.
          example: https://pos.example.com/t/AB12CD
        metadata:
          $ref: '#/components/schemas/CheckoutSessionMetadata'
      anyOf:
        - required:
            - lookupUrl
        - properties:
            metadata:
              type: object
              required:
                - reservationExternalId
              properties:
                reservationExternalId:
                  type: string
          required:
            - metadata

    CheckoutUser:
      type: object
      description: |
        The customer initiating checkout, as known to the partner. Only
        `partnerUserId` is required. The contact fields are optional and are
        **not** used for member matching at session creation — recognition
        happens inside the Bilt-hosted page, and Bilt does not report whether
        a match was found.
      required:
        - partnerUserId
      properties:
        partnerUserId:
          type: string
          description: The partner's stable identifier for this customer.
          example: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
        phone:
          type: string
          description: Customer phone number in E.164 format.
          example: '+19172175555'
        name:
          type: string
          description: Customer's full name.
          example: Jacob Schmidt
        email:
          type: string
          format: email
          description: Customer's email address (optional).
          example: jschmidt@example.com
        dob:
          type: string
          format: date
          description: Customer's date of birth (optional).
          example: '1990-10-10'

    CheckoutSessionMetadata:
      type: object
      description: |
        Optional partner context carried with the session. The Bilt
        `merchantId` is not a partner input — Bilt derives it from the
        resolved check and stores it on the session.
      properties:
        biltUrl:
          type: string
          format: uri
          description: A partner-supplied URL associated with the checkout.
          example: https://partner.example.com/checkout/abc
        reservationExternalId:
          type: string
          description: |
            The partner's external identifier for the reservation. Bilt
            resolves the check from it when no `lookupUrl` is supplied.
          example: ot-res-8827361

    PartnerPointsBalanceRequest:
      type: object
      description: Context for fetching the partner user's current points balance.
      required:
        - partnerUserId
        - sessionId
        - currency
      properties:
        partnerUserId:
          type: string
          description: The partner's stable identifier for the customer.
          example: ot-user-12345
        sessionId:
          type: string
          description: The Bilt checkout session identifier.
          example: cs_9f3a
        currency:
          type: string
          description: ISO 4217 currency for the redemption quote.
          example: USD

    PartnerPointsBalanceResponse:
      type: object
      description: |
        The partner's authoritative points balance and redemption rules for
        this checkout context. If eligibility varies by merchant, user,
        reservation, or market, return the final eligible values here rather
        than making Bilt replicate partner eligibility logic.
      required:
        - partnerUserId
        - pointsBalance
        - conversionRate
        - minimumRedemptionPoints
        - maximumRedemptionPoints
        - incrementPoints
      properties:
        partnerUserId:
          type: string
          description: The partner's stable identifier for the customer.
          example: ot-user-12345
        pointsBalance:
          type: integer
          format: int64
          minimum: 0
          description: Current points balance available to this partner user.
          example: 12500
        conversionRate:
          $ref: '#/components/schemas/PartnerPointsConversionRate'
        minimumRedemptionPoints:
          type: integer
          format: int64
          minimum: 0
          description: Minimum number of points that may be redeemed.
          example: 100
        maximumRedemptionPoints:
          type: integer
          format: int64
          minimum: 0
          description: |
            Maximum number of points that may be redeemed. There is no
            separate redeemable balance; express the cap here.
          example: 10000
        incrementPoints:
          type: integer
          format: int64
          minimum: 1
          description: Required points increment for a redemption.
          example: 100
        expiresAt:
          type: string
          format: date-time
          description: Optional expiry time for this quote.
          example: '2026-07-21T12:05:00Z'

    PartnerPointsConversionRate:
      type: object
      description: The points-to-money conversion rate for this quote.
      required:
        - points
        - amountCents
        - currency
      properties:
        points:
          type: integer
          format: int64
          minimum: 1
          description: Number of points represented by the quoted amount.
          example: 1000
        amountCents:
          type: integer
          format: int64
          minimum: 0
          description: Monetary value of the points, in integer cents.
          example: 1000
        currency:
          type: string
          description: ISO 4217 currency for the quoted amount.
          example: USD

    PartnerPointsRedemptionValue:
      type: object
      description: Monetary value of a points debit or refund, in cents.
      required:
        - amountCents
        - currency
      properties:
        amountCents:
          type: integer
          format: int64
          minimum: 0
          description: Monetary value in integer cents.
          example: 2500
        currency:
          type: string
          description: ISO 4217 currency for the monetary value.
          example: USD

    PartnerPointsSpendRequest:
      type: object
      description: Request to immediately debit partner points.
      required:
        - partnerUserId
        - sessionId
        - biltPaymentId
        - pointsToSpend
        - redemptionValue
        - idempotencyKey
      properties:
        partnerUserId:
          type: string
          description: The partner's stable identifier for the customer.
          example: ot-user-12345
        sessionId:
          type: string
          description: The Bilt checkout session identifier.
          example: cs_9f3a
        biltPaymentId:
          type: string
          description: Bilt payment identifier shared for reconciliation.
          example: pay_7f3b2a1c
        merchantId:
          type: string
          description: Optional partner identifier for the location or merchant.
          example: merchant-soho
        pointsToSpend:
          type: integer
          format: int64
          minimum: 1
          description: Number of partner points to debit.
          example: 2500
        redemptionValue:
          $ref: '#/components/schemas/PartnerPointsRedemptionValue'
        idempotencyKey:
          type: string
          description: |
            Stable key for this spend attempt. Retrying the same key must
            return the same deterministic result.
          example: pts-spend-cs-9f3a-1

    PartnerPointsSpendResponse:
      type: object
      description: Result of an idempotent partner-points spend attempt.
      required:
        - status
        - pointsSpent
        - redemptionValue
        - remainingPointsBalance
      properties:
        status:
          $ref: '#/components/schemas/PartnerPointsSpendStatus'
        partnerPointsTransactionId:
          type: string
          description: |
            Stable partner transaction ID for reconciliation and refunds.
            MUST be present whenever points were actually debited (status
            `succeeded` or `already_processed`); it is absent only for
            declines and failures.
          example: ot-pts-txn-789
        pointsSpent:
          type: integer
          format: int64
          minimum: 0
          description: Number of points actually debited.
          example: 2500
        redemptionValue:
          $ref: '#/components/schemas/PartnerPointsRedemptionValue'
        remainingPointsBalance:
          type: integer
          format: int64
          minimum: 0
          description: Partner user's points balance after the spend.
          example: 10000

    PartnerPointsSpendStatus:
      type: string
      description: Outcome of a partner-points spend attempt.
      enum:
        - succeeded
        - declined_insufficient_balance
        - declined_not_eligible
        - already_processed
        - failed_retryable
        - failed_non_retryable

    PartnerPointsRefundRequest:
      type: object
      description: Request to refund all or part of a partner-points spend.
      required:
        - partnerUserId
        - sessionId
        - biltPaymentId
        - originalPartnerPointsTransactionId
        - pointsToRefund
        - refundValue
        - reason
        - idempotencyKey
      properties:
        partnerUserId:
          type: string
          description: The partner's stable identifier for the customer.
          example: ot-user-12345
        sessionId:
          type: string
          description: The Bilt checkout session identifier.
          example: cs_9f3a
        biltPaymentId:
          type: string
          description: Bilt payment identifier shared for reconciliation.
          example: pay_7f3b2a1c
        originalPartnerPointsTransactionId:
          type: string
          description: Partner transaction ID returned by the original spend.
          example: ot-pts-txn-789
        pointsToRefund:
          type: integer
          format: int64
          minimum: 1
          description: Number of partner points to refund; partial refunds are supported.
          example: 2500
        refundValue:
          $ref: '#/components/schemas/PartnerPointsRedemptionValue'
        reason:
          type: string
          description: Reason for the points refund or adjustment.
          example: payment_failed_after_points_spend
        idempotencyKey:
          type: string
          description: Stable key for this refund attempt.
          example: pts-refund-cs-9f3a-1

    PartnerPointsRefundResponse:
      type: object
      description: Result of an idempotent partner-points refund attempt.
      required:
        - status
        - pointsRefunded
        - refundValue
        - updatedPointsBalance
      properties:
        status:
          $ref: '#/components/schemas/PartnerPointsRefundStatus'
        partnerPointsRefundTransactionId:
          type: string
          description: |
            Stable partner refund transaction ID for reconciliation.
            MUST be present whenever points were actually refunded
            (status `succeeded` or `already_processed`); it is absent
            only for failures.
          example: ot-pts-refund-456
        pointsRefunded:
          type: integer
          format: int64
          minimum: 0
          description: Number of partner points actually refunded.
          example: 2500
        refundValue:
          $ref: '#/components/schemas/PartnerPointsRedemptionValue'
        updatedPointsBalance:
          type: integer
          format: int64
          minimum: 0
          description: Partner user's points balance after the refund.
          example: 12500

    PartnerPointsRefundStatus:
      type: string
      description: Outcome of a partner-points refund attempt.
      enum:
        - succeeded
        - already_processed
        - failed_retryable
        - failed_non_retryable

    CheckoutSession:
      type: object
      description: |
        Returned when a checkout session is created. `token` is the handoff
        credential your app passes to the Bilt checkout, which redeems it for
        the session context.
      required:
        - sessionId
        - token
        - expiresAt
      properties:
        sessionId:
          type: string
          description: Bilt's opaque identifier for the checkout session.
          example: cs_9f3a
        token:
          type: string
          description: |
            Short-lived handoff token (prefix `cst_`). Returned **only** here
            — Bilt stores only its SHA-256 hash, so it cannot be re-read.
            Redeeming it does not consume it; it stays valid until
            `expiresAt` or a terminal session status. Treat it as a
            credential: do not log it or put it in a URL.
          example: cst_x71a2b3c4d5e6f708192a3b4c5d6e7f80
        expiresAt:
          type: string
          format: date-time
          description: When the session and its handoff token expire.
          example: '2026-07-21T12:05:00Z'

    RedeemSessionRequest:
      type: object
      description: |
        Request from the Bilt checkout surface to redeem a handoff token. The
        token is sent in the body, not the URL, to keep it out of access
        logs, browser history, and `Referer` headers.
      required:
        - token
      properties:
        token:
          type: string
          description: The handoff token from the create response.
          example: cst_x71a2b3c4d5e6f708192a3b4c5d6e7f80

    CartSessionDetails:
      type: object
      description: |
        Session context returned to the Bilt checkout surface on redeem,
        carrying the POS linkage it needs to render the check. Not part of
        the partner-facing contract — partners receive `CheckoutSession` on
        create and the checkout outcome from the SDK.
      properties:
        sessionId:
          type: string
          example: cs_9f3a
        status:
          $ref: '#/components/schemas/CheckoutStatus'
        expiresAt:
          type: string
          format: date-time
          example: '2026-07-21T12:05:00Z'
        merchantId:
          type: string
          format: uuid
          description: Bilt merchant identifier, derived from the resolved check.
          example: 123e4567-e89b-12d3-a456-426614174000
        visitId:
          type: string
          format: uuid
        orderId:
          type: string
          format: uuid
        lookupUrl:
          type: string
          format: uri
          example: https://pos.example.com/t/AB12CD

    CheckoutSessionStatus:
      type: object
      description: Current state of a checkout session.
      required:
        - sessionId
        - status
      properties:
        sessionId:
          type: string
          example: cs_9f3a
        status:
          $ref: '#/components/schemas/CheckoutStatus'
        orderId:
          type: string
          description: Present once payment has succeeded.
          example: ord_5c2d
        expiresAt:
          type: string
          format: date-time
          example: '2026-07-21T12:05:00Z'

    CheckoutStatus:
      type: string
      description: |
        Terminal-or-pending status of a checkout session.
          - `OPEN` — session created, not yet completed.
          - `COMPLETED` — payment succeeded.
          - `CANCELLED` — cancelled without a successful payment.
          - `EXPIRED` — expired before completion.
          - `REVERSED` — the completed payment was later reversed.
      enum: [OPEN, COMPLETED, CANCELLED, EXPIRED, REVERSED]

    CheckoutSessionWebhookEvent:
      type: object
      description: |
        Body of every `checkout.session.*` webhook. The same field set is
        sent for every event type; a field that does not apply is `null`,
        never omitted. Idempotency and ordering: deduplicate on the
        `webhook-id` header, order on `timestamp`.
      required:
        - type
        - timestamp
        - data
      properties:
        type:
          type: string
          description: The event type. Equal to the `event_type` the event was routed on.
          enum:
            - checkout.session.completed
            - checkout.session.cancelled
            - checkout.session.expired
            - checkout.session.reversed
          example: checkout.session.completed
        timestamp:
          type: string
          format: date-time
          description: |
            When the status transition happened, RFC 3339 in UTC with
            nanosecond precision and a `Z` suffix.
          example: '2026-09-10T14:34:18.986759998Z'
        data:
          $ref: '#/components/schemas/CheckoutSessionWebhookData'

    CheckoutSessionWebhookData:
      type: object
      description: Reference-only session facts. No customer PII, amounts, or line items.
      required:
        - sessionId
        - status
        - orderId
        - configId
        - merchantCatalogId
        - checkoutPaymentId
      properties:
        sessionId:
          type: string
          format: uuid
          description: The Bilt checkout session the event is about.
          example: 2dfdb0f5-a072-4114-a8ee-7b1f2872886a
        status:
          type: string
          description: The session status after the transition; always matches `type`.
          enum: [COMPLETED, CANCELLED, EXPIRED, REVERSED]
          example: CANCELLED
        orderId:
          type: string
          format: uuid
          description: |
            The Bilt-assigned order id of the session, always present. This
            API does not accept a partner-supplied order id; correlate on
            `sessionId`.
          example: 955648d7-1926-4b0e-82ba-0b5b2a664de6
        configId:
          type: string
          format: uuid
          description: The Bilt merchant configuration the session was created against.
          example: 0c164cc0-9aa4-4054-b999-472ed4b75bc5
        merchantCatalogId:
          type: [string, 'null']
          format: uuid
          description: The Bilt merchant-catalog id of that merchant; `null` when none is configured.
          example: 5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a
        checkoutPaymentId:
          type: [string, 'null']
          format: uuid
          description: |
            The Bilt payment attached to the session. Always set on
            `checkout.session.completed` and `checkout.session.reversed`;
            `null` when no payment was ever attached.
          example: 9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d

    WebhookEvent:
      type: object
      description: |
        Envelope for the `orderClosed` and `closedOrderUpdated` webhooks.
        `data` varies by `type`; see the *Webhooks* tag for the event-type
        table. Checkout session lifecycle events use
        `CheckoutSessionWebhookEvent` instead.
      required:
        - type
        - timestamp
        - data
      properties:
        type:
          type: string
          description: The event type.
          enum:
            - orderClosed
            - closedOrderUpdated
          example: orderClosed
        timestamp:
          type: string
          format: date-time
          description: When the event happened, in UTC with a `Z` suffix.
          example: '2026-07-21T12:03:11Z'
        data:
          $ref: '#/components/schemas/WebhookEventData'

    WebhookEventData:
      type: object
      description: |
        Event-specific payload. `check` and `merchantId` are populated for both
        order events.
      required:
        - sessionId
        - partnerUserId
        - check
      properties:
        sessionId:
          type: string
          description: The Bilt checkout session.
          example: cs_9f3a
        partnerUserId:
          type: string
          description: The partner's diner/user identifier supplied at session creation; the join key partners use to attach reservation context.
          example: 3d1c9f8a-2b4e-4c6a-9f10-7a2b3c4d5e6f
        check:
          $ref: '#/components/schemas/Check'
        merchantId:
          type: string
          format: uuid
          description: The Bilt merchant identifier for the merchant location.
          example: 59fa7945-29a0-409b-8202-e8e4e817d304
        metadata:
          description: Optional partner context echoed from session creation.
          $ref: '#/components/schemas/CheckoutSessionMetadata'

    Check:
      type: object
      description: A check from a POS system, as delivered on order events.
        Monetary amounts are in cents.
      required:
      - id
      - checkState
      - checkAmounts
      - items
      - discounts
      - requiredTips
      - otherServiceCharges
      - payments
      - dueAmountCents
      - openTime
      - amountToTipOnCents
      - tipOptions
      - points
      - isPayable
      - isBarTab
      properties:
        id:
          type: string
          format: uuid
          description: The Bilt-generated unique identifier for the check.
        thirdPartyIds:
          type: object
          description: |
            Identifiers assigned by the merchant's POS, as opaque strings.
            `check.id` remains the Bilt identifier; use these to reconcile
            against POS exports. Present when available.
          properties:
            platform:
              type: string
              description: POS platform that issued the identifiers.
              example: TOAST
            locationId:
              type: string
              description: POS location or restaurant identifier that scopes other IDs when applicable.
            orderId:
              type: string
              description: POS order, such as a Toast order GUID or Olo ticket ID.
            checkId:
              type: string
              description: POS check within the order; for Olo, this equals the ticket ID.
        checkState:
          type: string
          enum:
          - open
          - completed
          description: The state of the check.
        splitMode:
          type: string
          enum:
          - NONE
          - EVEN_SPLIT
          - CUSTOM_AMOUNTS
          - BY_ITEM
          - REMAINING_BALANCE
          description: How the check was split among payers. `NONE` — one payer; `EVEN_SPLIT` — equal shares; `CUSTOM_AMOUNTS` — payer-chosen uneven amounts; `BY_ITEM` — payers selected items (see `payments.*.items`); `REMAINING_BALANCE` — a payer covered whatever was left.
        checkAmounts:
          $ref: '#/components/schemas/CheckAmounts'
        items:
          type: array
          description: The items on the check. Each item id is referenced by payment items
            when a guest split by item.
          items:
            $ref: '#/components/schemas/CheckItem'
        discounts:
          type: array
          description: All check-level discounts on the check.
          items:
            $ref: '#/components/schemas/PriceModifier'
        requiredTips:
          type: array
          description: Service charges categorized as required tips or auto-gratuity.
          items:
            $ref: '#/components/schemas/PriceModifier'
        otherServiceCharges:
          type: array
          description: Check-level service charges other than required gratuity.
          items:
            $ref: '#/components/schemas/PriceModifier'
        payments:
          $ref: '#/components/schemas/CheckPayments'
        dueAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The portion of requiredTotalAmountCents that has not been paid.
        openTime:
          type: string
          format: date-time
          description: The time the check was opened.
        amountToTipOnCents:
          type: integer
          format: int64
          minimum: 0
          description: The amount used to calculate tip options.
        tipOptions:
          type: array
          description: Preset tip options.
          items:
            $ref: '#/components/schemas/TipOption'
        points:
          type: integer
          format: int64
          description: The estimated number of points earned for this check.
        isPayable:
          type: boolean
          description: Whether the check can be paid on the POS terminal.
        isBarTab:
          type: boolean
          description: Whether this check is part of the bar tab flow.
        displayNumber:
          type: string
          description: The display number used by the POS to identify the check.
        tableNumber:
          type: [string, 'null']
          description: The table number from the POS system.
        name:
          type: [string, 'null']
          description: The tab or ticket name from the POS system.
        paymentIntents:
          type: array
          description: Payment intents associated with the check.
          items:
            $ref: '#/components/schemas/PaymentIntent'
        houseAccounts:
          type: array
          description: House accounts associated with the check.
          items:
            $ref: '#/components/schemas/HouseAccount'
        amount:
          type: number
          format: double
          minimum: 0
          deprecated: true
          description: The subtotal amount of the check. Deprecated in favor of checkAmounts.
        amountCents:
          type: integer
          format: int64
          minimum: 0
          deprecated: true
          description: The subtotal amount of the check, in cents. Deprecated in favor
            of checkAmounts.
        taxAmount:
          type: number
          format: double
          minimum: 0
          deprecated: true
          description: The tax amount of the check. Deprecated in favor of checkAmounts.
        taxAmountCents:
          type: integer
          format: int64
          minimum: 0
          deprecated: true
          description: The tax amount of the check, in cents. Deprecated in favor of checkAmounts.
    CheckAmounts:
      type: object
      description: The amounts of a check, in cents.
      required:
      - subtotalAmountCents
      - taxAmountCents
      - requiredTipsTotalAmountCents
      - requiredTotalAmountCents
      properties:
        subtotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The subtotal amount of the check, including item costs, discounts,
            and non-required service charges.
        preDiscountSubtotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The subtotal amount before item-level discounts are applied.
        preCheckDiscountSubtotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The subtotal before check-level discounts, inclusive of item-level
            discounts.
        checkDiscountsTotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The total amount of check-level discounts.
        taxAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The tax amount of the check.
        requiredTipsTotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The amount of required tips on the check.
        requiredTotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The total amount including subtotal, taxes, and required tips.
    CheckItem:
      type: object
      description: An item from a POS system.
      required:
      - id
      - name
      - quantity
      - amounts
      - discounts
      - modifiers
      - points
      properties:
        id:
          type: string
          format: uuid
          description: The UUID of the item.
        thirdPartyItemId:
          type: string
          description: |
            POS identifier of the item line; present when available.
            `check.items[].id` remains the Bilt id and is what
            `payments.*.items[].checkItemId` references.
        name:
          type: string
          description: The name of the item.
        quantity:
          type: number
          format: double
          description: The quantity of the item.
        amounts:
          $ref: '#/components/schemas/ItemAmounts'
        discounts:
          type: array
          description: Any discounts for the item.
          items:
            $ref: '#/components/schemas/PriceModifier'
        modifiers:
          type: array
          description: Any non-discount modifiers for the item.
          items:
            $ref: '#/components/schemas/PriceModifier'
        points:
          type: integer
          format: int64
          description: The estimated points earned for this item.
        cost:
          type: number
          format: double
          deprecated: true
          description: The label price of the item, not including tax. Deprecated in favor
            of amounts.
        costCents:
          type: integer
          format: int64
          deprecated: true
          description: The label price in cents. Deprecated in favor of amounts.
        taxAmount:
          type: number
          format: double
          deprecated: true
          description: The tax amount. Deprecated in favor of amounts.
        taxAmountCents:
          type: integer
          format: int64
          deprecated: true
          description: The tax amount in cents. Deprecated in favor of amounts.
    ItemAmounts:
      type: object
      description: Amounts for an item. For quantities above one, these represent the
        total quantity.
      required:
      - netCostCents
      - netTaxAmountCents
      properties:
        netCostCents:
          type: integer
          format: int64
          minimum: 0
          description: Net line-item cost excluding tax, including discounts and modifiers.
        preDiscountCostCents:
          type: integer
          format: int64
          minimum: 0
          description: Line-item cost including modifiers but excluding discounts.
        netTaxAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: Tax amount of the net item cost.
    PriceModifier:
      type: object
      description: An item or check-level modifier.
      required:
      - name
      - netAmountCents
      properties:
        name:
          type: string
          description: Display name for the modifier.
        netAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: The net amount of the modification in cents.
        netPercent:
          type: number
          format: double
          description: The percentage rate for percentage-based modifiers.
    CheckPayments:
      type: object
      description: The various types of payments on a check. If no payments have been
        made, all arrays are empty.
      required:
      - mobileCheckoutMemberPayments
      - mobileCheckoutGuestPayments
      - thirdPartyCardPayments
      - thirdPartyCashPayments
      - thirdPartyUncategorizedPayments
      - houseAccountPayments
      - payForGuestPayments
      properties:
        mobileCheckoutMemberPayments:
          type: array
          items:
            $ref: '#/components/schemas/MobileCheckoutMemberPayment'
        mobileCheckoutGuestPayments:
          type: array
          items:
            $ref: '#/components/schemas/MobileCheckoutGuestPayment'
        thirdPartyCardPayments:
          type: array
          items:
            $ref: '#/components/schemas/ThirdPartyCardPayment'
        thirdPartyCashPayments:
          type: array
          items:
            $ref: '#/components/schemas/ThirdPartyCashPayment'
        thirdPartyUncategorizedPayments:
          type: array
          items:
            $ref: '#/components/schemas/ThirdPartyUncategorizedPayment'
        houseAccountPayments:
          type: array
          items:
            $ref: '#/components/schemas/HouseAccountPayment'
        payForGuestPayments:
          type: array
          items:
            $ref: '#/components/schemas/PayForGuestPayment'
    PaymentAmountDetails:
      type: object
      description: The amount details of a payment.
      required:
      - paidTotalAmountCents
      properties:
        paidRequiredAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: Portion going toward the required amount.
        paidElectiveTipAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: Portion going toward an elective tip.
        paidTotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: Total payment amount.
        paidEstimatedSubtotalAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: Estimated subtotal portion paid.
        paidEstimatedTaxAmountCents:
          type: integer
          format: int64
          minimum: 0
          description: Estimated tax portion paid.
    GuestPaymentMethodDetails:
      type: object
      description: The method details of a guest payment.
      required:
      - type
      properties:
        type:
          type: string
          enum:
          - APPLE_PAY
          - GOOGLE_PAY
          - CREDIT_CARD
          - ROOM_CHARGE
          description: The payment method type provided by the POS.
    CardPaymentDetails:
      type: object
      description: Details of a card payment.
      required:
      - isBiltCard
      properties:
        network:
          type: string
          enum:
          - VISA
          - MASTERCARD
          - DISCOVER
          - AMEX
          - JCB
          - DINERS
          - UNKNOWN
          description: Card network.
        lastFour:
          type: string
          description: Last four digits of the card.
        isBiltCard:
          type: boolean
          description: Whether the card is a Bilt card.
    PointPaymentDetails:
      type: object
      description: Details of a Pay with Points payment.
      required:
      - points
      properties:
        points:
          type: integer
          format: int64
          minimum: 0
          description: Points used for the payment.
    CreditPaymentDetails:
      type: object
      description: Details of a Pay with Credits payment.
      required:
      - type
      - redeemedAmount
      properties:
        type:
          type: string
          description: Credit type, usually a UUID.
        redeemedAmount:
          type: number
          format: double
          minimum: 0
          description: Amount of credit used.
    DiningPaymentStatus:
      type: string
      description: The user-facing status of a payment.
      enum:
      - Charged
      - Completed
      - Refunded
      - Partially Refunded
      - Charge Failed
    MobileCheckoutMemberPayment:
      type: object
      description: A member payment made through Bilt's mobile checkout feature.
      required:
      - amountDetails
      - pointPaymentDetails
      - creditPaymentsDetails
      - biltMemberId
      - estimatedPointsEarned
      - status
      properties:
        paymentId:
          type: string
          format: uuid
        biltMemberId:
          type: string
          format: uuid
        member:
          type: object
          description: Identity of the Bilt member who made this payment. Present only when the diner paid while signed in to Bilt and the merchant is enabled for member data sharing; never present for guest payments. When present, all fields are populated.
          required:
          - firstName
          - lastName
          - phone
          - email
          - rewardTier
          properties:
            firstName:
              type: string
            lastName:
              type: string
            phone:
              type: string
              description: E.164 phone number; the diner's Bilt login phone number, which may differ from the number on the reservation.
              pattern: '^\+[1-9]\d{1,14}$'
            email:
              type: string
              format: email
            rewardTier:
              type: string
              description: The member's current Bilt Rewards status tier when the event was produced, lowest to highest. This is loyalty-program status, not the Bilt card product the member holds or whether they hold one. Tiers change over time, so treat the value as a point-in-time snapshot rather than a fixed member attribute.
              enum:
              - BLUE
              - SILVER
              - GOLD
              - PLATINUM
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
        reversalSummary:
          $ref: '#/components/schemas/ReversalSummary'
        cardPaymentDetails:
          $ref: '#/components/schemas/CardPaymentDetails'
        pointPaymentDetails:
          $ref: '#/components/schemas/PointPaymentDetails'
        estimatedPointsEarned:
          type: integer
          format: int64
          minimum: 0
        creditPaymentsDetails:
          type: array
          items:
            $ref: '#/components/schemas/CreditPaymentDetails'
        addOns:
          type: array
          items:
            $ref: '#/components/schemas/PaymentAddOnLineItem'
        items:
          $ref: '#/components/schemas/ItemDetails'
        status:
          $ref: '#/components/schemas/DiningPaymentStatus'
    MobileCheckoutGuestPayment:
      type: object
      description: A guest payment made through Bilt's mobile checkout feature.
      required:
      - amountDetails
      - guestPaymentMethodDetails
      - status
      properties:
        paymentId:
          type: string
          format: uuid
        anonymousUserId:
          type: string
          format: uuid
          description: Identifier of the guest's anonymous checkout profile. It is scoped to the guest's device/card enrolment and is **not a stable diner identifier** across visits; use `partnerUserId` to correlate diners.
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
        reversalSummary:
          $ref: '#/components/schemas/ReversalSummary'
        guestPaymentMethodDetails:
          $ref: '#/components/schemas/GuestPaymentMethodDetails'
        addOns:
          type: array
          items:
            $ref: '#/components/schemas/PaymentAddOnLineItem'
        items:
          $ref: '#/components/schemas/ItemDetails'
        status:
          $ref: '#/components/schemas/DiningPaymentStatus'
    ItemDetails:
      type: array
      description: Details about items paid for in a split-by-item payment.
      items:
        $ref: '#/components/schemas/ItemDetailEntry'
    ItemDetailEntry:
      type: object
      description: An entry representing items paid for, grouped by checkItemId.
      required:
      - checkItemId
      - quantity
      properties:
        checkItemId:
          type: string
          format: uuid
          description: The check item ID that was paid for.
        quantity:
          type: integer
          format: int32
          minimum: 1
          description: Quantity of this item paid for.
    PaymentAddOnLineItem:
      type: object
      properties:
        amountCents:
          type: integer
          format: int64
          minimum: 0
          description: Amount in cents of the add-on line item.
        name:
          type: string
          description: Description of the line item.
    ThirdPartyCardPayment:
      type: object
      description: A card payment made directly with the merchant's POS system.
      required:
      - paymentId
      - amountDetails
      properties:
        paymentId:
          type: string
          format: uuid
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
        cardPaymentDetails:
          $ref: '#/components/schemas/CardPaymentDetails'
    ThirdPartyCashPayment:
      type: object
      description: A cash payment made directly with the merchant's POS system.
      required:
      - amountDetails
      properties:
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
    ThirdPartyUncategorizedPayment:
      type: object
      description: A payment made directly with the merchant's POS system that is not
        card or cash.
      required:
      - amountDetails
      properties:
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
    HouseAccountPayment:
      type: object
      description: A payment made through a house account.
      required:
      - paymentId
      - houseAccountId
      - patronId
      - amountDetails
      - status
      properties:
        paymentId:
          type: string
          format: uuid
        houseAccountId:
          type: string
          format: uuid
        patronId:
          type: string
          format: uuid
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
        reversalSummary:
          $ref: '#/components/schemas/ReversalSummary'
        status:
          $ref: '#/components/schemas/DiningPaymentStatus'
    PayForGuestPayment:
      type: object
      description: A payment made by a guest through the pay-for-guest flow.
      required:
      - paymentId
      - amountDetails
      - status
      properties:
        paymentId:
          type: string
          format: uuid
        amountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
        reversalSummary:
          $ref: '#/components/schemas/ReversalSummary'
        status:
          $ref: '#/components/schemas/DiningPaymentStatus'
    ReversalSummary:
      type: object
      description: Summary of reversal activity for a payment.
      required:
      - originalAmountDetails
      - refunds
      properties:
        originalAmountDetails:
          $ref: '#/components/schemas/PaymentAmountDetails'
        refunds:
          type: array
          items:
            $ref: '#/components/schemas/PaymentRefund'
    PaymentRefund:
      type: object
      description: A refund entry for a payment.
      required:
      - amountCents
      properties:
        amountCents:
          type: integer
          format: int64
          minimum: 0
    TipOption:
      type: object
      description: A preset tip option.
      required:
      - displayName
      - tipPercent
      - tipAmountCents
      - isDefault
      properties:
        displayName:
          type: string
        tipPercent:
          type: number
          format: double
          minimum: 0
        tipAmountCents:
          type: integer
          format: int64
          minimum: 0
        isDefault:
          type: boolean
          default: false
    PaymentIntentPurpose:
      type: string
      enum:
      - PAY_FOR_GUEST
      - TAB_AUTHORIZATION
    PaymentIntentStatus:
      type: string
      enum:
      - NEEDS_CONFIRMATION
      - PENDING
      - SUCCEEDED
      - FAILED
      - CANCELLED
    PaymentIntent:
      type: object
      required:
      - id
      - purpose
      - status
      properties:
        id:
          type: string
          format: uuid
        purpose:
          $ref: '#/components/schemas/PaymentIntentPurpose'
        status:
          $ref: '#/components/schemas/PaymentIntentStatus'
        paymentIntentType:
          type: string
          enum:
          - WHOLE_CHECK
          - FIXED_AMOUNT
        payorName:
          type: string
        maxAmountCents:
          type: integer
          format: int64
          minimum: 1
        giftNote:
          type: string
          maxLength: 150
        electiveTipPercent:
          type: number
          format: double
          minimum: 0
        electiveTipAmountCents:
          type: integer
          format: int64
        card:
          $ref: '#/components/schemas/CardPaymentDetails'
        callerCanUse:
          type: boolean
    HouseAccount:
      type: object
      description: Represents a house account.
      required:
      - id
      - name
      - merchantId
      - primaryPatronId
      - isDefault
      - electiveTipPercentage
      - notifyGuestOption
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 255
        merchantId:
          type: string
          format: uuid
        primaryPatronId:
          type: string
          format: uuid
        isDefault:
          type: boolean
        electiveTipPercentage:
          type: number
          format: double
        notifyGuestOption:
          type: string
          enum:
          - INFORM_GUEST_BEFORE_CLOSING
          - CLOSE_AUTOMATICALLY
        defaultCard:
          $ref: '#/components/schemas/HouseAccountCard'
        email:
          type: string
          format: email
    HouseAccountCard:
      type: object
      properties:
        id:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        cardType:
          type: string
        cardBrand:
          type: string
          enum:
          - VISA
          - MASTERCARD
          - DISCOVER
          - AMEX
          - JCB
          - DINERS
          - UNKNOWN
        cardNumberLastFour:
          type: string
          pattern: ^[0-9]{4}$
        isDefault:
          type: boolean
        createdAt:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code.
              example: INVALID_REQUEST
            message:
              type: string
              description: Human-readable description.
              example: 'user.partnerUserId is required'
