{
  "openapi": "3.1.0",
  "info": {
    "title": "Yutai distributor API",
    "version": "1",
    "description": "The distributor API's calls, served today at https://api.yutai.com and on the holder app's address beside it, both named by the servers below: the wallet eligibility read (GET /v1/eligibility), the benefit availability read (GET /v1/availability), one claim read (GET /v1/claims/{id}), which answers one claim the calling distributor's own key recorded, by its opaque claim id, and the reissue beside it (POST /v1/claims/{id}/link), which mints a fresh redemption link for one granted claim that same key recorded, replacing the stored digest so the previous link stops working, and the status read served beside them (GET /v1/status), which needs no key, because a distributor calls it before it holds one. A self-custody distributor asks for the challenge a wallet signs before a claim (POST /v1/claims/challenge) and records the claim itself with that proof (POST /v1/claims). When a benefit is one the distributor credits itself, the fulfilment rides beside the claim: the poll (GET /v1/fulfilments) answers the distributor's own pending fulfilments, each with the benefit's name beside it, and the confirm (POST /v1/fulfilments/{id}/confirm) marks one done with the distributor's own reference for the credit. A distributor's own server asks for one hosted Connect session for one of its users (POST /v1/connect/sessions) and reads that session's standing afterwards (GET /v1/connect/sessions/{id}), the two calls whose keys carry the Connect scopes. The registry page read, one registry's companies, share classes and token instruments a page at a time, is served the same way (GET /v1/registry/companies). The registry's by-ids facts read, the facts of one or more listed instruments in the order the ask names them, is served the same way (GET /v1/registry/instruments). A custodial distributor can also prove its own customer's holdings by submitting one signed statement in the request itself (the attested subject, Addendum 03 V-17): the claim call takes that subject beside the wallet proof, and its statement's own shapes stand in the contracts beside the wallet read's and on the sign a balance statement page, which documents the exact message the signature binds; this document names no balance. Distributors identify a holder by wallet, never by a Yutai holder id. Distributors authenticate with an API key the platform issues: the Bearer key names one tenant, and the key's scopes gate the calls, one scope per path. Responses carry no legal name, no balance of the holder's own record and no bank identifier."
  },
  "servers": [
    {
      "url": "https://api.yutai.com",
      "description": "Live and simulated data: each data domain stands in its own mode, and an illustrative offer is labelled."
    },
    {
      "url": "https://app.yutai.com/app/api",
      "description": "The legacy address, kept working: the same calls answer on both."
    }
  ],
  "paths": {
    "/v1/eligibility": {
      "get": {
        "operationId": "getWalletEligibility",
        "tags": [
          "holders"
        ],
        "summary": "Read the benefits one or more wallets reach",
        "security": [
          {
            "bearerKey": [
              "eligibility.read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "wallets",
            "in": "query",
            "required": true,
            "schema": {
              "minItems": 1,
              "maxItems": 20,
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[!-~]{3,256}$"
              },
              "description": "The wallet addresses to read: one or more, at most 20 in one read, each an EVM 0x address or a Solana address."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The wallets the request named, each with its tokens and the benefits they reach. The claimed state is the one fact the answer carries at the holder level: a benefit the holder the wallet is linked to has claimed reads claimed on every wallet that carries it, so wallets that share it show one fact about their holder.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorEligibility"
                }
              }
            }
          },
          "400": {
            "description": "The query could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope, or the wallets name chains outside the distributor's scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute, or the platform has used today's live wallet reads; the Retry-After header names the seconds until the next window opens, or until the reads open again. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "503": {
            "description": "The data source this read needs is not live yet, or the owners' blockchain switch does not allow the read, so the read is refused. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/availability": {
      "get": {
        "operationId": "getBenefitAvailability",
        "tags": [
          "holders"
        ],
        "summary": "Read the benefits one or more instruments carry",
        "security": [
          {
            "bearerKey": [
              "availability.read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "instruments",
            "in": "query",
            "required": true,
            "schema": {
              "minItems": 1,
              "maxItems": 200,
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "The instruments to read: one or more, at most 200 in one read, each an ISIN such as US0000000009 or a CAIP-19 instrument id such as eip155:88880/erc20:0x0000000000000000000000000000000000000000."
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2}$",
              "description": "The market whose stored policy shapes the answer: its two-letter country code, such as PT."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The instruments the request named, each once in the order it named them, keyed by its security's ISIN: an instrument the registry does not resolve and a company with no benefit to offer are left out. Each row names the market display policy its shape stands under - full carries the benefits, badge_only the count alone - and the market the ask names shapes every row, full when that market stores no policy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorAvailability"
                }
              }
            }
          },
          "400": {
            "description": "The query could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "503": {
            "description": "The data source this read needs is not live yet, so the read is refused. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/registry/companies": {
      "get": {
        "operationId": "listRegistryCompanies",
        "tags": [
          "registry"
        ],
        "summary": "Read the companies one registry holds",
        "security": [
          {
            "bearerKey": [
              "availability.read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "description": "The page's size: from 1 to 200 rows, 50 when left out.",
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "string",
                  "pattern": "^[0-9]{1,4}$"
                }
              ]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "The page link the previous answer carried: the nextCursor field's value of the page before this one.",
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Narrow the page to the companies of one country: its two-letter country code, such as US.",
              "type": "string",
              "pattern": "^[A-Z]{2}$"
            }
          },
          {
            "name": "isin",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Narrow the page to the company the ISIN belongs to: the share class's ISIN, such as US0000000009.",
              "type": "string",
              "pattern": "^[A-Z]{2}[A-Z0-9]{9}[0-9]$"
            }
          },
          {
            "name": "chain",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Narrow the page to the companies with an instrument on the chain: its CAIP-2 id, such as eip155:88880.",
              "type": "string",
              "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The companies one registry holds today, each once in key order: the company's name, its country and the mode its rows are in, then its share classes, each with the ACTIVE token instruments its mapping resolves to, named by CAIP-19 id, chain, wrapper name and the token issuer's name, which stands null where the programme names none. Each instrument carries its programme's facts too: its legal form, whether the issuing company sponsors it, its transfer model, whether holding it needs the programme's own KYC, and the token it converts into, named by its CAIP-19 id and programme. A form or a model the registry has not recorded reads null, and the conversion reads null where the registry stores none or the target is not itself listed. Only what a venue lists an instrument by rides: no internal id, no tenant and no holder fact. The next page's cursor rides beside the rows, null when this is the last page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorRegistryCompanyPage"
                }
              }
            }
          },
          "400": {
            "description": "The query could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "503": {
            "description": "The data source this read needs is not live yet, so the read is refused. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/registry/instruments": {
      "get": {
        "operationId": "readRegistryInstrumentFacts",
        "tags": [
          "registry"
        ],
        "summary": "Read the facts of one or more listed instruments",
        "security": [
          {
            "bearerKey": [
              "availability.read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "instrumentIds",
            "in": "query",
            "required": true,
            "schema": {
              "minItems": 1,
              "maxItems": 100,
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\\/[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}$"
              },
              "description": "The instruments to read the facts of: one or more, at most 100 in one read, each a CAIP-19 instrument id such as eip155:88880/erc20:0x0000000000000000000000000000000000000000."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The instruments the ask named, each once in the order it named them: each row names the instrument by its CAIP-19 id, its chain, its wrapper programme and the token issuer's name, which stands null where the programme names none, and carries the programme's own facts - its legal form, whether the issuing company sponsors it, its transfer model, whether holding it needs the programme's own KYC - and the token it converts into, named by its CAIP-19 id and programme. An instrument the ask names that the registry does not list today answers nothing: an unknown, paused, unmapped, other-mode or other-tenant id carries no row. The next page's cursor is null: the ask is answered whole, one call.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorRegistryInstrumentPage"
                }
              }
            }
          },
          "400": {
            "description": "The query could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "503": {
            "description": "The data source this read needs is not live yet, so the read is refused. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/claims/{id}": {
      "get": {
        "operationId": "getClaim",
        "tags": [
          "holders"
        ],
        "summary": "Read one claim this distributor recorded",
        "security": [
          {
            "bearerKey": [
              "claims.write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
              "description": "The claim's own id, the one the claim answer carried: a clm_ prefixed ULID."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The claim's own facts: its id, the benefit it claimed and the instant it was recorded, with its state in words - granted, or, when the benefit is one the venue credits itself, the venue credit's state (waiting on the venue, or credited once the venue confirmed), or rejected, or voided, when the grant was taken back. Nothing personal rides the answer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorClaimRead"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "404": {
            "description": "No claim answers this id under this distributor's key: an unknown id, or one another distributor's key recorded. The answer is the same for both, so no claim id can be probed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/claims/{id}/link": {
      "post": {
        "operationId": "reissueClaimLink",
        "tags": [
          "claims"
        ],
        "summary": "Reissue the redemption link of one claim this distributor recorded",
        "security": [
          {
            "bearerKey": [
              "claims.write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
              "description": "The claim's own id, the one the claim answer carried: a clm_ prefixed ULID."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The fresh link: the claim's own id and the one absolute address its new token opens, built on the same public origin the granted answer names. Only the last link reissued opens the claim's page, so the previous link stops working the moment this answer leaves; the token itself is never stored, so this answer carries the only copy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorClaimLink"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "404": {
            "description": "No claim answers this id under this distributor's key: an unknown id, or one another distributor's key recorded. The answer is the same for both, so no claim id can be probed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "409": {
            "description": "The claim the id names stands rejected or taken back, so it carries no redemption link to reissue.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/status": {
      "get": {
        "operationId": "getApiStatus",
        "tags": [
          "status"
        ],
        "summary": "Check the API status",
        "security": [],
        "responses": {
          "200": {
            "description": "Every external domain of Yutai's data, each with its mode today and the one sentence to show beside data in that mode. The call needs no key, because a distributor calls it before it holds one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VenueApiStatus"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/claims/challenge": {
      "post": {
        "operationId": "requestClaimChallenge",
        "tags": [
          "claims"
        ],
        "summary": "Ask for the challenge a wallet signs to claim a benefit",
        "security": [
          {
            "bearerKey": [
              "claims.write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DistributorClaimChallengeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The challenge: the exact message the holder signs, the one-time nonce to hand the page beside it, the wallets the proof binds to, and the instant the window closes, 300 seconds after the call. The signature proves the wallet owns the address; it moves nothing and approves nothing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorClaimChallenge"
                }
              }
            }
          },
          "400": {
            "description": "The request body could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope, or the challenge itself was refused: the venue is paused or not a self-custody venue, the benefit is not a claimable offer, or a wallet sits on a chain the venue does not serve. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/claims": {
      "post": {
        "operationId": "recordClaim",
        "tags": [
          "claims"
        ],
        "summary": "Record a claim a wallet's own signature or a distributor's signed statement stands behind",
        "security": [
          {
            "bearerKey": [
              "claims.write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DistributorClaimRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The claim's answer: granted, with the claim's own facts - its id, the wallets that signed it, the instant it was recorded and the decision behind it - or refused, when the holder's own world refused the claim, with the reason beside the same decision. The granted answer carries the code the benefit delivers, when it delivers by code, and the holder's private redemption link, on the first grant only. A retry of the same challenge answers the one claim it already recorded, marked alreadyClaimed, and so does a statement whose account already stands for the claim.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorClaimOutcome"
                }
              }
            }
          },
          "400": {
            "description": "The request body could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope, or the claim itself was refused: the challenge was never verified, was issued for another distributor or another benefit, or the holder's own world refused the claim, and the attested subject's statement the same - unsigned or unverifiable, expired, naming an instrument the distributor does not list or the registry no longer keeps active, naming another tenant, or for a benefit the account's holder already claimed once. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/fulfilments": {
      "get": {
        "operationId": "listPendingFulfilments",
        "tags": [
          "claims"
        ],
        "summary": "List the fulfilments waiting on this distributor",
        "security": [
          {
            "bearerKey": [
              "claims.write"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The calling distributor's own pending fulfilments, newest first: each names the claim it opens beside, the benefit it credits and the instant it was opened, with the waiting state the pending row carries. Nothing personal rides the answer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorFulfilmentList"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/fulfilments/{id}/confirm": {
      "post": {
        "operationId": "confirmFulfilment",
        "tags": [
          "claims"
        ],
        "summary": "Confirm one fulfilment waiting on this distributor",
        "security": [
          {
            "bearerKey": [
              "claims.write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^ful_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
              "description": "The fulfilment's own id, the one the poll's answer carried: a ful_ prefixed ULID."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DistributorFulfilmentConfirmRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The fulfilment's own facts after the confirm: the claim it opens beside, the benefit it credits and the instant it was opened, the credited state, the distributor's own reference for the credit and the instant the confirm recorded. Nothing personal rides the answer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorFulfilmentRead"
                }
              }
            }
          },
          "400": {
            "description": "The request body could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope, or the fulfilment was already confirmed: the confirm that stands is the one that landed first. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "404": {
            "description": "No fulfilment answers this id under this distributor's key: an unknown id, or one another distributor's key recorded. The answer is the same for both, so no fulfilment id can be probed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connect/sessions": {
      "post": {
        "operationId": "createConnectSession",
        "tags": [
          "connect"
        ],
        "summary": "Create a Connect session",
        "security": [
          {
            "bearerKey": [
              "connect.write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DistributorConnectSessionCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The session's id, the hosted page's address the distributor's app opens, and the instant its one-time token expires, 900 seconds after the call. The address carries the token once; the store keeps only its digest.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorConnectSessionCreated"
                }
              }
            }
          },
          "400": {
            "description": "The request body could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope, or the return address is not one the distributor's profile allows. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connect/sessions/{id}": {
      "get": {
        "operationId": "getConnectSession",
        "tags": [
          "connect"
        ],
        "summary": "Read a Connect session",
        "security": [
          {
            "bearerKey": [
              "connect.read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^cxs_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
              "description": "The Connect session's own id, the one the create answer carried."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The session's standing - pending, opened, connected, cancelled, failed or expired - the distributor's own reference, when it was created and when it ended, and the one reason a failed session carries. A session still open carries no completion and no reason; a session no one opened before its token ran out reads expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorConnectSessionRead"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, unknown, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "403": {
            "description": "The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "404": {
            "description": "No Connect session answers this id under this distributor's key: an unknown id, a malformed id, or one another distributor's key created. The answer is the same for both, so no session id can be probed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "429": {
            "description": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          },
          "500": {
            "description": "The read failed inside Yutai. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DistributorApiError"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "tier_changed": {
      "post": {
        "operationId": "receiveTierChanged",
        "summary": "Receive one tier change",
        "tags": [
          "webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9._:-]{1,256}$"
                  },
                  "kind": {
                    "type": "string",
                    "const": "tier_changed"
                  },
                  "payload": {
                    "$ref": "#/components/schemas/WebhookTierChangedPayload"
                  }
                },
                "required": [
                  "id",
                  "kind",
                  "payload"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A 2xx answer inside the transport's timeout counts the delivery as delivered. The same event id can arrive more than once, so the venue keeps the event ids it has answered and answers a repeat without acting on the change again."
          },
          "default": {
            "description": "The delivery is not taken: any answer outside 2xx, or no answer inside the transport's timeout, is one failed attempt. Yutai records the attempt as failed and sends the delivery again on its own schedule until the attempt budget is spent."
          }
        }
      }
    },
    "benefit_unlocked": {
      "post": {
        "operationId": "receiveBenefitUnlocked",
        "summary": "Receive one benefit unlock",
        "tags": [
          "webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9._:-]{1,256}$"
                  },
                  "kind": {
                    "type": "string",
                    "const": "benefit_unlocked"
                  },
                  "payload": {
                    "$ref": "#/components/schemas/WebhookBenefitUnlockedPayload"
                  }
                },
                "required": [
                  "id",
                  "kind",
                  "payload"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A 2xx answer inside the transport's timeout counts the delivery as delivered. The same event id can arrive more than once, so the venue keeps the event ids it has answered and answers a repeat without acting on the change again."
          },
          "default": {
            "description": "The delivery is not taken: any answer outside 2xx, or no answer inside the transport's timeout, is one failed attempt. Yutai records the attempt as failed and sends the delivery again on its own schedule until the attempt budget is spent."
          }
        }
      }
    },
    "claim_confirmed": {
      "post": {
        "operationId": "receiveClaimConfirmed",
        "summary": "Receive one claim confirmation",
        "tags": [
          "webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9._:-]{1,256}$"
                  },
                  "kind": {
                    "type": "string",
                    "const": "claim_confirmed"
                  },
                  "payload": {
                    "$ref": "#/components/schemas/WebhookClaimConfirmedPayload"
                  }
                },
                "required": [
                  "id",
                  "kind",
                  "payload"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A 2xx answer inside the transport's timeout counts the delivery as delivered. The same event id can arrive more than once, so the venue keeps the event ids it has answered and answers a repeat without acting on the change again."
          },
          "default": {
            "description": "The delivery is not taken: any answer outside 2xx, or no answer inside the transport's timeout, is one failed attempt. Yutai records the attempt as failed and sends the delivery again on its own schedule until the attempt budget is spent."
          }
        }
      }
    },
    "redemption_recorded": {
      "post": {
        "operationId": "receiveRedemptionRecorded",
        "summary": "Receive one redemption record",
        "tags": [
          "webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9._:-]{1,256}$"
                  },
                  "kind": {
                    "type": "string",
                    "const": "redemption_recorded"
                  },
                  "payload": {
                    "$ref": "#/components/schemas/WebhookRedemptionRecordedPayload"
                  }
                },
                "required": [
                  "id",
                  "kind",
                  "payload"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A 2xx answer inside the transport's timeout counts the delivery as delivered. The same event id can arrive more than once, so the venue keeps the event ids it has answered and answers a repeat without acting on the change again."
          },
          "default": {
            "description": "The delivery is not taken: any answer outside 2xx, or no answer inside the transport's timeout, is one failed attempt. Yutai records the attempt as failed and sends the delivery again on its own schedule until the attempt budget is spent."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "The API key Yutai issues a distributor: the Bearer key names one tenant, and the key's scopes gate the calls, one scope per path."
      }
    },
    "schemas": {
      "DistributorApiError": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          }
        },
        "required": [
          "message"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "message": "The wallet could not be read."
          }
        ]
      },
      "DistributorAvailability": {
        "type": "object",
        "properties": {
          "instruments": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "isin": {
                  "type": "string",
                  "pattern": "^[A-Z]{2}[A-Z0-9]{9}[0-9]$",
                  "description": "The instrument's ISIN, in the registry's canonical spelling."
                },
                "display": {
                  "type": "string",
                  "enum": [
                    "full",
                    "badge_only"
                  ],
                  "description": "full lists the benefits, badge_only carries the count alone."
                },
                "count": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 500,
                  "description": "How many benefits the company offers in the caller's country."
                },
                "illustrative": {
                  "type": "boolean",
                  "description": "True when every benefit the count counts is illustrative, meaning an example Yutai made up rather than a real offer."
                },
                "benefits": {
                  "description": "The benefits the count counts, present on a full row and absent on a badge_only row.",
                  "maxItems": 500,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 128,
                        "description": "The benefit's name as the company writes it."
                      },
                      "requirement": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 512,
                        "description": "What the holder must do to reach the benefit, in the company's own short words."
                      },
                      "fulfilment": {
                        "type": "string",
                        "enum": [
                          "CODE",
                          "POINTS_CREDIT",
                          "VENUE_REDEMPTION",
                          "CHAIN_MINT",
                          "TOKEN_TRANSFER"
                        ],
                        "description": "How the benefit reaches the holder: CODE for a discount code or voucher, POINTS_CREDIT for points, VENUE_REDEMPTION for access at the venue, CHAIN_MINT for a digital collectible and TOKEN_TRANSFER for a token sent to the holder's wallet."
                      },
                      "illustrative": {
                        "type": "boolean",
                        "description": "True when the benefit is an example Yutai made up, not an offer a real company has agreed to."
                      }
                    },
                    "required": [
                      "name",
                      "requirement",
                      "fulfilment",
                      "illustrative"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "isin",
                "display",
                "count",
                "illustrative"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "instruments"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "instruments": [
              {
                "isin": "US0000000009",
                "display": "full",
                "count": 1,
                "illustrative": true,
                "benefits": [
                  {
                    "name": "Sample lounge access",
                    "requirement": "Hold 15 shares of the programme for 30 days.",
                    "fulfilment": "VENUE_REDEMPTION",
                    "illustrative": true
                  }
                ]
              },
              {
                "isin": "US0000000007",
                "display": "badge_only",
                "count": 2,
                "illustrative": true
              }
            ]
          }
        ]
      },
      "DistributorClaimRead": {
        "type": "object",
        "properties": {
          "claimId": {
            "type": "string",
            "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The claim's own opaque id, the address the claim read answers at."
          },
          "benefitId": {
            "type": "string",
            "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The benefit the claim was recorded for, by its own opaque id."
          },
          "benefitName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The benefit's name as the programme carries it, so a claim reads without a second lookup."
          },
          "state": {
            "type": "string",
            "enum": [
              "granted",
              "rejected",
              "voided",
              "waiting on the venue",
              "credited by the venue"
            ],
            "description": "Where the claim stands in plain words: whether the grant stands, was refused or taken back, or the venue's credit is still to come."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "The instant Yutai recorded the claim and its decision."
          }
        },
        "required": [
          "claimId",
          "benefitId",
          "benefitName",
          "state",
          "createdAt"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "claimId": "clm_01K4V9QG000000000000000001",
            "benefitId": "bft_01K4V9QG000000000000000001",
            "benefitName": "Sample lounge access",
            "state": "granted",
            "createdAt": "2026-10-08T12:00:00.000Z"
          }
        ]
      },
      "DistributorEligibility": {
        "type": "object",
        "properties": {
          "wallets": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "wallet": {
                  "type": "string",
                  "pattern": "^[!-~]{3,256}$",
                  "description": "The wallet address the request named, in the spelling it sent."
                },
                "read": {
                  "type": "boolean",
                  "description": "Whether Yutai read the wallet at all; false when the wallet could not be read."
                },
                "sourceMode": {
                  "type": "string",
                  "enum": [
                    "SIMULATED",
                    "SANDBOX",
                    "LIVE"
                  ],
                  "description": "The data mode the read answered in: SIMULATED, SANDBOX or LIVE."
                },
                "tokens": {
                  "maxItems": 200,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "issuer": {
                        "description": "The issuer that mints the token, or null when no issuer is recorded.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "security": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 256
                          },
                          "isin": {
                            "type": "string",
                            "pattern": "^[A-Z]{2}[A-Z0-9]{9}[0-9]$"
                          }
                        },
                        "required": [
                          "name",
                          "isin"
                        ],
                        "additionalProperties": false,
                        "description": "The security the token's mapping names, with its name and its ISIN."
                      },
                      "wrapper": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 128,
                        "description": "The wrapper programme that carries the token."
                      },
                      "chain": {
                        "type": "string",
                        "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$",
                        "description": "The chain the token trades on, as its CAIP-2 id."
                      },
                      "shares": {
                        "type": "string",
                        "pattern": "^(0|[1-9][0-9]{0,76})(\\.[0-9]{0,35}[1-9])?$",
                        "description": "The wallet's holding as a decimal string at the token's own decimals, never a JSON number."
                      },
                      "daysHeld": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991,
                        "description": "Whole days the wallet has held the security without selling; counts toward the tier."
                      },
                      "tier": {
                        "description": "The programme tier the wallet's own trail answers, or null when no tier stands.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "benefits": {
                        "maxItems": 500,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "benefitId": {
                              "type": "string",
                              "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
                            },
                            "name": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 128
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "DISCOUNT_CODE",
                                "EXPERIENCE",
                                "POINTS",
                                "VOUCHER",
                                "ACCESS",
                                "DIGITAL_COLLECTIBLE",
                                "STOCK_REWARD"
                              ]
                            },
                            "delivery": {
                              "type": "string",
                              "enum": [
                                "CODE",
                                "POINTS_CREDIT",
                                "VENUE_REDEMPTION",
                                "CHAIN_MINT",
                                "TOKEN_TRANSFER"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "eligible",
                                "locked",
                                "claimed",
                                "redeemed",
                                "unavailable"
                              ]
                            },
                            "illustrative": {
                              "type": "boolean"
                            },
                            "lockedReason": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 512
                            }
                          },
                          "required": [
                            "benefitId",
                            "name",
                            "type",
                            "delivery",
                            "state",
                            "illustrative"
                          ],
                          "additionalProperties": false
                        },
                        "description": "The benefits the holding reaches, each with its state and its illustrative flag."
                      }
                    },
                    "required": [
                      "issuer",
                      "security",
                      "wrapper",
                      "chain",
                      "shares",
                      "daysHeld",
                      "tier",
                      "benefits"
                    ],
                    "additionalProperties": false
                  },
                  "description": "The tokens the wallet's own trail answers, each with the benefits it reaches; present when the wallet was read."
                },
                "unreadReason": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 512,
                  "description": "Why the wallet could not be read; present only when read is false."
                }
              },
              "required": [
                "wallet",
                "read",
                "sourceMode"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "wallets"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "wallets": [
              {
                "wallet": "0xabc0000000000000000000000000000000000001",
                "read": true,
                "sourceMode": "SIMULATED",
                "tokens": [
                  {
                    "issuer": null,
                    "security": {
                      "name": "Sample Global Holdings",
                      "isin": "US0000000009"
                    },
                    "wrapper": "Sample token programme",
                    "chain": "eip155:88880",
                    "shares": "15",
                    "daysHeld": 452,
                    "tier": "Patron",
                    "benefits": [
                      {
                        "benefitId": "bft_01K4V9QG000000000000000001",
                        "name": "Sample lounge access",
                        "type": "ACCESS",
                        "delivery": "VENUE_REDEMPTION",
                        "state": "eligible",
                        "illustrative": true
                      }
                    ]
                  }
                ]
              },
              {
                "wallet": "0xdef0000000000000000000000000000000000002",
                "read": false,
                "sourceMode": "SIMULATED",
                "unreadReason": "Yutai has not read this wallet yet."
              }
            ]
          }
        ]
      },
      "VenueApiStatus": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "const": "1"
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "domain": {
                  "type": "string",
                  "enum": [
                    "chain",
                    "openbanking",
                    "enrichment",
                    "prices",
                    "wallet",
                    "kyc-attest",
                    "registry",
                    "token-issuer-sources",
                    "reference-data",
                    "custodial",
                    "treasury"
                  ]
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "SIMULATED",
                    "SANDBOX",
                    "LIVE"
                  ]
                },
                "sentence": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "required": [
                "domain",
                "mode",
                "sentence"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "apiVersion",
          "domains"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "apiVersion": "1",
            "domains": [
              {
                "domain": "chain",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "openbanking",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "enrichment",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "prices",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "wallet",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "kyc-attest",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "registry",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "token-issuer-sources",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "reference-data",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "custodial",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              },
              {
                "domain": "treasury",
                "mode": "SIMULATED",
                "sentence": "This is simulated sample data for trying Yutai, not real records."
              }
            ]
          }
        ]
      },
      "DistributorClaimChallengeRequest": {
        "type": "object",
        "properties": {
          "benefitId": {
            "type": "string",
            "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The benefit the challenge asks a claim for: the id the eligibility read named."
          },
          "wallets": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^0x[0-9a-fA-F]{40}$"
                },
                {
                  "type": "string",
                  "pattern": "^[1-9A-HJ-NP-Za-km-z]{32,44}$"
                }
              ]
            },
            "uniqueItems": true,
            "description": "The wallets the challenge covers, each once, up to the cap this field carries."
          }
        },
        "required": [
          "benefitId",
          "wallets"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "benefitId": "bft_01K4V9QG000000000000000001",
            "wallets": [
              "0xabc0000000000000000000000000000000000001"
            ]
          }
        ]
      },
      "DistributorClaimChallenge": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "The exact text the holder's wallet signs. Signing moves nothing and approves nothing."
          },
          "nonce": {
            "type": "string",
            "pattern": "^[0-9a-f]{32}$",
            "description": "The one-time nonce to hand the holder's page beside the message: single use, and Yutai stores only its digest."
          },
          "wallets": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^0x[0-9a-fA-F]{40}$"
                },
                {
                  "type": "string",
                  "pattern": "^[1-9A-HJ-NP-Za-km-z]{32,44}$"
                }
              ]
            },
            "uniqueItems": true,
            "description": "The wallets the proof binds to, each once, the same list the request named."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "The instant the challenge stops being accepted, counted from the moment the door issued it."
          }
        },
        "required": [
          "message",
          "nonce",
          "wallets",
          "expiresAt"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "message": "Yutai claim challenge\nTenant: tnt_01K4V9QG000000000000000001\nVenue: Sample venue (tnt_01K4V9QG000000000000000002)\nBenefit: Sample lounge access (bft_01K4V9QG000000000000000001)\nWallet: 0xabc0000000000000000000000000000000000001\nNonce digest: 0xa1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4\nExpires: 2026-10-11T12:05:00.000Z\nSigning moves nothing and approves nothing.",
            "nonce": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
            "wallets": [
              "0xabc0000000000000000000000000000000000001"
            ],
            "expiresAt": "2026-10-11T12:05:00.000Z"
          }
        ]
      },
      "DistributorClaimRequest": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "benefitId": {
                "type": "string",
                "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
              },
              "wallet": {
                "anyOf": [
                  {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  },
                  {
                    "type": "string",
                    "pattern": "^[1-9A-HJ-NP-Za-km-z]{32,44}$"
                  }
                ]
              },
              "nonce": {
                "type": "string",
                "pattern": "^[0-9a-f]{32}$"
              },
              "signature": {
                "type": "string",
                "maxLength": 132
              }
            },
            "required": [
              "benefitId",
              "wallet",
              "nonce",
              "signature"
            ],
            "additionalProperties": false,
            "description": "The wallet proof: the benefit the claim stands on, the wallet that signs the challenge, the challenge's one-time nonce and the signature over the challenge's own message."
          },
          {
            "type": "object",
            "properties": {
              "benefitId": {
                "type": "string",
                "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
              },
              "subject": {
                "type": "object",
                "properties": {
                  "payload": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {},
                    "description": "The signed statement itself: the payload the venue signs the canonical message over, in the exact spellings the signature binds. Its shapes stand in the contracts beside the wallet read's and on the sign a balance statement page, which documents the exact message the signature binds; this document names no balance."
                  },
                  "signature": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "keyId": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "at": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "kind": {
                    "type": "string",
                    "const": "attested"
                  },
                  "venueId": {
                    "type": "string",
                    "pattern": "^tnt_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
                  },
                  "accountRef": {
                    "type": "string",
                    "maxLength": 256,
                    "pattern": "^[A-Za-z0-9._:-]{1,128}$"
                  }
                },
                "required": [
                  "payload",
                  "at",
                  "kind",
                  "venueId",
                  "accountRef"
                ],
                "additionalProperties": false,
                "description": "The attested subject the claim is about: the one subject the eligibility read's request carries. The distributor's own key presents the statement its own system signed, with the id of the registered key that verified it, the instant the call was made, and the venue and the account the statement binds, each once; the request's own fields must name the statement's own venue and account, and Yutai re-checks the statement and every rule at claim time. The statement's own shapes stand in the contracts beside the wallet read's and on the sign a balance statement page, which documents the exact message the signature binds; this document names no balance."
              }
            },
            "required": [
              "benefitId",
              "subject"
            ],
            "additionalProperties": false,
            "description": "The attested ask: a custodial distributor claims a benefit for its own customer by presenting the signed statement its own key signs. Yutai re-checks the statement and every rule at claim time, so the answer reflects the world as it stands."
          }
        ],
        "examples": [
          {
            "benefitId": "bft_01K4V9QG000000000000000001",
            "wallet": "0xabc0000000000000000000000000000000000001",
            "nonce": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
            "signature": "0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab"
          }
        ]
      },
      "DistributorClaimOutcome": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "claimed",
                "description": "The granted answer's own word: always claimed."
              },
              "claimId": {
                "type": "string",
                "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
                "description": "The claim's own opaque id, the address the claim read answers at."
              },
              "benefitId": {
                "type": "string",
                "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
                "description": "The benefit the claim was granted for, by its own opaque id."
              },
              "venueId": {
                "type": "string",
                "pattern": "^tnt_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
                "description": "The venue that asked, by its own tenant id; no other venue's claim answers it."
              },
              "subjectKeys": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "The wallets the claim's challenge named, the ones the venue itself saw; never the holder's other wallets."
              },
              "alreadyClaimed": {
                "type": "boolean",
                "description": "True when this call replayed a claim already recorded and false on the first grant; the same call answers the same words twice."
              },
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                "description": "The instant Yutai recorded the claim and its decision, as an ISO 8601 string."
              },
              "code": {
                "description": "The code the holder redeems, present only when the benefit delivers by code; a replay answers the same code, never a second take.",
                "type": "string",
                "minLength": 1,
                "maxLength": 128
              },
              "link": {
                "description": "The holder's private redemption link, present on the first grant only; a replay carries no link.",
                "type": "string",
                "minLength": 1,
                "maxLength": 512
              },
              "decision": {
                "type": "object",
                "properties": {
                  "eligible": {
                    "type": "boolean"
                  },
                  "tree": {
                    "maxItems": 64,
                    "type": "array",
                    "items": {
                      "$ref": "#/$defs/__schema0"
                    }
                  },
                  "simulatedInputs": {
                    "maxItems": 576,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "tenure",
                            "position",
                            "country",
                            "spend",
                            "consent",
                            "venue",
                            "holding",
                            "price",
                            "stock"
                          ]
                        },
                        "securityId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256
                        }
                      },
                      "required": [
                        "kind"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "eligible",
                  "tree"
                ],
                "additionalProperties": false,
                "description": "The claim's own decision: whether the benefit's rules granted it, with only the notes the eligibility read and the challenge already answer a venue."
              }
            },
            "required": [
              "status",
              "claimId",
              "benefitId",
              "venueId",
              "subjectKeys",
              "alreadyClaimed",
              "createdAt",
              "decision"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "refused",
                "description": "The refused answer's own word: always refused."
              },
              "reason": {
                "type": "string",
                "enum": [
                  "unknown_challenge",
                  "other_venue",
                  "other_benefit",
                  "not_consumed",
                  "no_holder",
                  "conflicting_holders",
                  "unknown_benefit",
                  "no_offer",
                  "already_claimed",
                  "not_eligible"
                ],
                "description": "Why the claim was refused, one of the closed list of plain reasons a venue branches on."
              },
              "decision": {
                "description": "The benefit's decision, present only when the world itself refused (the rulebook, the holdings trail or the country); an already claimed refusal carries none.",
                "type": "object",
                "properties": {
                  "eligible": {
                    "type": "boolean"
                  },
                  "tree": {
                    "maxItems": 64,
                    "type": "array",
                    "items": {
                      "$ref": "#/$defs/__schema0"
                    }
                  },
                  "simulatedInputs": {
                    "maxItems": 576,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "tenure",
                            "position",
                            "country",
                            "spend",
                            "consent",
                            "venue",
                            "holding",
                            "price",
                            "stock"
                          ]
                        },
                        "securityId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256
                        }
                      },
                      "required": [
                        "kind"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "eligible",
                  "tree"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "status",
              "reason"
            ],
            "additionalProperties": false
          }
        ],
        "$defs": {
          "__schema0": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "tenure",
                  "holding",
                  "country",
                  "spend",
                  "consent",
                  "venue",
                  "holds",
                  "holds_any",
                  "holds_all",
                  "holds_count",
                  "window",
                  "stock",
                  "authorisation_active",
                  "not_paused",
                  "recipient_evm",
                  "not_already_claimed",
                  "attestation_given",
                  "jurisdiction",
                  "recipient_rules"
                ]
              },
              "met": {
                "type": "boolean"
              },
              "note": {
                "type": "string",
                "minLength": 1,
                "maxLength": 512
              },
              "simulatedInputs": {
                "maxItems": 576,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "tenure",
                        "position",
                        "country",
                        "spend",
                        "consent",
                        "venue",
                        "holding",
                        "price",
                        "stock"
                      ]
                    },
                    "securityId": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 256
                    }
                  },
                  "required": [
                    "kind"
                  ],
                  "additionalProperties": false
                }
              },
              "children": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "$ref": "#/$defs/__schema0"
                }
              }
            },
            "required": [
              "kind",
              "met",
              "note"
            ],
            "additionalProperties": false
          }
        },
        "examples": [
          {
            "status": "claimed",
            "claimId": "clm_01K4V9QG000000000000000001",
            "benefitId": "bft_01K4V9QG000000000000000001",
            "venueId": "tnt_01K4V9QG000000000000000002",
            "subjectKeys": [
              "evm:0xabc0000000000000000000000000000000000001"
            ],
            "alreadyClaimed": false,
            "createdAt": "2026-10-11T12:05:00.000Z",
            "code": "SAMPLE-LOUNGE-0001",
            "link": "https://app.yutai.com/r/clm_01K4V9QG000000000000000001?t=sample-redemption-token-0000000000000000000",
            "decision": {
              "eligible": true,
              "tree": [
                {
                  "kind": "tenure",
                  "met": true,
                  "note": "The wallet's own trail stands 452 days behind this ask."
                }
              ]
            }
          }
        ]
      },
      "DistributorClaimLink": {
        "type": "object",
        "properties": {
          "claimId": {
            "type": "string",
            "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The claim's own id, the one the claim answer carried."
          },
          "link": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "The one absolute address where the holder finishes the claim."
          }
        },
        "required": [
          "claimId",
          "link"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "claimId": "clm_01K4V9QG000000000000000001",
            "link": "https://app.yutai.com/r/clm_01K4V9QG000000000000000001?t=sample-redemption-token-0000000000000000000"
          }
        ]
      },
      "DistributorFulfilmentRead": {
        "type": "object",
        "properties": {
          "fulfilmentId": {
            "type": "string",
            "pattern": "^ful_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The fulfilment's own opaque id, the address its confirm answers at."
          },
          "claimId": {
            "type": "string",
            "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The claim this fulfilment opens beside, by its own opaque id."
          },
          "benefitId": {
            "type": "string",
            "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The benefit this fulfilment credits, by its own opaque id."
          },
          "benefitName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The benefit's name as the programme carries it, so a fulfilment reads without a second lookup."
          },
          "state": {
            "type": "string",
            "enum": [
              "waiting on the venue",
              "credited by the venue"
            ],
            "description": "Where the fulfilment stands in plain words: waiting on the venue until its confirm lands, then credited by the venue."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "The instant the fulfilment was opened, the moment the credit began waiting on the venue."
          },
          "venueReference": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "The venue's own reference for the credit, one to the stored maximum characters; present only once credited."
          },
          "confirmedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "The instant the venue's confirm was recorded; present only once the row is credited by the venue."
          }
        },
        "required": [
          "fulfilmentId",
          "claimId",
          "benefitId",
          "benefitName",
          "state",
          "createdAt"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "fulfilmentId": "ful_01K4V9QG000000000000000001",
            "claimId": "clm_01K4V9QG000000000000000001",
            "benefitId": "bft_01K4V9QG000000000000000001",
            "benefitName": "Sample lounge access",
            "state": "waiting on the venue",
            "createdAt": "2026-10-11T12:05:00.000Z"
          }
        ]
      },
      "DistributorFulfilmentList": {
        "type": "object",
        "properties": {
          "fulfilments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fulfilmentId": {
                  "type": "string",
                  "pattern": "^ful_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
                  "description": "The fulfilment's own opaque id, the address its confirm answers at."
                },
                "claimId": {
                  "type": "string",
                  "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
                  "description": "The claim this fulfilment opens beside, by its own opaque id."
                },
                "benefitId": {
                  "type": "string",
                  "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
                  "description": "The benefit this fulfilment credits, by its own opaque id."
                },
                "benefitName": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128,
                  "description": "The benefit's name as the programme carries it, so a fulfilment reads without a second lookup."
                },
                "state": {
                  "type": "string",
                  "enum": [
                    "waiting on the venue",
                    "credited by the venue"
                  ],
                  "description": "Where the fulfilment stands in plain words: waiting on the venue until its confirm lands, then credited by the venue."
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                  "description": "The instant the fulfilment was opened, the moment the credit began waiting on the venue."
                },
                "venueReference": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "The venue's own reference for the credit, one to the stored maximum characters; present only once credited."
                },
                "confirmedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                  "description": "The instant the venue's confirm was recorded; present only once the row is credited by the venue."
                }
              },
              "required": [
                "fulfilmentId",
                "claimId",
                "benefitId",
                "benefitName",
                "state",
                "createdAt"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "fulfilments"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "fulfilments": [
              {
                "fulfilmentId": "ful_01K4V9QG000000000000000001",
                "claimId": "clm_01K4V9QG000000000000000001",
                "benefitId": "bft_01K4V9QG000000000000000001",
                "benefitName": "Sample lounge access",
                "state": "waiting on the venue",
                "createdAt": "2026-10-11T12:05:00.000Z"
              }
            ]
          }
        ]
      },
      "DistributorFulfilmentConfirmRequest": {
        "type": "object",
        "properties": {
          "venueReference": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          }
        },
        "required": [
          "venueReference"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "venueReference": "Lounge visit 2026-10-08, table 12"
          }
        ]
      },
      "DistributorRegistryCompanyPage": {
        "type": "object",
        "properties": {
          "items": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "country": {
                  "type": "string",
                  "pattern": "^[A-Z]{2}$"
                },
                "sourceMode": {
                  "type": "string",
                  "enum": [
                    "SIMULATED",
                    "SANDBOX",
                    "LIVE"
                  ]
                },
                "securities": {
                  "minItems": 1,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "isin": {
                        "type": "string",
                        "pattern": "^[A-Z]{2}[A-Z0-9]{9}[0-9]$"
                      },
                      "ticker": {
                        "type": "string",
                        "pattern": "^[A-Z0-9.-]{1,16}$"
                      },
                      "instruments": {
                        "minItems": 1,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "instrumentId": {
                              "type": "string",
                              "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\\/[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}$"
                            },
                            "chain": {
                              "type": "string",
                              "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$"
                            },
                            "wrapperName": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 128
                            },
                            "tokenIssuerName": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 256
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "legalForm": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "synthetic_tracker",
                                    "security_entitlement_ucc8",
                                    "native_registered_share",
                                    "other"
                                  ]
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "issuerSponsored": {
                              "type": "boolean"
                            },
                            "transferModel": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "open",
                                    "permissioned_whitelist"
                                  ]
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "kycByWrapper": {
                              "type": "boolean"
                            },
                            "convertsTo": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "instrumentId": {
                                      "type": "string",
                                      "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\\/[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}$"
                                    },
                                    "wrapperName": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 128
                                    }
                                  },
                                  "required": [
                                    "instrumentId",
                                    "wrapperName"
                                  ],
                                  "additionalProperties": false
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "instrumentId",
                            "chain",
                            "wrapperName",
                            "tokenIssuerName",
                            "legalForm",
                            "issuerSponsored",
                            "transferModel",
                            "kycByWrapper",
                            "convertsTo"
                          ],
                          "additionalProperties": false
                        }
                      }
                    },
                    "required": [
                      "isin",
                      "ticker",
                      "instruments"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "name",
                "country",
                "sourceMode",
                "securities"
              ],
              "additionalProperties": false
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "nextCursor"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "items": [
              {
                "name": "Sample Global Holdings",
                "country": "US",
                "sourceMode": "SIMULATED",
                "securities": [
                  {
                    "isin": "US0000000009",
                    "ticker": "SGH",
                    "instruments": [
                      {
                        "instrumentId": "eip155:88880/erc20:0xabc0000000000000000000000000000000000001",
                        "chain": "eip155:88880",
                        "wrapperName": "Sample token programme",
                        "tokenIssuerName": null,
                        "legalForm": null,
                        "issuerSponsored": false,
                        "transferModel": null,
                        "kycByWrapper": false,
                        "convertsTo": null
                      }
                    ]
                  }
                ]
              }
            ],
            "nextCursor": "eyJ2IjoxLCJhZnRlciI6WyJTYW1wbGUgR2xvYmFsIEhvbGRpbmdzIiwiY21wXzAxSzRWOVFHMDAwMDAwMDAwMDAwMDAwMDAxIl19"
          }
        ]
      },
      "DistributorRegistryInstrumentPage": {
        "type": "object",
        "properties": {
          "items": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "instrumentId": {
                  "type": "string",
                  "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\\/[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}$"
                },
                "chain": {
                  "type": "string",
                  "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$"
                },
                "wrapperName": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                "tokenIssuerName": {
                  "anyOf": [
                    {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 256
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "legalForm": {
                  "anyOf": [
                    {
                      "type": "string",
                      "enum": [
                        "synthetic_tracker",
                        "security_entitlement_ucc8",
                        "native_registered_share",
                        "other"
                      ]
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "issuerSponsored": {
                  "type": "boolean"
                },
                "transferModel": {
                  "anyOf": [
                    {
                      "type": "string",
                      "enum": [
                        "open",
                        "permissioned_whitelist"
                      ]
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "kycByWrapper": {
                  "type": "boolean"
                },
                "convertsTo": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "instrumentId": {
                          "type": "string",
                          "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\\/[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}$"
                        },
                        "wrapperName": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128
                        }
                      },
                      "required": [
                        "instrumentId",
                        "wrapperName"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "instrumentId",
                "chain",
                "wrapperName",
                "tokenIssuerName",
                "legalForm",
                "issuerSponsored",
                "transferModel",
                "kycByWrapper",
                "convertsTo"
              ],
              "additionalProperties": false
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "nextCursor"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "items": [
              {
                "instrumentId": "eip155:88880/erc20:0xabc0000000000000000000000000000000000001",
                "chain": "eip155:88880",
                "wrapperName": "Sample token programme",
                "tokenIssuerName": null,
                "legalForm": null,
                "issuerSponsored": false,
                "transferModel": null,
                "kycByWrapper": false,
                "convertsTo": null
              }
            ],
            "nextCursor": null
          }
        ]
      },
      "DistributorConnectSessionCreateRequest": {
        "type": "object",
        "properties": {
          "externalRef": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._:-]{1,128}$"
          },
          "returnUrl": {
            "type": "string"
          },
          "context": {
            "type": "object",
            "properties": {
              "isin": {
                "type": "string",
                "pattern": "^[A-Z]{2}[A-Z0-9]{9}[0-9]$"
              },
              "companyId": {
                "type": "string",
                "pattern": "^cmp_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
              }
            },
            "additionalProperties": false
          },
          "locale": {
            "type": "string",
            "pattern": "^[A-Za-z]{2,8}(-[A-Za-z0-9]{1,8}){0,4}$"
          },
          "mode": {
            "default": "redirect",
            "type": "string",
            "enum": [
              "redirect",
              "popup",
              "app"
            ]
          },
          "view": {
            "default": "consent",
            "type": "string",
            "enum": [
              "consent",
              "purchases"
            ]
          },
          "wallets": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "address": {
                  "type": "string",
                  "pattern": "^[!-~]{3,256}$"
                },
                "chainFamily": {
                  "type": "string",
                  "enum": [
                    "EVM",
                    "SOLANA"
                  ]
                }
              },
              "required": [
                "address",
                "chainFamily"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "externalRef",
          "returnUrl"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "externalRef": "usr_8f2c1",
            "returnUrl": "https://wallet.example/yutai/return",
            "context": {
              "isin": "US0378331005"
            },
            "locale": "en-GB",
            "mode": "redirect",
            "view": "consent",
            "wallets": [
              {
                "address": "0xabc0000000000000000000000000000000000001",
                "chainFamily": "EVM"
              }
            ]
          }
        ]
      },
      "DistributorConnectSessionCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^cxs_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
          },
          "connectUrl": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "id",
          "connectUrl",
          "expiresAt"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "id": "cxs_01K4V9QG000000000000000001",
            "connectUrl": "https://app.yutai.com/connect/cxs_01K4V9QG000000000000000001?t=sample-connect-session-value-00000000000000",
            "expiresAt": "2026-10-18T12:15:00.000Z"
          }
        ]
      },
      "DistributorConnectSessionRead": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^cxs_[0-7][0-9A-HJKMNP-TV-Z]{25}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "opened",
              "connected",
              "cancelled",
              "failed",
              "expired"
            ]
          },
          "externalRef": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._:-]{1,128}$"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "completedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
              },
              {
                "type": "null"
              }
            ]
          },
          "failureReason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "consent_declined",
                  "bank_unavailable",
                  "country_not_supported"
                ]
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "status",
          "externalRef",
          "createdAt",
          "completedAt",
          "failureReason"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "id": "cxs_01K4V9QG000000000000000001",
            "status": "pending",
            "externalRef": "usr_8f2c1",
            "createdAt": "2026-10-18T12:00:00.000Z",
            "completedAt": null,
            "failureReason": null
          }
        ]
      },
      "WebhookTierChangedPayload": {
        "type": "object",
        "properties": {
          "asOf": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "The instant the tier refresh answered at."
          },
          "credentialId": {
            "type": "string",
            "pattern": "^crd_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the credential the move names."
          },
          "holderId": {
            "type": "string",
            "pattern": "^hld_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the holder whose credential moved."
          },
          "previousTier": {
            "type": "string",
            "enum": [
              "Holder",
              "Steward",
              "Patron"
            ],
            "description": "The tier the credential moved from."
          },
          "tier": {
            "type": "string",
            "enum": [
              "Holder",
              "Steward",
              "Patron"
            ],
            "description": "The tier the credential now names."
          }
        },
        "required": [
          "asOf",
          "credentialId",
          "holderId",
          "previousTier",
          "tier"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "asOf": "2026-10-11T09:00:00.000Z",
            "credentialId": "crd_01K4V9QG000000000000000001",
            "holderId": "hld_01K4V9QG000000000000000001",
            "previousTier": "Holder",
            "tier": "Steward"
          }
        ]
      },
      "WebhookBenefitUnlockedPayload": {
        "type": "object",
        "properties": {
          "benefitId": {
            "type": "string",
            "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the benefit that opened."
          },
          "tier": {
            "type": "string",
            "enum": [
              "Holder",
              "Steward",
              "Patron"
            ],
            "description": "The tier that opens the benefit."
          }
        },
        "required": [
          "benefitId",
          "tier"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "benefitId": "bft_01K4V9QG000000000000000002",
            "tier": "Steward"
          }
        ]
      },
      "WebhookClaimConfirmedPayload": {
        "type": "object",
        "properties": {
          "claimId": {
            "type": "string",
            "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the claim that was recorded."
          },
          "benefitId": {
            "type": "string",
            "pattern": "^bft_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the benefit the claim was made on."
          }
        },
        "required": [
          "claimId",
          "benefitId"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "claimId": "clm_01K4V9QG000000000000000003",
            "benefitId": "bft_01K4V9QG000000000000000002"
          }
        ]
      },
      "WebhookRedemptionRecordedPayload": {
        "type": "object",
        "properties": {
          "redemptionId": {
            "type": "string",
            "pattern": "^red_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the redemption that was recorded."
          },
          "claimId": {
            "type": "string",
            "pattern": "^clm_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
            "description": "The id of the claim the redemption redeemed."
          }
        },
        "required": [
          "redemptionId",
          "claimId"
        ],
        "additionalProperties": false,
        "examples": [
          {
            "redemptionId": "red_01K4V9QG000000000000000004",
            "claimId": "clm_01K4V9QG000000000000000003"
          }
        ]
      }
    }
  }
}
