{
  "ok": true,
  "data": {
    "openapi": "3.1.0",
    "info": {
      "title": "Sparq Node API",
      "version": "1.0.0",
      "description": "The JSON API of a Sparq (SPQ) full node. One process serves the chain,\nthe wallet reads, the payment gateway, the operator console and the\npublic block explorer.\n\n**Response envelope.** Every JSON response is `{ ok: boolean, data?: any,\nerror?: string }`. `ok` is `true` on success and `false` on failure; on\nfailure `error` carries a human-readable reason and `data` is absent.\nThere is no HTTP body that is not this shape.\n\n**Units.** 1 SPQ = 1,000,000 quanta. Amounts on the wire are integers in\nquanta; every response that carries one also carries a `…Formatted`\ndecimal string. Never do arithmetic on the formatted form.\n\n**Credentials.** `Authorization: Bearer spq_op_…` is an operator key\n(node control). `Authorization: Bearer spq_sk_…` is a merchant secret\nkey; `spq_pk_…` is a merchant publishable key and may only read. The two\nnamespaces never accept each other’s keys.\n\n**Rate limits.** Unauthenticated traffic is metered per source address\n(`publicRead`, `publicWrite`); authenticated traffic per credential. A\nrefused request is `429` with `Retry-After`.",
      "license": {
        "name": "MIT"
      }
    },
    "servers": [
      {
        "url": "https://pay.sparq.fi",
        "description": "A local node"
      }
    ],
    "x-chain-id": "sparq-devnet-1",
    "tags": [
      {
        "name": "node",
        "description": "Liveness, chain position, supply and difficulty."
      },
      {
        "name": "blocks",
        "description": "Blocks, headers and Merkle proofs."
      },
      {
        "name": "transactions",
        "description": "Looking up and submitting transactions."
      },
      {
        "name": "accounts",
        "description": "Balances and history."
      },
      {
        "name": "names",
        "description": "The on-chain handle registry."
      },
      {
        "name": "payments",
        "description": "Payment URIs, EMVCo payloads and payee resolution."
      },
      {
        "name": "invoices",
        "description": "Signed, publishable payment requests."
      },
      {
        "name": "network",
        "description": "Peer topology."
      },
      {
        "name": "mining",
        "description": "Local mining control. Operator only."
      },
      {
        "name": "faucet",
        "description": "Devnet-only test funds."
      },
      {
        "name": "gateway",
        "description": "The merchant-facing payment API. Charges, checkout and signed webhooks."
      },
      {
        "name": "explorer",
        "description": "The read-only public explorer index. GET only, and safe to put a CDN in front of."
      },
      {
        "name": "auth",
        "description": "Operator credentials: mint, inspect, re-scope, revoke."
      },
      {
        "name": "admin",
        "description": "Operator console reads. Every entry is recorded in the audit log."
      },
      {
        "name": "meta",
        "description": "The API describing itself."
      }
    ],
    "components": {
      "schemas": {
        "Envelope": {
          "type": "object",
          "required": [
            "ok"
          ],
          "properties": {
            "ok": {
              "type": "boolean"
            },
            "data": {
              "description": "Present when `ok` is true."
            },
            "error": {
              "type": "string",
              "description": "Present when `ok` is false."
            }
          }
        },
        "Error": {
          "type": "object",
          "required": [
            "ok",
            "error"
          ],
          "properties": {
            "ok": {
              "type": "boolean",
              "const": false
            },
            "error": {
              "type": "string"
            }
          }
        },
        "Page": {
          "type": "object",
          "properties": {
            "limit": {
              "type": "integer"
            },
            "offset": {
              "type": "integer",
              "nullable": true
            },
            "total": {
              "type": "integer"
            },
            "hasMore": {
              "type": "boolean"
            },
            "next": {
              "type": [
                "integer",
                "string",
                "null"
              ],
              "description": "Opaque cursor for the next page, or null."
            }
          }
        },
        "Amount": {
          "type": "integer",
          "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
          "minimum": 0
        },
        "AmountFormatted": {
          "type": "string",
          "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
          "examples": [
            "12.5"
          ]
        },
        "NodeStatus": {
          "type": "object",
          "description": "A one-shot view of the node: identity, chain position, peers and miner.",
          "properties": {
            "network": {
              "type": "string"
            },
            "chainId": {
              "type": "string",
              "examples": [
                "sparq-regtest-1"
              ]
            },
            "version": {
              "type": "string"
            },
            "height": {
              "type": "integer"
            },
            "tip": {
              "type": "string",
              "description": "Tip block hash."
            },
            "peers": {
              "type": "integer"
            },
            "mining": {
              "type": "boolean"
            },
            "mempool": {
              "type": "integer"
            },
            "supplyFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            }
          },
          "additionalProperties": true
        },
        "Readiness": {
          "type": "object",
          "description": "The verdict of every readiness check, with the reason each one reached it.",
          "properties": {
            "status": {
              "type": "string",
              "enum": [
                "ready",
                "not_ready"
              ]
            },
            "chainId": {
              "type": "string",
              "examples": [
                "sparq-regtest-1"
              ]
            },
            "uptimeSeconds": {
              "type": "integer"
            },
            "failing": {
              "type": "array",
              "description": "Names of the failed gate checks. Empty exactly when the status is 200.",
              "items": {
                "type": "string"
              }
            },
            "advisoryFailing": {
              "type": "array",
              "description": "Failed advisory checks. These are reported but never change the status.",
              "items": {
                "type": "string"
              }
            },
            "checks": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "gate",
                      "advisory"
                    ]
                  },
                  "description": {
                    "type": "string"
                  },
                  "ok": {
                    "type": "boolean"
                  },
                  "detail": {
                    "type": "string"
                  }
                },
                "required": [
                  "name",
                  "kind",
                  "ok"
                ]
              }
            }
          },
          "required": [
            "status",
            "checks"
          ]
        },
        "ChainStats": {
          "type": "object",
          "properties": {
            "height": {
              "type": "integer"
            },
            "blocks": {
              "type": "integer"
            },
            "accounts": {
              "type": "integer"
            },
            "transactions": {
              "type": "integer"
            },
            "names": {
              "type": "integer"
            },
            "supplyFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            }
          },
          "additionalProperties": true
        },
        "Supply": {
          "type": "object",
          "properties": {
            "circulating": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "circulatingFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "maxSupply": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "maxSupplyFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "minted": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "percentIssued": {
              "type": "number"
            }
          }
        },
        "Difficulty": {
          "type": "object",
          "properties": {
            "bits": {
              "type": "integer",
              "description": "Leading zero bits required of a block hash."
            },
            "expectedHashes": {
              "type": "number",
              "description": "2^bits — the mean work per block."
            },
            "targetBlockTimeSeconds": {
              "type": "integer"
            },
            "retargetInterval": {
              "type": "integer"
            },
            "networkHashRateEstimate": {
              "type": "number"
            }
          }
        },
        "BlockSummary": {
          "type": "object",
          "description": "A block without its transaction bodies.",
          "properties": {
            "height": {
              "type": "integer"
            },
            "hash": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "prevHash": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "merkleRoot": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "timestamp": {
              "type": "integer",
              "description": "Unix milliseconds."
            },
            "difficulty": {
              "type": "integer"
            },
            "nonce": {
              "type": "integer"
            },
            "minerId": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "minerFormatted": {
              "type": "string"
            },
            "txCount": {
              "type": "integer"
            },
            "reward": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "rewardFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "confirmations": {
              "type": "integer"
            },
            "onMainChain": {
              "type": "boolean"
            }
          },
          "additionalProperties": true
        },
        "Block": {
          "allOf": [
            {
              "$ref": "#/components/schemas/BlockSummary"
            },
            {
              "type": "object",
              "properties": {
                "transactions": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Tx"
                  }
                }
              }
            }
          ]
        },
        "BlockHeader": {
          "type": "object",
          "description": "A header only — enough for a light client to verify PoW and chain work.",
          "properties": {
            "height": {
              "type": "integer"
            },
            "hash": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "prevHash": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "merkleRoot": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "timestamp": {
              "type": "integer"
            },
            "difficulty": {
              "type": "integer"
            },
            "nonce": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        },
        "Tx": {
          "type": "object",
          "description": "A transaction. `amount` and `fee` are integers in quanta.",
          "properties": {
            "txid": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "type": {
              "type": "string",
              "enum": [
                "transfer",
                "handle",
                "delegation",
                "invoice",
                "coinbase"
              ]
            },
            "from": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "to": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "amount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "amountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "fee": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "feeFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "nonce": {
              "type": "integer"
            },
            "ref": {
              "type": [
                "string",
                "null"
              ],
              "description": "The on-chain payment reference the payee matches on."
            },
            "memo": {
              "type": [
                "string",
                "null"
              ]
            },
            "publicKey": {
              "type": "string"
            },
            "signature": {
              "type": "string"
            }
          },
          "additionalProperties": true
        },
        "TxView": {
          "type": "object",
          "description": "A transaction plus where it lives. `status` is `confirmed` or `pending`.",
          "properties": {
            "txid": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "tx": {
              "$ref": "#/components/schemas/Tx"
            },
            "height": {
              "type": "integer"
            },
            "blockHash": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "confirmations": {
              "type": "integer"
            },
            "blockTimestamp": {
              "type": "integer"
            },
            "described": {
              "type": "string",
              "description": "A one-line human summary."
            },
            "status": {
              "type": "string",
              "enum": [
                "confirmed",
                "pending"
              ]
            }
          }
        },
        "MempoolTx": {
          "type": "object",
          "properties": {
            "txid": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "from": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "to": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "amount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "amountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "fee": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "nonce": {
              "type": "integer"
            },
            "type": {
              "type": "string"
            },
            "ref": {
              "type": [
                "string",
                "null"
              ]
            },
            "memo": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        },
        "Mempool": {
          "type": "object",
          "properties": {
            "size": {
              "type": "integer"
            },
            "bytes": {
              "type": "integer"
            },
            "minFeeQuanta": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "transactions": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/MempoolTx"
              }
            }
          },
          "additionalProperties": true
        },
        "Account": {
          "type": "object",
          "description": "A balance view. `balance` is spendable now; `immature` is mined but not yet mature.",
          "properties": {
            "id": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "idFormatted": {
              "type": "string"
            },
            "balance": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "balanceFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "immature": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "immatureFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "total": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "totalFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "nonce": {
              "type": "integer"
            },
            "handle": {
              "type": [
                "string",
                "null"
              ]
            },
            "pending": {
              "type": "integer",
              "description": "Quanta incoming in the mempool."
            }
          },
          "additionalProperties": true
        },
        "AccountHistoryEntry": {
          "type": "object",
          "properties": {
            "txid": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "height": {
              "type": "integer"
            },
            "delta": {
              "type": "integer",
              "description": "Signed change to this account, in quanta."
            },
            "deltaFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "amount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "amountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "fee": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "feeFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "direction": {
              "type": "string",
              "enum": [
                "in",
                "out",
                "self"
              ]
            },
            "counterparty": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "timestamp": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        },
        "Name": {
          "type": "object",
          "description": "An on-chain handle registration.",
          "properties": {
            "handle": {
              "type": "string",
              "description": "A registered handle, without the leading `@`.",
              "examples": [
                "sparq"
              ]
            },
            "formatted": {
              "type": "string",
              "examples": [
                "@sparq"
              ]
            },
            "owner": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "ownerFormatted": {
              "type": "string"
            },
            "registeredAt": {
              "type": "integer"
            },
            "expiresAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "paymentUri": {
              "type": "string"
            }
          },
          "additionalProperties": true
        },
        "ResolvedPayee": {
          "type": "object",
          "properties": {
            "found": {
              "type": "boolean"
            },
            "id": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "handle": {
              "type": [
                "string",
                "null"
              ]
            },
            "error": {
              "type": "string"
            },
            "uri": {
              "type": "string",
              "description": "A `sparq://` payment URI."
            },
            "emv": {
              "type": "string",
              "description": "An EMVCo merchant-presented QR payload."
            },
            "emvDecoded": {
              "type": "string"
            }
          },
          "additionalProperties": true
        },
        "Invoice": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "payee": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "amount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "amountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "memo": {
              "type": [
                "string",
                "null"
              ]
            },
            "ref": {
              "type": [
                "string",
                "null"
              ]
            },
            "createdAt": {
              "type": "integer"
            },
            "expiresAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "signerId": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "signature": {
              "type": "string"
            }
          },
          "additionalProperties": true
        },
        "Settlement": {
          "type": "object",
          "description": "Whether an invoice or charge has been paid, and how confidently.",
          "properties": {
            "status": {
              "type": "string",
              "enum": [
                "awaiting",
                "pending",
                "paid",
                "underpaid",
                "expired",
                "cancelled"
              ]
            },
            "paidQuanta": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "confirmations": {
              "type": "integer"
            },
            "txid": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          "additionalProperties": true
        },
        "Charge": {
          "type": "object",
          "description": "A payment request created by a merchant.",
          "properties": {
            "id": {
              "type": "string",
              "examples": [
                "ch_…"
              ]
            },
            "status": {
              "type": "string",
              "enum": [
                "awaiting",
                "pending",
                "paid",
                "underpaid",
                "expired",
                "cancelled"
              ]
            },
            "amount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "amountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "paidAmount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "paidAmountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "currency": {
              "type": "string",
              "const": "SPQ"
            },
            "description": {
              "type": [
                "string",
                "null"
              ]
            },
            "reference": {
              "type": [
                "string",
                "null"
              ]
            },
            "ref": {
              "type": "string",
              "description": "The on-chain reference a payer must include."
            },
            "payee": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "payeeFormatted": {
              "type": "string"
            },
            "uri": {
              "type": "string"
            },
            "emv": {
              "type": "string"
            },
            "checkoutUrl": {
              "type": "string"
            },
            "qrUrl": {
              "type": "string"
            },
            "metadata": {
              "type": [
                "object",
                "null"
              ]
            },
            "createdAt": {
              "type": "integer"
            },
            "expiresAt": {
              "type": "integer"
            },
            "settledAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "txid": {
              "type": [
                "string",
                "null"
              ]
            },
            "confirmations": {
              "type": "integer"
            },
            "late": {
              "type": "boolean"
            }
          },
          "additionalProperties": true
        },
        "Merchant": {
          "type": "object",
          "description": "A merchant profile. Secrets are never part of this shape.",
          "properties": {
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "payee": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "payeeFormatted": {
              "type": "string"
            },
            "email": {
              "type": [
                "string",
                "null"
              ]
            },
            "webhookUrl": {
              "type": [
                "string",
                "null"
              ]
            },
            "mcc": {
              "type": [
                "string",
                "null"
              ]
            },
            "city": {
              "type": [
                "string",
                "null"
              ]
            },
            "country": {
              "type": [
                "string",
                "null"
              ]
            },
            "createdAt": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        },
        "WebhookDelivery": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "event": {
              "type": "string",
              "examples": [
                "charge.paid"
              ]
            },
            "chargeId": {
              "type": [
                "string",
                "null"
              ]
            },
            "url": {
              "type": "string"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "delivering",
                "delivered",
                "failed",
                "exhausted"
              ]
            },
            "attempts": {
              "type": "integer"
            },
            "maxAttempts": {
              "type": "integer"
            },
            "createdAt": {
              "type": "integer"
            },
            "lastAttemptAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "nextAttemptAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "deliveredAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "responseStatus": {
              "type": [
                "integer",
                "null"
              ]
            },
            "responseBody": {
              "type": [
                "string",
                "null"
              ]
            },
            "error": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        },
        "OperatorKey": {
          "type": "object",
          "properties": {
            "keyId": {
              "type": "string"
            },
            "label": {
              "type": "string"
            },
            "scopes": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "last4": {
              "type": "string"
            },
            "createdAt": {
              "type": "integer"
            },
            "expiresAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "revokedAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "lastUsedAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "uses": {
              "type": "integer"
            }
          }
        },
        "AuditEntry": {
          "type": "object",
          "description": "One privileged action, allowed or refused. Refusals are recorded too.",
          "properties": {
            "at": {
              "type": "integer"
            },
            "action": {
              "type": "string"
            },
            "actor": {
              "type": "string"
            },
            "role": {
              "type": "string"
            },
            "allowed": {
              "type": "boolean"
            },
            "reason": {
              "type": [
                "string",
                "null"
              ]
            },
            "ip": {
              "type": "string"
            },
            "target": {
              "type": [
                "string",
                "null"
              ]
            },
            "detail": {
              "type": [
                "object",
                "null"
              ]
            }
          },
          "additionalProperties": true
        },
        "PeerInfo": {
          "type": "object",
          "properties": {
            "count": {
              "type": "integer"
            },
            "peers": {
              "type": "array",
              "items": {
                "type": "object",
                "additionalProperties": true
              }
            }
          },
          "additionalProperties": true
        },
        "MiningStats": {
          "type": "object",
          "properties": {
            "hashrate": {
              "type": "number"
            },
            "hashes": {
              "type": "integer"
            },
            "blocksFound": {
              "type": "integer"
            },
            "mining": {
              "type": "boolean"
            },
            "minerId": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            }
          },
          "additionalProperties": true
        },
        "FaucetInfo": {
          "type": "object",
          "properties": {
            "enabled": {
              "type": "boolean"
            },
            "address": {
              "type": [
                "string",
                "null"
              ]
            },
            "addressFormatted": {
              "type": [
                "string",
                "null"
              ]
            },
            "balance": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "balanceFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "defaultAmount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "maxAmount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "cooldownSeconds": {
              "type": "integer"
            },
            "note": {
              "type": "string"
            }
          }
        },
        "QrIntent": {
          "type": "object",
          "description": "A decoded payment intent, from either a `sparq://` URI or an EMVCo payload.",
          "properties": {
            "payee": {
              "type": "string"
            },
            "amount": {
              "type": [
                "integer",
                "null"
              ]
            },
            "memo": {
              "type": [
                "string",
                "null"
              ]
            },
            "ref": {
              "type": [
                "string",
                "null"
              ]
            },
            "network": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          "additionalProperties": true
        },
        "ExplorerStats": {
          "type": "object",
          "description": "Chain totals plus the read cache’s own counters.",
          "properties": {
            "height": {
              "type": "integer"
            },
            "tipHash": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "A 64-character lowercase hex digest."
            },
            "accounts": {
              "type": "integer"
            },
            "transactions": {
              "type": "integer"
            },
            "names": {
              "type": "integer"
            },
            "supplyFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "cache": {
              "type": "object",
              "properties": {
                "size": {
                  "type": "integer"
                },
                "maxEntries": {
                  "type": "integer"
                },
                "ttlMs": {
                  "type": "integer"
                },
                "hits": {
                  "type": "integer"
                },
                "misses": {
                  "type": "integer"
                },
                "evictions": {
                  "type": "integer"
                },
                "expirations": {
                  "type": "integer"
                },
                "hitRate": {
                  "type": "number"
                }
              }
            }
          },
          "additionalProperties": true
        },
        "RichListEntry": {
          "type": "object",
          "properties": {
            "rank": {
              "type": "integer"
            },
            "id": {
              "type": "string",
              "pattern": "^SPQ[0-9A-HJ-NP-Z]{20}$",
              "description": "A SparqID — the canonical address form, e.g. `SPQ…` (23 characters)."
            },
            "idFormatted": {
              "type": "string"
            },
            "handle": {
              "type": [
                "string",
                "null"
              ]
            },
            "balance": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "balanceFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "spendable": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "immature": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            }
          },
          "additionalProperties": true
        },
        "SearchResult": {
          "type": "object",
          "description": "What a free-text query resolved to. `kind` is `empty`, `height`, `hash`, `handle`, `account`, `ref`, `block`, `tx` or `unknown`.",
          "properties": {
            "query": {
              "type": "string"
            },
            "kind": {
              "type": "string"
            },
            "matches": {
              "type": "array",
              "items": {
                "type": "object",
                "additionalProperties": true
              }
            }
          },
          "additionalProperties": true
        },
        "Refund": {
          "type": "object",
          "description": "A refund against a paid charge. Recorded here, settled on-chain by the merchant.",
          "properties": {
            "id": {
              "type": "string",
              "examples": [
                "rf_…"
              ]
            },
            "object": {
              "type": "string",
              "const": "refund"
            },
            "merchantId": {
              "type": "string"
            },
            "chargeId": {
              "type": "string"
            },
            "amount": {
              "type": "integer",
              "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
              "minimum": 0
            },
            "amountFormatted": {
              "type": "string",
              "description": "Decimal SPQ amount as a string, with trailing zeros trimmed. Display only.",
              "examples": [
                "12.5"
              ]
            },
            "currency": {
              "type": "string",
              "const": "SPQ"
            },
            "reason": {
              "type": [
                "string",
                "null"
              ]
            },
            "note": {
              "type": [
                "string",
                "null"
              ]
            },
            "status": {
              "type": "string",
              "enum": [
                "issued",
                "settled",
                "cancelled"
              ]
            },
            "createdAt": {
              "type": "integer"
            },
            "settledAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "txid": {
              "type": [
                "string",
                "null"
              ]
            },
            "history": {
              "type": "array",
              "description": "Every state this refund has passed through, oldest first.",
              "items": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "at": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "additionalProperties": true
        },
        "TeamMember": {
          "type": "object",
          "description": "A merchant team member. Key material is never part of this shape.",
          "properties": {
            "id": {
              "type": "string",
              "examples": [
                "tm_…"
              ]
            },
            "object": {
              "type": "string",
              "const": "team_member"
            },
            "merchantId": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "email": {
              "type": [
                "string",
                "null"
              ]
            },
            "role": {
              "type": "string",
              "enum": [
                "admin",
                "developer",
                "viewer"
              ]
            },
            "keyLast4": {
              "type": "string",
              "description": "The last four characters of the member key, for recognition only."
            },
            "createdAt": {
              "type": "integer"
            },
            "lastUsedAt": {
              "type": [
                "integer",
                "null"
              ]
            },
            "revokedAt": {
              "type": [
                "integer",
                "null"
              ]
            }
          },
          "additionalProperties": true
        },
        "OpenApiDocument": {
          "type": "object",
          "description": "This document, generated from the running dispatcher.",
          "additionalProperties": true
        }
      },
      "securitySchemes": {
        "operatorKey": {
          "type": "http",
          "scheme": "bearer",
          "description": "An operator key, `spq_op_…`. Controls the node: mining, peers, keys, faucet limits and the audit log."
        },
        "merchantKey": {
          "type": "http",
          "scheme": "bearer",
          "description": "A merchant key. `spq_sk_…` reads and writes; `spq_pk_…` reads only and is refused on writes with 403."
        }
      }
    },
    "paths": {
      "/api/account/{id}": {
        "get": {
          "operationId": "getApiAccountById",
          "summary": "An account balance",
          "tags": [
            "accounts"
          ],
          "parameters": [
            {
              "name": "id",
              "in": "path",
              "required": true,
              "description": "A SparqID or an `@handle`.",
              "schema": {
                "type": "string"
              },
              "example": "@sparq"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Account"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/account/{id}/history": {
        "get": {
          "operationId": "getApiAccountByIdHistory",
          "summary": "Account history",
          "tags": [
            "accounts"
          ],
          "parameters": [
            {
              "name": "id",
              "in": "path",
              "required": true,
              "description": "A SparqID or an `@handle`.",
              "schema": {
                "type": "string"
              },
              "example": "@sparq"
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 500,
                "default": 50
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/accounts": {
        "get": {
          "operationId": "getApiAccounts",
          "summary": "Richest accounts",
          "tags": [
            "accounts"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 500,
                "default": 50
              }
            },
            {
              "name": "offset",
              "in": "query",
              "required": false,
              "description": "Rows to skip.",
              "schema": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/RichListEntry"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/admin/audit": {
        "get": {
          "operationId": "getApiAdminAudit",
          "summary": "Audit log",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000,
                "default": 100
              }
            },
            {
              "name": "action",
              "in": "query",
              "required": false,
              "description": "Exact action filter, e.g. `mining.start`.",
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "actor",
              "in": "query",
              "required": false,
              "description": "Exact actor filter.",
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "allowed",
              "in": "query",
              "required": false,
              "description": "`true` for allowed entries, `false` for refused ones.",
              "schema": {
                "type": "boolean"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/AuditEntry"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Refused attempts are recorded as faithfully as allowed ones.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "audit:read"
        }
      },
      "/api/admin/gateway/announcements": {
        "get": {
          "operationId": "getApiAdminGatewayAnnouncements",
          "summary": "List all platform announcements",
          "tags": [
            "admin"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        },
        "post": {
          "operationId": "postApiAdminGatewayAnnouncements",
          "summary": "Publish a platform announcement for merchants and users",
          "tags": [
            "admin"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "title",
                    "message"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Announcement headline."
                    },
                    "message": {
                      "type": "string",
                      "description": "Announcement body."
                    },
                    "level": {
                      "type": "string",
                      "description": "Severity level.",
                      "enum": [
                        "info",
                        "warning",
                        "urgent"
                      ],
                      "default": "info"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/announcements/{announcementId}": {
        "delete": {
          "operationId": "deleteApiAdminGatewayAnnouncementsByAnnouncementId",
          "summary": "Delete a platform announcement",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "announcementId",
              "in": "path",
              "required": true,
              "description": "Announcement id.",
              "schema": {
                "type": "string"
              },
              "example": "ann_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write"
        }
      },
      "/api/admin/gateway/merchants": {
        "get": {
          "operationId": "getApiAdminGatewayMerchants",
          "summary": "Every merchant, with approval state and earnings metrics",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "approval",
              "in": "query",
              "required": false,
              "description": "Filter by approval state.",
              "schema": {
                "type": "string",
                "enum": [
                  "auto",
                  "pending",
                  "approved",
                  "rejected",
                  "suspended"
                ]
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Secrets are never part of the shape, so the whole table is safe to render. `total` is the count after filtering.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        },
        "post": {
          "operationId": "postApiAdminGatewayMerchants",
          "summary": "Provision a merchant as operator",
          "tags": [
            "admin"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name",
                    "payee"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Trading name."
                    },
                    "payee": {
                      "type": "string",
                      "description": "Settlement SparqID or `@handle`."
                    },
                    "email": {
                      "type": "string",
                      "description": "Contact email."
                    },
                    "webhookUrl": {
                      "type": "string",
                      "description": "Webhook endpoint URL."
                    },
                    "city": {
                      "type": "string",
                      "description": "City."
                    },
                    "country": {
                      "type": "string",
                      "description": "Country code."
                    },
                    "autoApprove": {
                      "type": "boolean",
                      "description": "Automatically approve the merchant upon provisioning."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/merchants.csv": {
        "get": {
          "operationId": "getApiAdminGatewayMerchants.csv",
          "summary": "Export all merchants and volume metrics as CSV",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "approval",
              "in": "query",
              "required": false,
              "description": "Filter by approval status.",
              "schema": {
                "type": "string",
                "enum": [
                  "pending",
                  "approved",
                  "rejected",
                  "suspended"
                ]
              }
            }
          ],
          "responses": {
            "200": {
              "description": "Success",
              "content": {
                "text/csv": {
                  "schema": {
                    "type": "string"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        }
      },
      "/api/admin/gateway/merchants/{merchantId}": {
        "get": {
          "operationId": "getApiAdminGatewayMerchantsByMerchantId",
          "summary": "Inspect a merchant’s full earnings, pay-ins, payouts, refunds, and tickets",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        }
      },
      "/api/admin/gateway/merchants/{merchantId}/activate": {
        "post": {
          "operationId": "postApiAdminGatewayMerchantsByMerchantIdActivate",
          "summary": "Reactivate a suspended or rejected merchant",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {
                      "type": "string",
                      "description": "Operator reactivation note."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/merchants/{merchantId}/approve": {
        "post": {
          "operationId": "postApiAdminGatewayMerchantsByMerchantIdApprove",
          "summary": "Approve a merchant",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Idempotent — approving an approved merchant is a no-op that still answers 200. This is what sets `active: true`, and `active` is what allows the merchant to take payments.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {
                      "type": "string",
                      "description": "Why it was approved. Stored on the merchant."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/merchants/{merchantId}/charges.csv": {
        "get": {
          "operationId": "getApiAdminGatewayMerchantsByMerchantIdCharges.csv",
          "summary": "Export a merchant’s charges as CSV",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "Success",
              "content": {
                "text/csv": {
                  "schema": {
                    "type": "string"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "RFC 4180, one row per charge, with the header row always present so an empty export still opens in a spreadsheet. Served as an attachment. This is the operator-side reconciliation export; the merchant surface has no equivalent.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        }
      },
      "/api/admin/gateway/merchants/{merchantId}/limits": {
        "post": {
          "operationId": "postApiAdminGatewayMerchantsByMerchantIdLimits",
          "summary": "Update merchant risk tier, fee basis points, and charge/daily volume limits",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "riskTier": {
                      "type": "string",
                      "description": "Risk tier.",
                      "enum": [
                        "standard",
                        "verified",
                        "enterprise",
                        "high_risk"
                      ]
                    },
                    "feeBps": {
                      "type": "integer",
                      "description": "Platform fee in basis points (0-1000).",
                      "minimum": 0,
                      "maximum": 1000
                    },
                    "maxCharge": {
                      "type": "string",
                      "description": "Per-charge cap in SPQ (`0` or `null` for unlimited)."
                    },
                    "dailyLimit": {
                      "type": "string",
                      "description": "Rolling 24-hour charge cap in SPQ (`0` or `null` for unlimited)."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/merchants/{merchantId}/reject": {
        "post": {
          "operationId": "postApiAdminGatewayMerchantsByMerchantIdReject",
          "summary": "Reject a merchant",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Idempotent. Rejection clears any earlier approval, so a merchant is never approved and rejected at the same time.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string",
                      "description": "Why it was rejected. Stored and shown to the merchant."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/merchants/{merchantId}/suspend": {
        "post": {
          "operationId": "postApiAdminGatewayMerchantsByMerchantIdSuspend",
          "summary": "Suspend an active merchant",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "path",
              "required": true,
              "description": "Merchant id.",
              "schema": {
                "type": "string"
              },
              "example": "mch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string",
                      "description": "Reason for suspension."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/payouts": {
        "get": {
          "operationId": "getApiAdminGatewayPayouts",
          "summary": "List all merchant payouts across the platform",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "merchantId",
              "in": "query",
              "required": false,
              "description": "Filter by merchant id.",
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "status",
              "in": "query",
              "required": false,
              "description": "Filter by payout status.",
              "schema": {
                "type": "string",
                "enum": [
                  "requested",
                  "settled",
                  "cancelled"
                ]
              }
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 50
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        }
      },
      "/api/admin/gateway/payouts/{payoutId}/cancel": {
        "post": {
          "operationId": "postApiAdminGatewayPayoutsByPayoutIdCancel",
          "summary": "Cancel an unsettled merchant payout as platform operator",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "payoutId",
              "in": "path",
              "required": true,
              "description": "Payout id.",
              "schema": {
                "type": "string"
              },
              "example": "po_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string",
                      "description": "Cancellation reason."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/payouts/{payoutId}/settle": {
        "post": {
          "operationId": "postApiAdminGatewayPayoutsByPayoutIdSettle",
          "summary": "Settle a merchant payout as platform operator",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "payoutId",
              "in": "path",
              "required": true,
              "description": "Payout id.",
              "schema": {
                "type": "string"
              },
              "example": "po_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "txid": {
                      "type": "string",
                      "description": "On-chain transaction id."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/policy": {
        "post": {
          "operationId": "postApiAdminGatewayPolicy",
          "summary": "Update gateway onboarding and approval policy",
          "tags": [
            "admin"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "manualApproval": {
                      "type": "boolean",
                      "description": "Require operator approval before new merchants can create charges."
                    },
                    "openRegistration": {
                      "type": "boolean",
                      "description": "Allow self-service merchant registration."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/support": {
        "get": {
          "operationId": "getApiAdminGatewaySupport",
          "summary": "List merchant support tickets across the platform",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "status",
              "in": "query",
              "required": false,
              "description": "Filter by ticket status.",
              "schema": {
                "type": "string",
                "enum": [
                  "open",
                  "answered",
                  "resolved",
                  "closed"
                ]
              }
            },
            {
              "name": "merchantId",
              "in": "query",
              "required": false,
              "description": "Filter by merchant id.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:read"
        }
      },
      "/api/admin/gateway/support/{ticketId}/reply": {
        "post": {
          "operationId": "postApiAdminGatewaySupportByTicketIdReply",
          "summary": "Reply to a merchant support ticket as platform operator",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "ticketId",
              "in": "path",
              "required": true,
              "description": "Ticket id.",
              "schema": {
                "type": "string"
              },
              "example": "tkt_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Reply message."
                    },
                    "status": {
                      "type": "string",
                      "description": "Optional updated status.",
                      "enum": [
                        "open",
                        "answered",
                        "resolved",
                        "closed"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/gateway/support/{ticketId}/status": {
        "post": {
          "operationId": "postApiAdminGatewaySupportByTicketIdStatus",
          "summary": "Update a merchant support ticket status",
          "tags": [
            "admin"
          ],
          "parameters": [
            {
              "name": "ticketId",
              "in": "path",
              "required": true,
              "description": "Ticket id.",
              "schema": {
                "type": "string"
              },
              "example": "tkt_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "gateway:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Target status.",
                      "enum": [
                        "open",
                        "answered",
                        "resolved",
                        "closed"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/admin/security": {
        "get": {
          "operationId": "getApiAdminSecurity",
          "summary": "Security posture",
          "tags": [
            "admin"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Key counts, CORS origins, proxy trust, limiter occupancy, faucet limits and the bind host. Intended for a dashboard, not for polling in a loop.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "audit:read"
        }
      },
      "/api/auth/keys": {
        "get": {
          "operationId": "getApiAuthKeys",
          "summary": "List operator keys",
          "tags": [
            "auth"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/OperatorKey"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Returns metadata only — never a token, and never a hash.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "keys:write"
        },
        "post": {
          "operationId": "postApiAuthKeys",
          "summary": "Mint an operator key",
          "tags": [
            "auth"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The token is returned exactly once; only its hash is stored. A non-root key may not mint a key holding scopes it does not itself hold.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "keys:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string",
                      "description": "A human label, truncated to 64 characters."
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Defaults to the read-only set."
                    },
                    "expiresInSeconds": {
                      "type": "integer",
                      "description": "Lifetime. Omit for a key that does not expire.",
                      "minimum": 1
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/auth/keys/{keyId}": {
        "patch": {
          "operationId": "patchApiAuthKeysByKeyId",
          "summary": "Re-scope an operator key",
          "tags": [
            "auth"
          ],
          "parameters": [
            {
              "name": "keyId",
              "in": "path",
              "required": true,
              "description": "The key to re-scope.",
              "schema": {
                "type": "string"
              },
              "example": "key_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "keys:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "scopes"
                  ],
                  "properties": {
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/auth/keys/{keyId}/revoke": {
        "post": {
          "operationId": "postApiAuthKeysByKeyIdRevoke",
          "summary": "Revoke an operator key",
          "tags": [
            "auth"
          ],
          "parameters": [
            {
              "name": "keyId",
              "in": "path",
              "required": true,
              "description": "The key to revoke.",
              "schema": {
                "type": "string"
              },
              "example": "key_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Refuses to revoke the key the caller is authenticating with, so an operator cannot lock itself out by accident.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "keys:write"
        }
      },
      "/api/auth/me": {
        "get": {
          "operationId": "getApiAuthMe",
          "summary": "Validate an operator key",
          "tags": [
            "auth"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The admin console calls this to validate a pasted key before storing it, so a wrong paste fails immediately. Needs no particular scope — the answer is about the caller itself.",
          "security": [
            {
              "operatorKey": []
            }
          ]
        }
      },
      "/api/auth/scopes": {
        "get": {
          "operationId": "getApiAuthScopes",
          "summary": "Every scope and the read-only subset",
          "tags": [
            "auth"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Unauthenticated: a client needs to know the scope names before it can be granted one.",
          "security": []
        }
      },
      "/api/block/{ref}": {
        "get": {
          "operationId": "getApiBlockByRef",
          "summary": "A block with its transactions",
          "tags": [
            "blocks"
          ],
          "parameters": [
            {
              "name": "ref",
              "in": "path",
              "required": true,
              "description": "Block height or 64-hex block hash.",
              "schema": {
                "type": "string"
              },
              "example": "0"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Block"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/block/{ref}/merkle/{txid}": {
        "get": {
          "operationId": "getApiBlockByRefMerkleByTxid",
          "summary": "Merkle inclusion proof",
          "tags": [
            "blocks"
          ],
          "parameters": [
            {
              "name": "ref",
              "in": "path",
              "required": true,
              "description": "Block height or 64-hex block hash.",
              "schema": {
                "type": "string"
              },
              "example": "0"
            },
            {
              "name": "txid",
              "in": "path",
              "required": true,
              "description": "The transaction id to prove.",
              "schema": {
                "type": "string"
              },
              "example": "0000000000000000000000000000000000000000000000000000000000000000"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Public by construction: the proof is against a root already committed in the header, and it reveals nothing about the block’s other transactions.",
          "security": []
        }
      },
      "/api/blocks": {
        "get": {
          "operationId": "getApiBlocks",
          "summary": "Recent blocks",
          "tags": [
            "blocks"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 20
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Most recent first. For a paginated walk use `/api/explorer/blocks`.",
          "security": []
        }
      },
      "/api/chain/stats": {
        "get": {
          "operationId": "getApiChainStats",
          "summary": "Chain totals",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/ChainStats"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/difficulty": {
        "get": {
          "operationId": "getApiDifficulty",
          "summary": "Current difficulty",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Difficulty"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/explorer": {
        "get": {
          "operationId": "getApiExplorer",
          "summary": "Explorer discovery document",
          "tags": [
            "explorer"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Lists the explorer endpoints and their maximum page sizes, so a client can find the surface without reading the source.",
          "security": []
        }
      },
      "/api/explorer/address/{idOrHandle}": {
        "get": {
          "operationId": "getApiExplorerAddressByIdOrHandle",
          "summary": "An address page",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "idOrHandle",
              "in": "path",
              "required": true,
              "description": "A SparqID or an `@handle`.",
              "schema": {
                "type": "string"
              },
              "example": "@sparq"
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "default": 25
              }
            },
            {
              "name": "offset",
              "in": "query",
              "required": false,
              "description": "History rows to skip.",
              "schema": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Account"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Unlike `/api/account/{id}`, a valid id with no history is a real page showing a zero balance rather than a 404.",
          "security": []
        }
      },
      "/api/explorer/block/{heightOrHash}": {
        "get": {
          "operationId": "getApiExplorerBlockByHeightOrHash",
          "summary": "A block",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "heightOrHash",
              "in": "path",
              "required": true,
              "description": "A height or a 64-hex block hash.",
              "schema": {
                "type": "string"
              },
              "example": "0"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Block"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/explorer/blocks": {
        "get": {
          "operationId": "getApiExplorerBlocks",
          "summary": "Blocks, newest first",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "default": 20
              }
            },
            {
              "name": "before",
              "in": "query",
              "required": false,
              "description": "Return blocks at or below this height. **Inclusive.**",
              "schema": {
                "type": "integer",
                "minimum": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Page"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "`before` is inclusive, so `next` names the height just *below* the last block on the page. An off-by-one here duplicates a block on every page turn, which is why it is stated twice.",
          "security": []
        }
      },
      "/api/explorer/names": {
        "get": {
          "operationId": "getApiExplorerNames",
          "summary": "Registered handles",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 50
              }
            },
            {
              "name": "offset",
              "in": "query",
              "required": false,
              "description": "Rows to skip.",
              "schema": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              }
            },
            {
              "name": "q",
              "in": "query",
              "required": false,
              "description": "Case-insensitive prefix filter.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Name"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/explorer/richlist": {
        "get": {
          "operationId": "getApiExplorerRichlist",
          "summary": "Richest accounts",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 500,
                "default": 50
              }
            },
            {
              "name": "offset",
              "in": "query",
              "required": false,
              "description": "Rows to skip.",
              "schema": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/RichListEntry"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/explorer/search": {
        "get": {
          "operationId": "getApiExplorerSearch",
          "summary": "Search for anything",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "q",
              "in": "query",
              "required": true,
              "description": "A height, a block hash, a txid, a SparqID, an `@handle`, or a payment reference.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/SearchResult"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "A missing `q` is a 400. An empty `q` is a 200 with a hint, because the explorer renders \"you have not typed anything\" very differently from \"your request was malformed\".",
          "security": []
        }
      },
      "/api/explorer/stats": {
        "get": {
          "operationId": "getApiExplorerStats",
          "summary": "Chain totals and cache counters",
          "tags": [
            "explorer"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/ExplorerStats"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "A confirmed block’s body is immutable, so the cache keys bodies by hash and recomputes confirmations live. That is what makes it reorg-safe by construction rather than by invalidation.",
          "security": []
        }
      },
      "/api/explorer/tx/{txidOrRef}": {
        "get": {
          "operationId": "getApiExplorerTxByTxidOrRef",
          "summary": "A transaction",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "txidOrRef",
              "in": "path",
              "required": true,
              "description": "A 64-hex txid or a payment reference.",
              "schema": {
                "type": "string"
              },
              "example": "0000000000000000000000000000000000000000000000000000000000000000"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/TxView"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The shape matches `/api/tx/{txid}` including `described`, so a client can switch endpoints without re-learning the payload.",
          "security": []
        }
      },
      "/api/explorer/txs": {
        "get": {
          "operationId": "getApiExplorerTxs",
          "summary": "Transactions, newest first",
          "tags": [
            "explorer"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "default": 50
              }
            },
            {
              "name": "before",
              "in": "query",
              "required": false,
              "description": "Cursor from the previous page’s `next`, formatted `<height>:<index>`. **Exclusive.**",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Page"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The cursor is exclusive: it names the next position to emit, not the last one emitted. A reorged-out transaction is reported as not found rather than orphaned — the index is pruned on undo.",
          "security": []
        }
      },
      "/api/faucet": {
        "get": {
          "operationId": "getApiFaucet",
          "summary": "Faucet configuration and balance",
          "tags": [
            "faucet"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/FaucetInfo"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        },
        "post": {
          "operationId": "postApiFaucet",
          "summary": "Request a faucet drip",
          "tags": [
            "faucet"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Deliberately unauthenticated: a devnet faucet exists so an anonymous developer can get test funds. It is disabled off devnet, rate-limited per address and per source address, and capped by operator-set limits. Refused drips explain themselves in `error`.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "address": {
                      "type": "string",
                      "description": "A SparqID or an `@handle` to fund."
                    },
                    "amount": {
                      "type": "string",
                      "description": "Quanta to request. Clamped to the operator’s maximum."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/faucet/config": {
        "post": {
          "operationId": "postApiFaucetConfig",
          "summary": "Set faucet limits",
          "tags": [
            "faucet"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/FaucetInfo"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "faucet:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "defaultAmountQuanta": {
                      "type": "integer",
                      "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
                      "minimum": 0
                    },
                    "maxAmountQuanta": {
                      "type": "integer",
                      "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
                      "minimum": 0
                    },
                    "cooldownMs": {
                      "type": "integer",
                      "description": "Per-address cooldown in milliseconds."
                    },
                    "enabled": {
                      "type": "boolean",
                      "description": "Whether drips are allowed."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/announcements": {
        "get": {
          "operationId": "getApiGatewayAnnouncements",
          "summary": "List active platform announcements",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/gateway/charges": {
        "get": {
          "operationId": "getApiGatewayCharges",
          "summary": "List charges",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 50
              }
            },
            {
              "name": "status",
              "in": "query",
              "required": false,
              "description": "Filter by charge status.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Charge"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        },
        "post": {
          "operationId": "postApiGatewayCharges",
          "summary": "Create a charge",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "409": {
              "description": "Idempotency conflict: the key was reused with a different body.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Send an `Idempotency-Key` header (or the same field in the body) to make retries safe. Reusing a key with a *different* body is a 409, not a 400 — the caller can act on the distinction.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "amount": {
                      "type": "string",
                      "description": "Amount in SPQ, as a string. Prefer this or `amountQuanta`, never both computed differently."
                    },
                    "amountQuanta": {
                      "type": "integer",
                      "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
                      "minimum": 0
                    },
                    "reference": {
                      "type": "string",
                      "description": "Your order id. Echoed back and carried on the event."
                    },
                    "description": {
                      "type": "string",
                      "description": "Shown to the customer."
                    },
                    "ttlSeconds": {
                      "type": "integer",
                      "description": "How long the request lives.",
                      "minimum": 1
                    },
                    "metadata": {
                      "type": "object",
                      "description": "Stored verbatim and echoed back."
                    },
                    "requiredConfirmations": {
                      "type": "integer",
                      "description": "Confirmations before the charge counts as paid.",
                      "minimum": 0
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/charges/{chargeId}": {
        "get": {
          "operationId": "getApiGatewayChargesByChargeId",
          "summary": "One charge",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "chargeId",
              "in": "path",
              "required": true,
              "description": "Charge id.",
              "schema": {
                "type": "string"
              },
              "example": "ch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Charge"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/charges/{chargeId}/cancel": {
        "post": {
          "operationId": "postApiGatewayChargesByChargeIdCancel",
          "summary": "Cancel a charge",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "chargeId",
              "in": "path",
              "required": true,
              "description": "Charge id.",
              "schema": {
                "type": "string"
              },
              "example": "ch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Charge"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Cancelling does not and cannot undo a payment that already happened. A charge that settles after cancellation is reported with `late: true`.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string",
                      "description": "Why it was cancelled."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/charges/{chargeId}/refund": {
        "post": {
          "operationId": "postApiGatewayChargesByChargeIdRefund",
          "summary": "Refund a paid charge",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "chargeId",
              "in": "path",
              "required": true,
              "description": "Charge id.",
              "schema": {
                "type": "string"
              },
              "example": "ch_nonexistent"
            }
          ],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Refund"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Omit `amountQuanta` to refund the whole remaining refundable balance. Only a paid charge can be refunded, and the sum of live refunds may never exceed what the payer actually sent. 201 means recorded, not yet on-chain — settle it with the txid once the transfer is broadcast.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "amountQuanta": {
                      "type": "integer",
                      "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
                      "minimum": 0
                    },
                    "reason": {
                      "type": "string",
                      "description": "Why the refund was issued."
                    },
                    "note": {
                      "type": "string",
                      "description": "Internal memo."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/checkout/{chargeId}": {
        "get": {
          "operationId": "getApiGatewayCheckoutByChargeId",
          "summary": "The hosted checkout page",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "chargeId",
              "in": "path",
              "required": true,
              "description": "Charge id.",
              "schema": {
                "type": "string"
              },
              "example": "ch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "Success",
              "content": {
                "text/html": {
                  "schema": {
                    "type": "string"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "A static page that reads the charge id from its own URL and fetches its status. Serving it leaks nothing.",
          "security": []
        }
      },
      "/api/gateway/checkout/{chargeId}/status": {
        "get": {
          "operationId": "getApiGatewayCheckoutByChargeIdStatus",
          "summary": "Public charge status",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "chargeId",
              "in": "path",
              "required": true,
              "description": "Charge id.",
              "schema": {
                "type": "string"
              },
              "example": "ch_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Charge"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The only shape the customer’s browser ever sees. It exposes what a payer already sees on the QR and nothing else — no merchant identity beyond a display name, no secrets, no other charges.",
          "security": []
        }
      },
      "/api/gateway/customers": {
        "get": {
          "operationId": "getApiGatewayCustomers",
          "summary": "List repeat customers and payer intelligence for the authenticated merchant",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 500,
                "default": 100
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/earnings": {
        "get": {
          "operationId": "getApiGatewayEarnings",
          "summary": "Merchant earnings, pay-in volume, refunded volume, and payout summary",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/merchants": {
        "post": {
          "operationId": "postApiGatewayMerchants",
          "summary": "Self-register a merchant",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Open on devnet (`openRegistration`); 403 when the operator has closed self-registration. The `secretKey` is returned once and never again.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Trading name."
                    },
                    "payee": {
                      "type": "string",
                      "description": "Where settlement goes: a SparqID or `@handle`."
                    },
                    "email": {
                      "type": "string",
                      "description": "Contact address."
                    },
                    "webhookUrl": {
                      "type": "string",
                      "description": "Where to POST signed events."
                    },
                    "mcc": {
                      "type": "string",
                      "description": "ISO 18245 merchant category code."
                    },
                    "city": {
                      "type": "string",
                      "description": "City, for the EMV payload."
                    },
                    "country": {
                      "type": "string",
                      "description": "ISO 3166-1 alpha-2 country code."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/merchants/me": {
        "get": {
          "operationId": "getApiGatewayMerchantsMe",
          "summary": "The authenticated merchant",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        },
        "patch": {
          "operationId": "patchApiGatewayMerchantsMe",
          "summary": "Update authenticated merchant profile, settlement payee, or webhook URL",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Merchant"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Trading name."
                    },
                    "email": {
                      "type": "string",
                      "description": "Contact email."
                    },
                    "payee": {
                      "type": "string",
                      "description": "Settlement SparqID or `@handle`."
                    },
                    "webhookUrl": {
                      "type": "string",
                      "description": "Webhook endpoint URL."
                    },
                    "city": {
                      "type": "string",
                      "description": "City."
                    },
                    "country": {
                      "type": "string",
                      "description": "ISO country code."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/merchants/me/rotate-key": {
        "post": {
          "operationId": "postApiGatewayMerchantsMeRotate-key",
          "summary": "Rotate the secret key",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The new secret is shown once. The previous key stops working immediately.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/merchants/me/rotate-webhook-secret": {
        "post": {
          "operationId": "postApiGatewayMerchantsMeRotate-webhook-secret",
          "summary": "Rotate the webhook signing secret",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Signatures from the old secret fail immediately. Update the receiving endpoint first if you need a graceful swap — there is no overlap window.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/payment-links": {
        "get": {
          "operationId": "getApiGatewayPayment-links",
          "summary": "List reusable payment links for the authenticated merchant",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        },
        "post": {
          "operationId": "postApiGatewayPayment-links",
          "summary": "Create a reusable fixed or custom-amount payment link",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "title"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Display title for the payment link."
                    },
                    "description": {
                      "type": "string",
                      "description": "Optional description shown to customers."
                    },
                    "amount": {
                      "type": "string",
                      "description": "Fixed amount in SPQ (required unless `allowCustomAmount: true`)."
                    },
                    "allowCustomAmount": {
                      "type": "boolean",
                      "description": "Allow customer to enter a custom SPQ amount."
                    },
                    "minAmount": {
                      "type": "string",
                      "description": "Minimum custom amount in SPQ."
                    },
                    "maxAmount": {
                      "type": "string",
                      "description": "Maximum custom amount in SPQ."
                    },
                    "redirectUrl": {
                      "type": "string",
                      "description": "Optional post-payment redirect URL."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/payment-links/{linkId}": {
        "get": {
          "operationId": "getApiGatewayPayment-linksByLinkId",
          "summary": "Public details for a reusable payment link",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "linkId",
              "in": "path",
              "required": true,
              "description": "Payment link id.",
              "schema": {
                "type": "string"
              },
              "example": "pl_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        },
        "post": {
          "operationId": "postApiGatewayPayment-linksByLinkId",
          "summary": "Update a reusable payment link",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "linkId",
              "in": "path",
              "required": true,
              "description": "Payment link id.",
              "schema": {
                "type": "string"
              },
              "example": "pl_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Updated title."
                    },
                    "description": {
                      "type": "string",
                      "description": "Updated description."
                    },
                    "active": {
                      "type": "boolean",
                      "description": "Enable or disable the payment link."
                    },
                    "amount": {
                      "type": "string",
                      "description": "Updated fixed SPQ amount."
                    },
                    "allowCustomAmount": {
                      "type": "boolean",
                      "description": "Whether custom amounts are allowed."
                    },
                    "minAmount": {
                      "type": "string",
                      "description": "Minimum custom amount in SPQ."
                    },
                    "maxAmount": {
                      "type": "string",
                      "description": "Maximum custom amount in SPQ."
                    },
                    "redirectUrl": {
                      "type": "string",
                      "description": "Redirect URL."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/payment-links/{linkId}/session": {
        "post": {
          "operationId": "postApiGatewayPayment-linksByLinkIdSession",
          "summary": "Create a live checkout charge session from a payment link",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "linkId",
              "in": "path",
              "required": true,
              "description": "Payment link id.",
              "schema": {
                "type": "string"
              },
              "example": "pl_nonexistent"
            }
          ],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Charge"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "amount": {
                      "type": "string",
                      "description": "Customer-chosen amount in SPQ (when `allowCustomAmount: true`)."
                    },
                    "customerNote": {
                      "type": "string",
                      "description": "Optional customer note."
                    },
                    "reference": {
                      "type": "string",
                      "description": "Optional order reference."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/payouts": {
        "get": {
          "operationId": "getApiGatewayPayouts",
          "summary": "List merchant payouts and direct on-chain settlements",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 50
              }
            },
            {
              "name": "status",
              "in": "query",
              "required": false,
              "description": "Filter by payout status.",
              "schema": {
                "type": "string",
                "enum": [
                  "requested",
                  "settled",
                  "cancelled"
                ]
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        },
        "post": {
          "operationId": "postApiGatewayPayouts",
          "summary": "Create a merchant payout or settlement record",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "amount": {
                      "type": "string",
                      "description": "Payout amount in SPQ."
                    },
                    "amountQuanta": {
                      "type": "integer",
                      "description": "An exact count of quanta. 1 SPQ = 1,000,000 quanta.",
                      "minimum": 0
                    },
                    "destination": {
                      "type": "string",
                      "description": "Destination SparqID or `@handle`. Defaults to merchant payee."
                    },
                    "reference": {
                      "type": "string",
                      "description": "Internal payout reference."
                    },
                    "note": {
                      "type": "string",
                      "description": "Payout memo."
                    },
                    "txid": {
                      "type": "string",
                      "description": "On-chain settlement txid, if already broadcast."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/payouts/{payoutId}/cancel": {
        "post": {
          "operationId": "postApiGatewayPayoutsByPayoutIdCancel",
          "summary": "Cancel an unsettled merchant payout",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "payoutId",
              "in": "path",
              "required": true,
              "description": "Payout id.",
              "schema": {
                "type": "string"
              },
              "example": "po_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string",
                      "description": "Cancellation reason."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/payouts/{payoutId}/settle": {
        "post": {
          "operationId": "postApiGatewayPayoutsByPayoutIdSettle",
          "summary": "Record on-chain settlement txid for a payout",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "payoutId",
              "in": "path",
              "required": true,
              "description": "Payout id.",
              "schema": {
                "type": "string"
              },
              "example": "po_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "txid": {
                      "type": "string",
                      "description": "On-chain transaction id."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/qr/{chargeId}.svg": {
        "get": {
          "operationId": "getApiGatewayQrByChargeId.svg",
          "summary": "A charge’s QR code",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "chargeId",
              "in": "path",
              "required": true,
              "description": "Charge id, optionally with a `.svg` suffix.",
              "schema": {
                "type": "string"
              },
              "example": "ch_nonexistent.svg"
            },
            {
              "name": "format",
              "in": "query",
              "required": false,
              "description": "`emv` renders the EMVCo payload instead of the `sparq://` URI.",
              "schema": {
                "type": "string",
                "enum": [
                  "uri",
                  "emv"
                ],
                "default": "uri"
              }
            },
            {
              "name": "size",
              "in": "query",
              "required": false,
              "description": "Module scale, 2–20.",
              "schema": {
                "type": "integer",
                "minimum": 2,
                "maximum": 20,
                "default": 6
              }
            },
            {
              "name": "dark",
              "in": "query",
              "required": false,
              "description": "Dark module colour, as a CSS colour.",
              "schema": {
                "type": "string",
                "default": "#000000"
              }
            },
            {
              "name": "light",
              "in": "query",
              "required": false,
              "description": "Light module colour.",
              "schema": {
                "type": "string",
                "default": "#ffffff"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "Success",
              "content": {
                "image/svg+xml": {
                  "schema": {
                    "type": "string"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "410": {
              "description": "Gone — the charge was cancelled.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "410 once a charge has been cancelled, so a cached image is never shown for a dead request.",
          "security": []
        }
      },
      "/api/gateway/refunds": {
        "get": {
          "operationId": "getApiGatewayRefunds",
          "summary": "List refunds",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 50
              }
            },
            {
              "name": "status",
              "in": "query",
              "required": false,
              "description": "Filter by refund status.",
              "schema": {
                "type": "string",
                "enum": [
                  "issued",
                  "settled",
                  "cancelled"
                ]
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Refund"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/refunds/{refundId}": {
        "get": {
          "operationId": "getApiGatewayRefundsByRefundId",
          "summary": "One refund",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "refundId",
              "in": "path",
              "required": true,
              "description": "Refund id.",
              "schema": {
                "type": "string"
              },
              "example": "rf_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Refund"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "A refund belonging to another merchant is a 404, not a 403: the id space is not a directory, so a probe learns nothing.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/refunds/{refundId}/cancel": {
        "post": {
          "operationId": "postApiGatewayRefundsByRefundIdCancel",
          "summary": "Cancel an unsettled refund",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "refundId",
              "in": "path",
              "required": true,
              "description": "Refund id.",
              "schema": {
                "type": "string"
              },
              "example": "rf_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Refund"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Returns the amount to the charge’s refundable balance. A settled refund cannot be cancelled — cancelling after the money moved would only make the books disagree with the chain.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string",
                      "description": "Why it was cancelled."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/refunds/{refundId}/settle": {
        "post": {
          "operationId": "postApiGatewayRefundsByRefundIdSettle",
          "summary": "Record a refund’s on-chain settlement",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "refundId",
              "in": "path",
              "required": true,
              "description": "Refund id.",
              "schema": {
                "type": "string"
              },
              "example": "rf_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Refund"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The node records the merchant’s claim; it does not verify the txid against the chain, and it does not move funds. Idempotent for an already-settled refund. A cancelled refund cannot be settled.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "txid": {
                      "type": "string",
                      "description": "The 64-hex txid that carried the refund."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/stats": {
        "get": {
          "operationId": "getApiGatewayStats",
          "summary": "Gateway health",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "503 when the node was started with the gateway disabled.",
          "security": []
        }
      },
      "/api/gateway/support": {
        "get": {
          "operationId": "getApiGatewaySupport",
          "summary": "List support tickets for the authenticated merchant",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "status",
              "in": "query",
              "required": false,
              "description": "Filter by ticket status.",
              "schema": {
                "type": "string",
                "enum": [
                  "open",
                  "answered",
                  "resolved",
                  "closed"
                ]
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        },
        "post": {
          "operationId": "postApiGatewaySupport",
          "summary": "Open a support ticket with the platform operator",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "subject",
                    "message"
                  ],
                  "properties": {
                    "subject": {
                      "type": "string",
                      "description": "Support ticket subject."
                    },
                    "category": {
                      "type": "string",
                      "description": "Category (`general`, `settlement`, `payout`, `webhook`, `account`)."
                    },
                    "priority": {
                      "type": "string",
                      "description": "Priority (`low`, `normal`, `high`, `urgent`)."
                    },
                    "chargeId": {
                      "type": "string",
                      "description": "Optional related charge id."
                    },
                    "message": {
                      "type": "string",
                      "description": "Detailed description."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/support/{ticketId}/reply": {
        "post": {
          "operationId": "postApiGatewaySupportByTicketIdReply",
          "summary": "Reply to a support ticket as the merchant",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "ticketId",
              "in": "path",
              "required": true,
              "description": "Ticket id.",
              "schema": {
                "type": "string"
              },
              "example": "tkt_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Reply message."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/team": {
        "get": {
          "operationId": "getApiGatewayTeam",
          "summary": "List team members",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/TeamMember"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Key material is never returned, only the last four characters of each key. `roles` names the assignable roles so a client does not have to hard-code them.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        },
        "post": {
          "operationId": "postApiGatewayTeam",
          "summary": "Add a team member",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/TeamMember"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The member’s secret key is returned once, in this response, and never again. A `viewer` may read but not write. A read-only merchant key cannot manage the team at all.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Display name."
                    },
                    "role": {
                      "type": "string",
                      "description": "One of the assignable roles.",
                      "enum": [
                        "admin",
                        "developer",
                        "viewer"
                      ],
                      "default": "viewer"
                    },
                    "email": {
                      "type": "string",
                      "description": "Contact address."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/gateway/team/{memberId}": {
        "delete": {
          "operationId": "deleteApiGatewayTeamByMemberId",
          "summary": "Remove a team member",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "memberId",
              "in": "path",
              "required": true,
              "description": "Team member id.",
              "schema": {
                "type": "string"
              },
              "example": "tm_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Removal is immediate and deletes the member; their key stops working on the very next request. A member belonging to another merchant is a 404.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/team/{memberId}/rotate-key": {
        "post": {
          "operationId": "postApiGatewayTeamByMemberIdRotate-key",
          "summary": "Rotate a team member’s key",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "memberId",
              "in": "path",
              "required": true,
              "description": "Team member id.",
              "schema": {
                "type": "string"
              },
              "example": "tm_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/TeamMember"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The old key stops working immediately; there is no overlap window. Rotation also clears a previous revocation, so it doubles as re-activation.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/webhooks/deliveries": {
        "get": {
          "operationId": "getApiGatewayWebhooksDeliveries",
          "summary": "Webhook delivery log",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 25
              }
            },
            {
              "name": "chargeId",
              "in": "query",
              "required": false,
              "description": "Only deliveries for one charge.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/webhooks/deliveries/{deliveryId}/redeliver": {
        "post": {
          "operationId": "postApiGatewayWebhooksDeliveriesByDeliveryIdRedeliver",
          "summary": "Replay a delivery",
          "tags": [
            "gateway"
          ],
          "parameters": [
            {
              "name": "deliveryId",
              "in": "path",
              "required": true,
              "description": "Delivery id.",
              "schema": {
                "type": "string"
              },
              "example": "whd_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Replays with the same signature and the same event id, so a receiver that de-duplicates on the id will ignore it. That is the intended behaviour.",
          "security": [
            {
              "merchantKey": []
            }
          ]
        }
      },
      "/api/gateway/webhooks/test": {
        "post": {
          "operationId": "postApiGatewayWebhooksTest",
          "summary": "Send a test event",
          "tags": [
            "gateway"
          ],
          "parameters": [],
          "responses": {
            "202": {
              "description": "Accepted",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "202: the delivery is queued, not yet attempted. Poll `/deliveries` or watch your endpoint.",
          "security": [
            {
              "merchantKey": []
            }
          ],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "event": {
                      "type": "string",
                      "description": "Event name to forge.",
                      "default": "charge.paid"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/headers": {
        "get": {
          "operationId": "getApiHeaders",
          "summary": "Header feed for light clients",
          "tags": [
            "blocks"
          ],
          "parameters": [
            {
              "name": "from",
              "in": "query",
              "required": false,
              "description": "First height to include.",
              "schema": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              }
            },
            {
              "name": "to",
              "in": "query",
              "required": false,
              "description": "Last height to include. Defaults to the tip.",
              "schema": {
                "type": "integer"
              }
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10000,
                "default": 2000
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Headers only — a SPV client verifies PoW and chain work itself and never needs the bodies.",
          "security": []
        }
      },
      "/api/invoice": {
        "post": {
          "operationId": "postApiInvoice",
          "summary": "Publish a signed invoice",
          "tags": [
            "invoices"
          ],
          "parameters": [],
          "responses": {
            "201": {
              "description": "Created",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The invoice must carry a valid signature from its payee. The payee’s key is verified against the chain, not trusted from the request.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "A signed invoice, or `{ invoice: … }`.",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "/api/invoice/{id}": {
        "get": {
          "operationId": "getApiInvoiceById",
          "summary": "An invoice and its settlement",
          "tags": [
            "invoices"
          ],
          "parameters": [
            {
              "name": "id",
              "in": "path",
              "required": true,
              "description": "Invoice id.",
              "schema": {
                "type": "string"
              },
              "example": "inv_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Invoice"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/invoice/{id}/verify": {
        "post": {
          "operationId": "postApiInvoiceByIdVerify",
          "summary": "Verify an invoice without publishing it",
          "tags": [
            "invoices"
          ],
          "parameters": [
            {
              "name": "id",
              "in": "path",
              "required": true,
              "description": "Invoice id. Advisory only — the body is what is verified.",
              "schema": {
                "type": "string"
              },
              "example": "inv_nonexistent"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "A bad signature is a 200 with `{ valid: false, reason }`, not a 4xx. On success the invoice is also added to the node’s book.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "/api/invoices": {
        "get": {
          "operationId": "getApiInvoices",
          "summary": "The node’s invoice book",
          "tags": [
            "invoices"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Invoice"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/mempool": {
        "get": {
          "operationId": "getApiMempool",
          "summary": "Mempool contents",
          "tags": [
            "transactions"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Mempool"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/mining": {
        "get": {
          "operationId": "getApiMining",
          "summary": "Mining status",
          "tags": [
            "mining"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/MiningStats"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        },
        "post": {
          "operationId": "postApiMining",
          "summary": "Start or stop mining",
          "tags": [
            "mining"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/MiningStats"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Requires an operator key. The credential is checked before the body is read, so an anonymous caller receives the same 401 whether the body is well-formed or malformed.",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "mining:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "action"
                  ],
                  "properties": {
                    "action": {
                      "type": "string",
                      "enum": [
                        "start",
                        "stop"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/name/{handle}": {
        "get": {
          "operationId": "getApiNameByHandle",
          "summary": "Look up one handle",
          "tags": [
            "names"
          ],
          "parameters": [
            {
              "name": "handle",
              "in": "path",
              "required": true,
              "description": "The handle, with or without the leading `@`.",
              "schema": {
                "type": "string"
              },
              "example": "sparq"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Name"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/names": {
        "get": {
          "operationId": "getApiNames",
          "summary": "Registered handles",
          "tags": [
            "names"
          ],
          "parameters": [
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "description": "Maximum rows to return.",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200,
                "default": 100
              }
            },
            {
              "name": "offset",
              "in": "query",
              "required": false,
              "description": "Rows to skip.",
              "schema": {
                "type": "integer",
                "minimum": 0,
                "default": 0
              }
            },
            {
              "name": "q",
              "in": "query",
              "required": false,
              "description": "Case-insensitive prefix filter.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Name"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/openapi.json": {
        "get": {
          "operationId": "getApiOpenapi.json",
          "summary": "This document",
          "tags": [
            "meta"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/OpenApiDocument"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Generated from the same manifest the dispatcher is verified against, so it cannot describe a route the node does not serve.",
          "security": []
        }
      },
      "/api/pay/{payee}": {
        "get": {
          "operationId": "getApiPayByPayee",
          "summary": "Build a payment request for a payee",
          "tags": [
            "payments"
          ],
          "parameters": [
            {
              "name": "payee",
              "in": "path",
              "required": true,
              "description": "A SparqID or an `@handle`.",
              "schema": {
                "type": "string"
              },
              "example": "@sparq"
            },
            {
              "name": "amount",
              "in": "query",
              "required": false,
              "description": "Amount in SPQ, e.g. `12.5`.",
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "memo",
              "in": "query",
              "required": false,
              "description": "A note for the payer.",
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "ref",
              "in": "query",
              "required": false,
              "description": "Your reference. It is committed on-chain so the payee can match the payment.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/ResolvedPayee"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Returns both a `sparq://` URI and an EMVCo payload, plus a decoded description of each.",
          "security": []
        }
      },
      "/api/peers": {
        "get": {
          "operationId": "getApiPeers",
          "summary": "Peer list",
          "tags": [
            "network"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/PeerInfo"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Public: peer topology is the same class of information every public node exposes.",
          "security": []
        },
        "post": {
          "operationId": "postApiPeers",
          "summary": "Add peers",
          "tags": [
            "network"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/PeerInfo"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "peers:write",
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "peer": {
                      "type": "string",
                      "description": "A single `host:port` address."
                    },
                    "peers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Several addresses."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/peers/{address}": {
        "delete": {
          "operationId": "deleteApiPeersByAddress",
          "summary": "Remove a peer",
          "tags": [
            "network"
          ],
          "parameters": [
            {
              "name": "address",
              "in": "path",
              "required": true,
              "description": "The `host:port` to remove.",
              "schema": {
                "type": "string"
              },
              "example": "127.0.0.1:19779"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/PeerInfo"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "peers:write"
        }
      },
      "/api/qr/build": {
        "post": {
          "operationId": "postApiQrBuild",
          "summary": "Build a QR payload",
          "tags": [
            "payments"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payee": {
                      "type": "string",
                      "description": "A SparqID or an `@handle`."
                    },
                    "payeeName": {
                      "type": "string",
                      "description": "Display name for the payee."
                    },
                    "amount": {
                      "type": "string",
                      "description": "Amount in SPQ."
                    },
                    "memo": {
                      "type": "string",
                      "description": "A note."
                    },
                    "ref": {
                      "type": "string",
                      "description": "Your reference."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/qr/decode": {
        "post": {
          "operationId": "postApiQrDecode",
          "summary": "Decode a QR payload",
          "tags": [
            "payments"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "An undecodable payload is a 200 carrying `data.error` rather than a 4xx, because a scanner cannot act on a status code.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "payload"
                  ],
                  "properties": {
                    "payload": {
                      "type": "string",
                      "description": "A `sparq://` URI or an EMVCo payload, as scanned."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "/api/resolve": {
        "get": {
          "operationId": "getApiResolve",
          "summary": "Resolve anything payable",
          "tags": [
            "payments"
          ],
          "parameters": [
            {
              "name": "q",
              "in": "query",
              "required": false,
              "description": "A SparqID, an `@handle`, or a payment URI.",
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/ResolvedPayee"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/status": {
        "get": {
          "operationId": "getApiStatus",
          "summary": "Node status",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/NodeStatus"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "security": []
        }
      },
      "/api/supply": {
        "get": {
          "operationId": "getApiSupply",
          "summary": "Supply and issuance",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Supply"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Max supply is 84,000,000 SPQ and is a consensus constant.",
          "security": []
        }
      },
      "/api/tx/broadcast": {
        "post": {
          "operationId": "postApiTxBroadcast",
          "summary": "Broadcast a signed transaction",
          "tags": [
            "transactions"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "400": {
              "description": "Bad request — the body or query is malformed, or the operation is not allowed on this state.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Accepts `{ tx }` or a bare transaction. Fails with 400 and a reason when the transaction is structurally invalid, has a bad signature, or spends more than the account holds.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Either the transaction itself, or `{ tx: … }`.",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "/api/tx/validate": {
        "post": {
          "operationId": "postApiTxValidate",
          "summary": "Dry-run a transaction",
          "tags": [
            "transactions"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Never returns a 4xx for an invalid transaction: a rejected transaction is a 200 with `{ valid: false, reason }`. The response also reports the effective fee rate.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "/api/tx/{txid}": {
        "get": {
          "operationId": "getApiTxByTxid",
          "summary": "A transaction",
          "tags": [
            "transactions"
          ],
          "parameters": [
            {
              "name": "txid",
              "in": "path",
              "required": true,
              "description": "64-hex transaction id.",
              "schema": {
                "type": "string"
              },
              "example": "0000000000000000000000000000000000000000000000000000000000000000"
            }
          ],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/TxView"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Looks in the chain first, then the mempool. `status` distinguishes the two.",
          "security": []
        }
      },
      "/health": {
        "get": {
          "operationId": "getHealth",
          "summary": "Liveness probe",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/NodeStatus"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Cheap and unauthenticated. Returns 200 whenever the HTTP loop is alive, even mid-sync. Not rate limited, so an orchestrator can poll it as often as it likes.",
          "security": []
        }
      },
      "/metrics": {
        "get": {
          "operationId": "getMetrics",
          "summary": "Prometheus metrics",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "Success",
              "content": {
                "text/plain": {
                  "schema": {
                    "type": "string"
                  }
                }
              }
            },
            "401": {
              "description": "Missing or invalid credential.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "403": {
              "description": "Authenticated, but the credential does not hold the required scope — or self-registration is closed.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "404": {
              "description": "No such resource, or an unknown endpoint under a known namespace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "The Prometheus text exposition format, version 0.0.4 — not JSON, and not wrapped in the usual envelope. Every series is `sparq_`-prefixed. Request counts are labelled by a bounded route family rather than by path, so cardinality is a property of the code and not of the traffic. `--no-metrics` removes the route (404).",
          "security": [
            {
              "operatorKey": []
            }
          ],
          "x-required-scope": "metrics:read"
        }
      },
      "/ready": {
        "get": {
          "operationId": "getReady",
          "summary": "Readiness probe",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "object",
                    "required": [
                      "ok"
                    ],
                    "properties": {
                      "ok": {
                        "type": "boolean"
                      },
                      "data": {
                        "$ref": "#/components/schemas/Readiness"
                      },
                      "error": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "503": {
              "description": "The payment gateway is disabled on this node.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Answers a different question from `/health`: not \"is this process alive?\" but \"should this node be sent traffic?\". Every check is listed with its verdict, so a 503 names the gate that failed. Advisory checks are reported but never change the status.",
          "security": []
        }
      },
      "/rpc": {
        "post": {
          "operationId": "postRpc",
          "summary": "Exchange JSON-RPC 2.0 endpoint",
          "tags": [
            "node"
          ],
          "parameters": [],
          "responses": {
            "200": {
              "description": "OK",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "204": {
              "description": "Success",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "405": {
              "description": "Wrong method. The explorer namespace is read-only and answers `Allow: GET`.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "413": {
              "description": "Failure",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "429": {
              "description": "Rate limited. `Retry-After` says how long to wait.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            },
            "500": {
              "description": "The node failed to handle the request. The message is included; it is not a stack trace.",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/Envelope"
                  }
                }
              }
            }
          },
          "description": "Standard JSON-RPC 2.0 endpoint for cryptocurrency exchanges and institutional custodians. Accepts single requests, batch arrays (up to 100 calls), and notifications.",
          "security": [],
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jsonrpc",
                    "method",
                    "id"
                  ],
                  "properties": {
                    "jsonrpc": {
                      "type": "string",
                      "description": "JSON-RPC protocol version (`\"2.0\"`).",
                      "enum": [
                        "2.0"
                      ]
                    },
                    "id": {
                      "type": "integer",
                      "description": "Caller correlation identifier."
                    },
                    "method": {
                      "type": "string",
                      "description": "RPC method name (`getblockcount`, `getbestblockhash`, `getblock`, `getblockhash`, `getrawtransaction`, `sendrawtransaction`, `validateaddress`, `getbalance`, `getmempoolinfo`, `estimatesmartfee`, `getpeerinfo`, `getnetworkinfo`, `getblockchaininfo`, `getsupplyinfo`).",
                      "enum": [
                        "getblockcount",
                        "getbestblockhash",
                        "getblockhash",
                        "getblock",
                        "getrawtransaction",
                        "sendrawtransaction",
                        "validateaddress",
                        "getbalance",
                        "getmempoolinfo",
                        "estimatesmartfee",
                        "getpeerinfo",
                        "getnetworkinfo",
                        "getblockchaininfo",
                        "getsupplyinfo",
                        "help",
                        "rpc.discover"
                      ]
                    },
                    "params": {
                      "type": "array",
                      "description": "Positional parameters for the RPC method.",
                      "items": {}
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}