{
  "openapi": "3.1.0",
  "info": {
    "title": "Route customer API",
    "version": "1.44.0-preview",
    "description": "Route mainnet API: eight adapter families; wallet-authorized execution is available on exact supported paths. Garden is paused for new quotes and execution, including Garden-backed SwapKit paths. SwapKit execution covers supported simple EVM and native Bitcoin deposit routes; other SwapKit transaction types remain quote-only. NEAR and SwapKit support explicit project selection of Route-managed or customer credentials. Garden retains saved credentials and settings but cannot be enabled while paused. NEAR has builders for 26 networks, including Bitcoin, Solana, Fogo, NEAR, TRON, Sui and Aptos; reviewed NEAR/OFT compositions and Auto-route plans use separately authorized two- or three-step workflows. Owners control USD and delivery policy. See /docs/compatibility.md and /docs/protocol-execution.md for supported paths and wallet requirements. Ordinary JSON bodies allow 8192 bytes; transaction/signature allows 110000 bytes. Keep Route keys server-side. Hosted CCTP testnet uses an explicit Route-Network header and the separate /docs/testnet-openapi.json contract. Each API key selects one named policy; quotes and payments are isolated by policy. See /docs/routing-policies.md. Circle-to-Stellar managed minting uses OpenZeppelin Channels sponsorship, with optional customer-funded destination execution. Standard mainnet API pricing: 1 credit per policy-eligible comparison and 10 credits per verified completed logical payment, reserved at preparation. Auto-route costs 4 comparison credits and 40 completion credits. 1 USDC buys 1,000 credits. See /docs/usage-and-billing.md. GET /payments/{id}/next-action supplies a normalized observational action snapshot; see /docs/next-actions.md. Existing mutation endpoints and their authorization requirements are unchanged. Rift uses its current REST API for reviewed tokenized stocks, ETFs, vault shares and crypto. Direct reviewed EVM/Bitcoin orders require explicit acceptVariableOutput:true; minimumReceived remains null in quotes. HyperCore and composed Rift execution are unsupported. Provider-reported delivered/refunded is not completed settlement without independently attributed finalized chain evidence. Rift health, Ethereum USDC to Base USDC quotes, and Ethereum USDC to Ethereum AAPLon tokenized-stock quotes were verified from isolated Cloudflare staging on October 1, 2026. No orders were created or funded; live order execution and settlement remain unverified. Quote availability remains specific to the pair, amount and observation time.",
    "x-documentation-revision": "2026-10-07",
    "x-integration-changelog": "/docs/changelog.md"
  },
  "servers": [
    {
      "url": "https://route.click/v1",
      "description": "Hosted mainnet API; execution availability depends on the exact adapter path and owner policy."
    },
    {
      "url": "http://localhost:8788/v1",
      "description": "Local development. For the separate explicit testnet mode, use testnet-openapi.json."
    }
  ],
  "security": [
    {
      "routeKey": []
    }
  ],
  "paths": {
    "/assets": {
      "get": {
        "operationId": "listAssets",
        "summary": "listAssets",
        "description": "Required scope: catalog:read.",
        "x-required-scope": "catalog:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetCatalog"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/adapters": {
      "get": {
        "operationId": "listAdapters",
        "summary": "listAdapters",
        "description": "Required scope: catalog:read. Rift supports direct reviewed EVM and Bitcoin orders with explicit variable-output acceptance. HyperCore and composed Rift execution remain unsupported. Capabilities describe implemented paths, not current provider availability; each quote and wallet action must pass its own checks.",
        "x-required-scope": "catalog:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdapterCatalog"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/providers": {
      "get": {
        "operationId": "listConnections",
        "summary": "listConnections",
        "description": "Required scope: providers:read.",
        "x-required-scope": "providers:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderList"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/providers/{adapter}": {
      "put": {
        "operationId": "updateConnection",
        "summary": "updateConnection",
        "description": "Required scope: providers:write.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Update"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "adapter",
            "in": "path",
            "required": true,
            "schema": {
              "enum": [
                "allbridge",
                "circle",
                "near",
                "layerzero",
                "axelar",
                "garden",
                "swapkit",
                "rift"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProviderUpdate"
              }
            }
          }
        }
      }
    },
    "/providers/near/credential": {
      "put": {
        "operationId": "saveNearCredential",
        "summary": "saveNearCredential",
        "description": "Required scope: providers:write. Saving selects the customer connection. Existing payment preparations retain their recorded connection source. Use PUT /providers/near with credentialSource: route for Route-managed access.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialUpdateResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CredentialUpdate"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removeNearCredential",
        "summary": "removeNearCredential",
        "description": "Required scope: providers:write. Saving selects the customer connection. Existing payment preparations retain their recorded connection source. Use PUT /providers/near with credentialSource: route for Route-managed access. Removal is never blocked. When payments tracked with this key have funding in flight and no terminal outcome, the response carries warnings: [{code: UNSETTLED_PROVIDER_PAYMENTS, count, message}]. See /docs/providers/#removing-a-provider-key-with-payments-in-flight.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialUpdateResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Version"
              }
            }
          }
        }
      }
    },
    "/policy": {
      "get": {
        "operationId": "readPolicy",
        "summary": "readPolicy",
        "description": "Required scope: policy:read. Reads or updates only the policy assigned to this key. Revisions are immutable; send the current version when updating.",
        "x-required-scope": "policy:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "savePolicy",
        "summary": "savePolicy",
        "description": "Required scope: policy:write. Reads or updates only the policy assigned to this key. Revisions are immutable; send the current version when updating.",
        "x-required-scope": "policy:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PolicyInput"
              }
            }
          }
        }
      }
    },
    "/quotes": {
      "post": {
        "operationId": "createQuote",
        "summary": "createQuote",
        "description": "Required scope: quotes:write. Optional key route and USD restrictions apply before saving a new quote. Matching replays return the original evidence. Set autoRoute to compare direct and bounded two- and three-leg paths using TypeSafe intent classification. Auto-route consumes 4x standard credits (4 per eligible comparison, 40 per verified completed logical payment); unsuccessful comparisons remain free. See /docs/auto-route.md. Defaults to view=best with one recommendation summary. Use list for safely selectable alternatives, compact for all candidates and checks, or full for detailed evidence. Views preserve the saved quote and idempotency identity. Reads never create a payment, refresh providers, extend expiry or add a charge.",
        "x-required-scope": "quotes:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteResponse"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient available credits for a new mainnet comparison. No provider quote is requested. Add credits in Billing, then retry the same input and Idempotency-Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Persist with the operation. Reuse for identical retries, including across key rotation. A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "best",
                "list",
                "compact",
                "full"
              ],
              "default": "best"
            },
            "description": "Defaults to view=best with one recommendation summary. Use list for safely selectable alternatives, compact for all candidates and checks, or full for detailed evidence. Views preserve the saved quote and idempotency identity. Reads never create a payment, refresh providers, extend expiry or add a charge. Invalid or repeated values return 400 INVALID_QUOTE_VIEW before requesting a quote or reserving quote credits."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteInput"
              }
            }
          }
        }
      }
    },
    "/quotes/{id}": {
      "get": {
        "operationId": "readQuote",
        "summary": "readQuote",
        "description": "Required scope: quotes:read. Defaults to view=best with one recommendation summary. Use list for safely selectable alternatives, compact for all candidates and checks, or full for detailed evidence. Views preserve the saved quote and idempotency identity. Reads never create a payment, refresh providers, extend expiry or add a charge.",
        "x-required-scope": "quotes:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteResponse"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "best",
                "list",
                "compact",
                "full"
              ],
              "default": "best"
            },
            "description": "Defaults to view=best with one recommendation summary. Use list for safely selectable alternatives, compact for all candidates and checks, or full for detailed evidence. Views preserve the saved quote and idempotency identity. Reads never create a payment, refresh providers, extend expiry or add a charge. Invalid or repeated values return 400 INVALID_QUOTE_VIEW before requesting a quote or reserving quote credits."
          }
        ]
      }
    },
    "/payments": {
      "post": {
        "operationId": "preparePayment",
        "summary": "preparePayment",
        "description": "Required scope: payments:write. Create a draft only. Omitted candidateId accepts the saved recommendation after expiry, policy, provider and key checks; Route refuses an unusable choice without switching routes. Persist the UUID Idempotency-Key and identical request body. Replays return the original payment, even after quote expiry. Preparation, wallet authorization and signing remain separate.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Persist with the operation. Reuse for identical retries, including across key rotation. A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreparePayment"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listPayments",
        "summary": "List payments",
        "description": "Required scope: payments:read. Lists top-level mainnet payments within the key’s policy. Active excludes archived records. Composed legs remain available through their parent.",
        "x-required-scope": "payments:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentList"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "view",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "archived",
                "all"
              ],
              "default": "active"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque nextCursor from the preceding page. Keep the same view."
          }
        ]
      }
    },
    "/payments/{id}": {
      "get": {
        "operationId": "readPayment",
        "summary": "readPayment",
        "description": "Required scope: payments:read.",
        "x-required-scope": "payments:read",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/payments/{id}/cancel": {
      "post": {
        "operationId": "cancelDraft",
        "summary": "cancelDraft",
        "description": "Required scope: payments:write. Only before a preparation is reserved. Returns PREPARATION_EXISTS otherwise.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Version"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/execute": {
      "post": {
        "operationId": "executePayment",
        "summary": "executePayment",
        "description": "Required scope: payments:write. On released paths, makes one submission of the already verified immutable transaction following fresh checks. Commits the attempt before network I/O; retries/concurrent calls return saved state without another send. Timeout or process interruption requires tracking the existing hash. Once unresolved review evidence is recorded for the action (a wallet-altered copy of its payment call, the same payment found sent at another nonce, or any other transaction the wallet signed that was reported for it and is neither the saved transaction nor a recognized cancellation, whichever recovery, confirmation, cancellation, close or close-after-manual-check request observed it), execute returns 409 WALLET_TRANSACTION_REVIEW_REQUIRED with that evidence in error.details before any external read, for protocol actions and NEAR source transactions alike, whatever the account nonces show and even after a review refresh and a new signature; Route never sends the saved signature and the database refuses the same submission. While a recovery, cancellation or close check for the action is reading the network, it returns 409 WALLET_EVIDENCE_CHECK_IN_PROGRESS (details.retryable: true, details.retryAfterSeconds) before any network read; the check clears it when it records what it found, and it lapses after 2 minutes. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "202": {
            "description": "Submission outcome requires tracking; this response is not permission to resend.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitTransaction"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/prepare": {
      "post": {
        "operationId": "prepareDeposit",
        "summary": "prepareDeposit",
        "description": "Required scope: payments:write. Prepare one NEAR deposit, protocol payment or composed workflow; UUID Idempotency-Key required. This does not submit. Follow the matching guide and current flags. See /docs/protocol-execution.md and /docs/composed-payments.md. Rift requires the RiftPrepare body with acceptVariableOutput:true. Refunds return to sender. Same-terms retries reuse the saved allocation; do not replace a timed-out order. Initial composed preparation requires the intermediate wallet(s) described by next-action.action.walletRequirements. Missing or invalid addresses return 400 INVALID_INTERMEDIATE_WALLETS; per-address error.details identifies field and network. Correct the input on the same payment while its quote remains valid; an already-expired, unprepared draft needs a fresh quote.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPreparation"
                }
              }
            }
          },
          "201": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPreparation"
                }
              }
            }
          },
          "202": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPreparation"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient available credits to reserve this payment’s completion charge. Add credits and retry the same preparation. Existing prepared payments continue without another charge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrepareDeposit"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/preparation": {
      "get": {
        "operationId": "getPreparation",
        "summary": "getPreparation",
        "description": "Required scope: payments:read. Read saved NEAR/protocol preparation or composed workflow. Before preparation exists, NEAR returns 404 and protocols return {preparation:null}.",
        "x-required-scope": "payments:read",
        "responses": {
          "200": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentPreparation"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "preparation": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "preparation"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/payments/{id}/submission": {
      "post": {
        "operationId": "registerSource",
        "summary": "registerSource",
        "description": "Required scope: payments:write. NEAR only on mainnet: register an existing chain-specific source hash; not proof of funding and never a broadcast. Protocol payments reject this endpoint with SIGNED_ACTION_REQUIRED; use /transaction/signature then /execute.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPreparation"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterSource"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/refresh": {
      "post": {
        "operationId": "refreshPayment",
        "summary": "refreshPayment",
        "description": "Required scope: payments:write. Requests fresh provider and chain receipt evidence. NEAR uses {}; protocols accept an optional destinationHash which still requires verification. For SwapKit, destinationHash must match the delivery leg reported for the saved source transfer; the original provider connection is required even with a supplied hash. SwapKit also accepts refundHash, which must match the refund leg SwapKit reports. Composed parents refresh the active child. Never broadcasts a customer-signed transaction. For Circle to Stellar with managed destination execution, once the source burn is finalized and attested, refresh may submit the already-authorized destination mint through OpenZeppelin Channels unless managed delivery is paused; Route records one submission claim, so repeated refreshes and background tracking do not submit it again (apart from Route's single guarded automatic re-mint of a lost or failed relay), and destinationExecution reports its progress. A relay submission is not proof of settlement. LayerZero Stellar discovery uses direct OFT events with an explorer fallback; if both are unavailable it returns 503 DESTINATION_DISCOVERY_UNAVAILABLE. A supplied or saved hash is independently chain-verified without requiring LayerZero explorer discovery.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPreparation"
                }
              }
            }
          },
          "202": {
            "description": "Saved attempt, observation or replay; inspect state and readiness. 202 requires reconciliation or later tracking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPreparation"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "destinationHash": {
                    "type": "string",
                    "pattern": "^(0x)?[a-fA-F0-9]{64}$",
                    "description": "Optional destination transaction for protocol tracking. For SwapKit the original provider connection must report this exact transaction as the final delivery leg of the saved source transfer; Route then independently verifies the saved destination, exact asset, reported amount, minimum, time and canonical receipts. Missing credentials or provider attribution leave the payment and reservations unchanged. NEAR uses an empty body."
                  },
                  "refundHash": {
                    "type": "string",
                    "pattern": "^(0x)?[a-fA-F0-9]{64}$",
                    "description": "SwapKit only: optional known refund transaction. Accepted only when SwapKit tracking, through the payment's saved SwapKit connection, reports this exact transaction as the swap's refund leg; Route then verifies a finalized credit of the reported source-asset amount to the saved refund address after the source time. Any wallet can credit the refund address, so chain credit alone never settles a refund. Otherwise returns 409 REFUND_RECEIPT_MISMATCH, or 409 PROVIDER_CREDENTIAL_REQUIRED when the SwapKit connection was removed; the payment and its reservations are unchanged. When SwapKit cannot confirm a refund (connection removed, or tracking has no refund report), a workspace member can confirm it in the dashboard instead; API keys cannot. Route still verifies that transaction on chain and records tracking.refundConfirmation."
                  }
                },
                "required": [],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "summary": "listWebhooks",
        "x-required-scope": "webhooks:read",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResult"
                }
              }
            }
          },
          "default": {
            "description": "Scoped error; inspect error.code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Required scope: webhooks:read. Outbound delivery requires an operator-approved HTTPS origin; currently disabled. See /docs/webhooks.md."
      },
      "post": {
        "operationId": "createWebhook",
        "summary": "createWebhook",
        "x-required-scope": "webhooks:write",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResult"
                }
              }
            }
          },
          "default": {
            "description": "Scoped error; inspect error.code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "name",
                  "url"
                ]
              }
            }
          }
        },
        "description": "Required scope: webhooks:write. Outbound delivery requires an operator-approved HTTPS origin; currently disabled. See /docs/webhooks.md."
      }
    },
    "/webhooks/{id}": {
      "put": {
        "operationId": "updateWebhook",
        "summary": "updateWebhook",
        "x-required-scope": "webhooks:write",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResult"
                }
              }
            }
          },
          "default": {
            "description": "Scoped error; inspect error.code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "enabled",
                  "version"
                ]
              }
            }
          }
        },
        "description": "Required scope: webhooks:write. Outbound delivery requires an operator-approved HTTPS origin; currently disabled. See /docs/webhooks.md."
      }
    },
    "/webhooks/{id}/rotate": {
      "post": {
        "operationId": "rotateWebhookSecret",
        "summary": "rotateWebhookSecret",
        "x-required-scope": "webhooks:write",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResult"
                }
              }
            }
          },
          "default": {
            "description": "Scoped error; inspect error.code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "version"
                ]
              }
            }
          }
        },
        "description": "Required scope: webhooks:write. Outbound delivery requires an operator-approved HTTPS origin; currently disabled. See /docs/webhooks.md."
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "operationId": "testWebhook",
        "summary": "testWebhook",
        "x-required-scope": "webhooks:write",
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResult"
                }
              }
            }
          },
          "default": {
            "description": "Scoped error; inspect error.code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {},
                "required": []
              }
            }
          }
        },
        "description": "Required scope: webhooks:write. Outbound delivery requires an operator-approved HTTPS origin; currently disabled. See /docs/webhooks.md."
      }
    },
    "/webhooks/{id}/retry": {
      "post": {
        "operationId": "retryWebhook",
        "summary": "retryWebhook",
        "x-required-scope": "webhooks:write",
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResult"
                }
              }
            }
          },
          "default": {
            "description": "Scoped error; inspect error.code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "deliveryId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "deliveryId"
                ]
              }
            }
          }
        },
        "description": "Required scope: webhooks:write. Outbound delivery requires an operator-approved HTTPS origin; currently disabled. See /docs/webhooks.md."
      }
    },
    "/payments/{id}/wallet-approval": {
      "get": {
        "operationId": "getWalletApproval",
        "summary": "getWalletApproval",
        "description": "Required scope: payments:read. Read the latest approval, or null. Preparation must exist.",
        "x-required-scope": "payments:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved approval or matching replay; inspect status and expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletApprovalResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "requestWalletApproval",
        "summary": "requestWalletApproval",
        "description": "Required scope: payments:write. Create an intent-only challenge for the current preparation version. Expires no later than its deposit review. Identical creation retries return the saved record even after expiry. One non-revoked record per preparation; explicitly revoke it before replacing. No provider allocation or funding.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry. Protocol payments do not use wallet intent approvals and answer USE_TRANSACTION_SIGNATURE instead."
          }
        ],
        "responses": {
          "200": {
            "description": "Saved approval or matching replay; inspect status and expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletIntentApproval"
                }
              }
            }
          },
          "201": {
            "description": "Created approval challenge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletIntentApproval"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Version"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/wallet-approval/confirm": {
      "post": {
        "operationId": "confirmWalletApproval",
        "summary": "confirmWalletApproval",
        "description": "Required scope: payments:write. Verify the saved message signature, recheck current access/state/key restrictions and store confirmation readiness. Identical confirmed signatures replay safely; changed signatures cannot replace proof. Expired, revoked or changed pending approvals are rejected. No transaction signing, budget adjustment or execution.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved approval or matching replay; inspect status and expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletIntentApproval"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmWalletApproval"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/wallet-approval/revoke": {
      "post": {
        "operationId": "revokeWalletApproval",
        "summary": "revokeWalletApproval",
        "description": "Required scope: payments:write. Explicitly revoke a pending or approved intent. Repeating revocation returns the saved record. Original preparation budget holds remain.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved approval or matching replay; inspect status and expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletIntentApproval"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeWalletApproval"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction": {
      "get": {
        "operationId": "getTransaction",
        "summary": "getTransaction",
        "description": "Required scope: payments:read. Read saved NEAR transaction or protocol action and live release flag. Protocol responses also include action history. May return transaction:null.",
        "x-required-scope": "payments:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "prepareTransaction",
        "summary": "prepareTransaction",
        "description": "Required scope: payments:write. NEAR requires approvalId and current preparation version; protocols require version only and reject approvalId. Protocol approval/reset, transfer/burn and Stellar mint are separate actions. Complete required token approval and wait for verified confirmation (a finalized Stellar ledger or one successful canonical EVM block inclusion) before requesting the next action on the same payment with its current preparation version and a new idempotency key. Route refreshes transfer terms; approval does not reserve the initial quoted price. Review the new action expiry before signing. Current policy, fees, wallet state and signatures are checked. Full arrival timing is required only when owner policy requires it; cost priority may explicitly omit a deadline. UUID Idempotency-Key required for each new attempt. Stellar-source CCTP approves exactly the amount the burn debits (amount minus its sub-6-decimal remainder) and skips approval only when the live allowance covers the burn through its expiry; amounts below one 6-decimal unit return AMOUNT_TOO_SMALL. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "201": {
            "description": "New saved transaction.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrepareTransaction"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/signature": {
      "post": {
        "operationId": "saveTransactionSignature",
        "summary": "saveTransactionSignature",
        "description": "Required scope: payments:write. Gated exact signature verification with fresh state, signer authority, pricing and budget checks. Registers the predictable source hash for tracking. Does not submit. Same signatures replay safely; different bytes cannot replace the saved proof.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveTransactionSignature"
              }
            }
          }
        }
      }
    },
    "/payments/{id}/advance": {
      "post": {
        "operationId": "advanceComposedPayment",
        "summary": "Requote and prepare the next transfer after verified intermediate settlement",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "review": {
                    "$ref": "#/components/schemas/ComposedAdvanceReview"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved composed workflow; replay retains the same child attempt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComposedPayment"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Required scope: payments:write. Composed routes only. Requote the next leg and remaining preview after finalized intermediate settlement, enforce the final minimum and aggregate budget, then save one next-leg payment. Save a separate UUID Idempotency-Key for each advance and reuse it on retries. Does not submit. Optionally pass the reviewed /advance-preview review. Route rejects changed receipt, leg, amount, provider/path, policy, expiry or worse output/estimated fees with ADVANCE_REVIEW_CHANGED. Reuse the same review and idempotency key on retry. Fresh wallet authorization remains required. After a supported finalized intermediate refund, review is required. The new attempt stays on the same leg and links to its historical refunded payment. All attempts retain the original parent credit charge and principal reservation. At most three attempts per leg; first-leg refunds cannot restart the route."
      }
    },
    "/payments/{id}/reconcile": {
      "post": {
        "operationId": "reconcileRejectedNearPreparation",
        "summary": "Check a rejected NEAR preparation",
        "description": "Required scope: payments:write. Verify a captured, signed executable NEAR quote rejected because its guaranteed output was below the saved minimum. Reads provider status only. Requires no issued deposit instructions, registered source hash, wallet action or authorization. Composed children require parent-aware manual recovery. Does not allocate, broadcast, cancel, release reservations or automatically replace a payment. Maximum 6 checks per preparation per minute.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Saved preparation with recovery observation; inspect recovery.canRequote and message. Original state stays needs-review.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NearPaymentPreparation"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/review": {
      "post": {
        "operationId": "refreshApprovalReview",
        "summary": "Renew an eligible EVM transaction review without replacing its transaction",
        "description": "Required scope: payments:write. Protocol EVM approval/reset: authorizationId required; returns ProtocolTransaction with a fresh 15-minute review, preserving all bytes and nonce. NEAR EVM deposit: current preparation version required and saved authorizationId recommended when present; returns DepositReview with a new wallet intent challenge. Confirm that challenge before continuing with the same transaction. Up to five minutes bounded by original provider/refund deadlines. Rechecks signed quote/status, source activity/nonces, recipient, fees, fresh USD prices, policy and key restrictions. No new deposit or quote, no transaction replacement, and no broadcast. Identical idempotent retries replay the same review. Submitted/uncertain actions, signed protocol transfers/burns, protocol mints, other non-EVM NEAR sources and testnet actions are not eligible. Native NEAR-chain allocations can renew only before any transaction action or source hash exists. Route checks the same signed provider allocation and zero final and optimistic token-deposit balances, reruns readiness and policy checks, and issues fresh NEP-413 wallet intent approval. Existing NEAR transaction actions, signatures or submission attempts require reconciliation. Unsigned EVM protocol burn/transfer actions can also renew their review if no signature, hash, submission or browser-wallet handoff exists. The exact transaction bytes and nonce remain unchanged. Fresh simulation, balances, policy and aggregate composed costs must still pass. Signed protocol funding actions require reconciliation. Stellar approvals are not eligible; an expired Stellar CCTP approval uses renew-approval at /transaction/renew.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED for a protocol action review. A NEAR deposit review keeps its existing behaviour and answers it with 404 NOT_FOUND (Record not found.). Neither changes anything; persist a UUID and retry."
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ProtocolTransaction"
                    },
                    {
                      "$ref": "#/components/schemas/DepositReview"
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Fresh NEAR deposit review; new wallet consent required. No transaction submitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DepositReview"
                }
              }
            }
          },
          "default": {
            "description": "Error. Includes APPROVAL_REVIEW_UNAVAILABLE, APPROVAL_ALREADY_BROADCAST, APPROVAL_NONCE_CHANGED, APPROVAL_STATE_CHANGED, TRANSACTION_FEE_CHANGED, TRANSACTION_NOT_READY, VERSION_CONFLICT and IDEMPOTENCY_CONFLICT. Network and policy failures never broadcast or replace an action. NEAR errors include DEPOSIT_REVIEW_UNAVAILABLE, DEPOSIT_ALREADY_ACTIVE, DEPOSIT_NONCE_CHANGED, DEPOSIT_STATUS_STALE, DEPOSIT_REVIEW_INVALID, TRANSACTION_STATE_CHANGED and TRANSACTION_EXPIRED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "authorizationId"
                    ],
                    "properties": {
                      "authorizationId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "version"
                    ],
                    "properties": {
                      "version": {
                        "type": "integer",
                        "minimum": 1
                      },
                      "authorizationId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/payments/{id}/archive": {
      "post": {
        "operationId": "archiveDraft",
        "summary": "Archive an unused draft",
        "description": "Required scope: payments:write. Archives only an unprepared standalone draft using its current version. A preparation, composed parent or composed leg cannot be archived. Repeating an archive returns the saved record. Records and idempotency history are retained. An archived draft cannot be prepared; obtain a fresh quote.",
        "x-required-scope": "payments:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Version"
              }
            }
          }
        }
      }
    },
    "/providers/garden/credential": {
      "put": {
        "operationId": "saveGardenCredential",
        "summary": "saveGardenCredential",
        "description": "Required scope: providers:write. Saving selects the customer connection for new activity. Removing a saved customer credential disables customer mode; Route mode stays enabled. Existing preparations retain their recorded connection source.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialUpdateResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GardenCredentialUpdate"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removeGardenCredential",
        "summary": "removeGardenCredential",
        "description": "Required scope: providers:write. Saving selects the customer connection for new activity. Removing a saved customer credential disables customer mode; Route mode stays enabled. Existing preparations retain their recorded connection source. Removal is never blocked. When payments tracked with this key have funding in flight and no terminal outcome, the response carries warnings: [{code: UNSETTLED_PROVIDER_PAYMENTS, count, message}]. See /docs/providers/#removing-a-provider-key-with-payments-in-flight.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialUpdateResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Version"
              }
            }
          }
        }
      }
    },
    "/providers/swapkit/credential": {
      "put": {
        "operationId": "saveSwapKitCredential",
        "summary": "saveSwapKitCredential",
        "description": "Required scope: providers:write. Saving selects the customer connection for new activity. Removing a saved customer credential disables customer mode; Route mode stays enabled. Existing preparations retain their recorded connection source.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialUpdateResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SwapKitCredentialUpdate"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removeSwapKitCredential",
        "summary": "removeSwapKitCredential",
        "description": "Required scope: providers:write. Saving selects the customer connection for new activity. Removing a saved customer credential disables customer mode; Route mode stays enabled. Existing preparations retain their recorded connection source. Removal is never blocked. When payments tracked with this key have funding in flight and no terminal outcome, the response carries warnings: [{code: UNSETTLED_PROVIDER_PAYMENTS, count, message}]. See /docs/providers/#removing-a-provider-key-with-payments-in-flight.",
        "x-required-scope": "providers:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialUpdateResult"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Version"
              }
            }
          }
        }
      }
    },
    "/auto-route": {
      "post": {
        "operationId": "createAutoRoute",
        "summary": "Auto-route: compare paths for a payment intent",
        "description": "Required scope: quotes:write. Optional key route and USD restrictions apply before saving a new quote. Matching replays return the original evidence. Set autoRoute to compare direct and bounded two- and three-leg paths using TypeSafe intent classification. Auto-route consumes 4x standard credits (4 per eligible comparison, 40 per verified completed logical payment); unsuccessful comparisons remain free. See /docs/auto-route.md. Defaults to view=best with one recommendation summary. Use list for safely selectable alternatives, compact for all candidates and checks, or full for detailed evidence. Views preserve the saved quote and idempotency identity. Reads never create a payment, refresh providers, extend expiry or add a charge.",
        "x-required-scope": "quotes:write",
        "responses": {
          "200": {
            "description": "Success (or an idempotent replay)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteResponse"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient available credits for a new mainnet comparison. No provider quote is requested. Add credits in Billing, then retry the same input and Idempotency-Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Persist with the operation. Reuse for identical retries, including across key rotation. A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "best",
                "list",
                "compact",
                "full"
              ],
              "default": "best"
            },
            "description": "Defaults to view=best with one recommendation summary. Use list for safely selectable alternatives, compact for all candidates and checks, or full for detailed evidence. Views preserve the saved quote and idempotency identity. Reads never create a payment, refresh providers, extend expiry or add a charge. Invalid or repeated values return 400 INVALID_QUOTE_VIEW before requesting a quote or reserving quote credits."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/QuoteInput"
                  },
                  {
                    "type": "object",
                    "required": [
                      "autoRoute"
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/payments/{id}/next-action": {
      "get": {
        "operationId": "getPaymentNextAction",
        "summary": "Read the next payment action",
        "description": "Required scope: payments:read. Read a normalized projection of saved payment, preparation and transaction state. Does not sign, broadcast, refresh chain evidence or create a provider deposit. Separate app, wallet and operator steps; preserve identifiers and reread after each operation. Unknown future actions must pause automatic execution.",
        "x-required-scope": "payments:read",
        "responses": {
          "200": {
            "description": "Saved-state action snapshot. Not an authorization or a guarantee of fresh readiness.",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Save when reporting an integration problem."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentNextAction"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Route-Network",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "const": "mainnet"
            },
            "description": "Omit or use mainnet. Use the separate testnet contract and testnet key/header for testnet."
          }
        ]
      }
    },
    "/payments/{id}/recovery": {
      "get": {
        "operationId": "getPaymentRecovery",
        "summary": "Read saved payment recovery evidence",
        "description": "Required scope: payments:read. Read a sanitized saved-state recovery report for the accessible root or active payment, without provider or chain requests. Does not sign, broadcast, perform managed minting, allocate deposits, replace payments or release reservations. Mainnet includes bounded saved reservation reads; testnet reservation groups are unobserved. Existing POST /refresh is separate and may advance previously authorized managed destination delivery.",
        "x-required-scope": "payments:read",
        "responses": {
          "200": {
            "description": "Saved recovery report. generatedAt is report creation time, not a fresh chain observation. No recovery action is authorized.",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string"
                },
                "description": "Save when reporting an integration problem."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRecoveryReport"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Route-Network",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "const": "mainnet"
            },
            "description": "Omit or use mainnet. Use the separate testnet contract and testnet key/header for testnet."
          }
        ]
      }
    },
    "/payments/{id}/transaction/broadcast": {
      "post": {
        "operationId": "beginWalletBroadcast",
        "summary": "beginWalletBroadcast",
        "description": "Required scope: payments:write. Reserve exclusive wallet submission of the current unsigned EVM action after fresh readiness, policy and budget checks. Returns walletBroadcast with eth_sendTransaction params. No network send occurs. Preserve the same authorizationId. An existing handoff is replayed; do not automatically invoke the wallet twice. Route signature, execute and review calls are blocked for this action. Once unresolved review evidence is recorded for a burn, transfer or NEAR source transaction (a wallet-altered copy of the payment call, for example broadcast-recover state altered-payment or a close refused with observedState altered-payment, the same payment found at another nonce, or any other reported transaction the wallet signed, reason unclassified-sender-transaction), a new handoff returns 409 WALLET_TRANSACTION_REVIEW_REQUIRED with that WalletAlteredTransaction evidence in error.details, before any external read: nothing is reserved and no eth_sendTransaction params are returned, because the wallet would send the saved call too. An existing handoff is still replayed and nothing is sent, but with method null, empty params and a review notice. An altered spending approval moves no funds and does not block its handoff or remove its params; the same payment found at another nonce, or an unclassified sender transaction, blocks an approval's handoff too. While a recovery, cancellation or close check for the action is reading the network, it returns 409 WALLET_EVIDENCE_CHECK_IN_PROGRESS (details.retryable: true, details.retryAfterSeconds) before any network read; the check clears it when it records what it found, and it lapses after 2 minutes. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/broadcast-confirm": {
      "post": {
        "operationId": "confirmWalletBroadcast",
        "summary": "confirmWalletBroadcast",
        "description": "Required scope: payments:write. Report the hash returned by the wallet for a previously reserved handoff. Route independently reconstructs the signed legacy transaction and verifies all fields and the signer before recording submission. This endpoint never broadcasts. It remains available after review expiry or an execution pause; the current API key must still have payment access. Same hash replays safely. 409 WALLET_TRANSACTION_NOT_FOUND: retry the same hash after bounded backoff. 409 WALLET_TRANSACTION_REVIEW_REQUIRED: the wallet changed the nonce, fees or transaction type but kept the exact payment call (sender, contract, calldata, value and chain); error.details is WalletAlteredTransaction evidence. Route records it permanently and as the action's lastError, never attaches it, and keeps the saved nonce and every reservation. The payment requires review (paymentState REQUIRES_ATTENTION, next action review-required, payment.requires_attention webhook) For a burn or transfer, cancellation can no longer close it (an altered spending approval moves no funds and does not block closure). The evidence remains if the exact original is confirmed later. Do not send replacement funds. Other mismatches (WALLET_TRANSACTION_MISMATCH) and conflicts (WALLET_TRANSACTION_CONFLICT) require reconciliation. Submission is not verified destination delivery. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen. Without a handoff to confirm, a hash on record for review for the action (recorded by this report) returns 409 WALLET_TRANSACTION_REVIEW_REQUIRED with that evidence in error.details instead of 404 WALLET_BROADCAST_NOT_FOUND.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved attempt or identical replay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentTransaction"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId",
                  "transactionHash"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionHash": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{64}$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/broadcast-recover": {
      "post": {
        "operationId": "recoverWalletBroadcast",
        "summary": "Recover wallet submission",
        "description": "Inspect the exact saved EVM source nonce without submitting funds. Supports browser-wallet handoffs and signed intermediate source actions in composed payments. Finalized cancellation evidence is required before explicit closure; missing receipts and review expiry are insufficient. Also supports standalone saved EVM source signatures (closure on Ethereum, Base and Arbitrum; a reported hash is inspected and recorded on every EVM network the action allows). A signature hash alone does not prove source funding. This read of network evidence does not close the payment or release holds. State altered-payment: the observed transaction is the exact payment call with a changed nonce, fee or transaction type. Route records it as review evidence (WalletAlteredTransaction), never attaches it, keeps all reservations and reports canClose: false for this action. A transaction the wallet signed that is the same payment without being the saved call (re-quoted, another value or envelope type, an unreadable call to the payment contract, or any call to its provider contracts), sent or still queued at any nonce, returns state equivalent-execution and is recorded the same way; for a NEAR source transaction that rule reads the 1Click deposit address from the preparation. Any other transaction the wallet signed that is not the recognized self-cancellation of the saved nonce (an unrelated transfer, the saved call batched through the wallet's delegated execution, another bridge), at any nonce and in any envelope, returns state unclassified-sender-transaction and is recorded the same way (fail-closed). A transaction the sender did not verifiably sign (another key, a relayer, an L2 system or deposit type) returns state unclassified-transaction and is recorded the same way. An observation is recorded even if the check outlives its 2-minute in-progress window while a submission or handoff starts. An observation is recorded even if the caller loses access during the check. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen. An action without a handoff, or a handoff whose transaction is already registered, can report another hash here too: it is inspected and recorded, and nothing closes.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verified recovery observation or idempotent closed result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletBroadcastRecovery"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionHash": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{64}$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/broadcast-cancel": {
      "post": {
        "operationId": "cancelWalletBroadcast",
        "summary": "Close a verified cancelled wallet submission",
        "description": "Verifies a finalized zero-value EVM self-transfer at the saved source nonce. Closes an eligible unfunded standalone browser-wallet payment, or the active EVM source attempt of a composed payment (Ethereum, Base, Arbitrum; signed or browser-submitted). First-leg closure cancels the unfunded parent and releases unused payment credit and API-limit holds exactly once. Intermediate closure retains the funded parent and its reservations. It does not submit a cancellation or automatically fund a replacement. See /docs/composed-payments/#close-a-cancelled-first-transfer. Standalone saved source signatures on Ethereum, Base and Arbitrum also support closure after verified finalized cancellation, including uncertain submissions. Original signatures and nonce history stay immutable. Returns SOURCE_CANCELLATION_REVIEW_REQUIRED when the standalone signed source cannot be closed. See /docs/recovery/#close-a-cancelled-signed-source-transfer. A cancellation consumes only the saved nonce: for a mainnet protocol payment Route also searches the wallet's provider events for the same payment sent at another nonce and stores that search with the cancellation. A match returns EVM_CLOSURE_REVIEW_REQUIRED and is saved on the action as lastError for review; an incomplete search returns it with observedState equivalent-scan-incomplete. Recorded evidence that the wallet sent the payment itself (lastError code WALLET_TRANSACTION_REVIEW_REQUIRED), or a provider whose sends cannot be searched by sender, returns canClose false on recovery and WALLET_CANCELLATION_REVIEW_REQUIRED, SOURCE_CANCELLATION_REVIEW_REQUIRED or COMPOSED_CANCELLATION_REVIEW_REQUIRED here. Reservations are kept in every refusal. A recorded wallet-altered burn or transfer (recovery state altered-payment, or 409 WALLET_TRANSACTION_REVIEW_REQUIRED from confirmation) blocks closure of that action: canClose is false, and closing returns 409 WALLET_CANCELLATION_REVIEW_REQUIRED (SOURCE_CANCELLATION_REVIEW_REQUIRED or COMPOSED_CANCELLATION_REVIEW_REQUIRED for saved-signature and composed sources). An altered spending approval moves no funds and does not block closure. Report every wallet transaction hash before closing. A same-payment copy reported with transactionHash (state equivalent-execution), or any other transaction the wallet signed (state unclassified-sender-transaction), is recorded and refuses the close, for NEAR source transactions too. A cancellation whose check outlived its 2-minute in-progress window returns 409 WALLET_EVIDENCE_CHECK_EXPIRED (details.retryable true) and closes nothing. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verified recovery observation or idempotent closed result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletBroadcastRecovery"
                }
              }
            }
          },
          "default": {
            "description": "Error. 409 EXECUTION_UNAVAILABLE while the release gate is closed. Other readiness, expiry, revocation and state checks remain enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId",
                  "transactionHash"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionHash": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{64}$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/quote-review": {
      "get": {
        "operationId": "getQuoteReview",
        "x-required-scope": "payments:read",
        "summary": "Review saved provider terms before funding",
        "description": "Requires payments:read. Supports a saved SwapKit build or an unfunded EVM- or Aptos-source NEAR allocation rejected for its minimum output. Standalone NEAR payments may explicitly accept revised receipt terms; later composed legs must retain the original final minimum. Rechecks wallets, fees, policy and remaining legs without allocating another deposit.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Captured quote terms or the recorded acceptance. No funds are sent.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentQuoteReview"
                    },
                    {
                      "$ref": "#/components/schemas/NearCapturedQuoteReview"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "No safe review is available; nothing changed. Includes PREPARATION_REQUIRED, SWAPKIT_BUILD_IDENTITY_REQUIRED, REVIEW_UNAVAILABLE, REVIEW_EXPIRED, SWAPKIT_CHANNEL_EXPIRED, SETTINGS_CHANGED and TRANSACTION_NOT_READY.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id. An unknown payment, or a payment whose adapter has no quote review (protocol adapters other than SwapKit), returns 404 NOT_FOUND. 429 TRY_LATER: wait before checking again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "acceptQuoteReview",
        "x-required-scope": "payments:write",
        "summary": "Accept the exact captured provider terms",
        "description": "Requires payments:write and explicit acceptance. SwapKit preserves its channel; a reserved preparation without deposit instructions adopts only the accepted minimum and provider quote. Retry prepare afterward. NEAR requires maxEstimatedTotalFeeUsd and becomes prepared with the same captured allocation, accepted minimum and cost ceiling. Original intent history remains unchanged. Standalone payment credits are re-reserved if previously released. Obtain separate wallet consent and signatures afterward. This endpoint does not send funds.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED for a SwapKit quote-review acceptance. A NEAR captured quote-review acceptance keeps its existing behaviour and answers it with 404 NOT_FOUND (Record not found.). Neither changes anything; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "description": "The body depends on the payment's adapter: SwapKit accepts only reviewHash and minimumReceived; NEAR also requires maxEstimatedTotalFeeUsd, for standalone payments and composed legs alike.",
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/SwapKitQuoteReviewAcceptance"
                  },
                  {
                    "$ref": "#/components/schemas/NearCapturedQuoteReviewAcceptance"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "SwapKit terms accepted for the same deposit channel; retry prepare afterward. No funds are sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentQuoteReview"
                }
              }
            }
          },
          "200": {
            "description": "NEAR acceptance, or the recorded acceptance of the same terms (SwapKit or NEAR). NEAR identifies a replay by its accepted terms, not by the Idempotency-Key. No funds are sent.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentQuoteReview"
                    },
                    {
                      "$ref": "#/components/schemas/NearCapturedQuoteReview"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nothing changed. INVALID_INPUT: a field outside the payment adapter's body; SwapKit rejects maxEstimatedTotalFeeUsd. INVALID_REVIEW: a missing or malformed reviewHash, or for NEAR a missing or non-string minimumReceived or a missing or malformed maxEstimatedTotalFeeUsd. IDEMPOTENCY_REQUIRED (SwapKit): the Idempotency-Key header is missing or is not a UUID; retry with a persisted UUID key. A NEAR acceptance answers a missing or non-UUID key with 404 NOT_FOUND instead (see default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "NEAR standalone payment: INSUFFICIENT_CREDITS. The payment's released credit reservation could not be restored, so nothing was accepted. Add credits, then retry the same acceptance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Nothing was accepted: the review changed, expired, already has a preparation or different accepted terms, or fails current checks. Includes REVIEW_CHANGED, REVIEW_CONFLICT, REVIEW_EXPIRED, REVIEW_UNAVAILABLE, EXECUTION_UNAVAILABLE, COMPOSED_FEE_LIMIT (NEAR: the fresh total exceeds maxEstimatedTotalFeeUsd or owner policy), TRANSACTION_NOT_READY, SWAPKIT_CHANNEL_EXPIRED and IDEMPOTENCY_CONFLICT (SwapKit: the key belongs to a different review).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id. For NEAR, a missing or non-UUID Idempotency-Key returns 404 NOT_FOUND (Record not found.); nothing changed, so retry with a persisted UUID key. An unknown payment, or a payment whose adapter has no quote review (protocol adapters other than SwapKit), also returns 404 NOT_FOUND. 429 TRY_LATER: wait before retrying the same acceptance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/renew": {
      "post": {
        "operationId": "renewStellarMint",
        "summary": "Renew an eligible expired Stellar mint, Stellar protocol action or NEAR source transaction",
        "description": "Required scope: payments:write. Follow next-action. renew-mint checks an unsubmitted customer CCTP Stellar destination mint. renew-source checks a signed or uncertain NEAR source on Stellar, Solana or Fogo. renew-approval checks the current expired Stellar CCTP approval (or legacy approval-reset) whose receipt was never included, whether unsigned, signed or submitted. For a protocol payment from Stellar (Circle CCTP, LayerZero or Axelar), renew-source checks the current expired burn or transfer that was never signed. Stellar requires finite ledger expiry and an unused sequence. For these Stellar protocol renewals, the saved envelope must match its signed maxTime, the network must report no receipt for its hash, and the account sequence must still be just below its nonce. Route then builds a fresh action at the same wallet sequence with the ordinary transaction checks, including a fresh quote and owner policy: for CCTP one exact approval, or the burn when a live allowance already covers it through the burn expiry; for LayerZero or Axelar the transfer. The expired action, any signature, and credit and key holds are retained; the replacement needs a fresh wallet signature and moves no funds itself. A signed Stellar burn or transfer cannot be renewed; see POST /payments/{id}/transaction/close. A never-signed Stellar action may still have been broadcast by the wallet itself (the Stellar hash excludes signatures, so the saved hash finds it): when the network returns exactly the saved envelope with the sender's one signature, renewal is refused and Route adopts it as the submitted action and tracks it; when the saved transaction's sequence is used, whether or not the network returns a receipt Route can verify (a fee-bump wrapper, other signatures or a mismatched envelope are never adopted), renewal is refused, the observation is recorded (sequence-consumed) and the preparation moves to needs-review for good (paymentState REQUIRES_ATTENTION; payment.requires_attention is emitted once). next-action then returns track or review-required instead of renewal. Solana/Fogo requires an invalid blockhash, finalized height past its last-valid height, no receipt, and contiguous finalized signature history back to the original blockhash (at most 512 blocks within 2,048 slots); incomplete or older history is rejected. The original provider allocation must remain unfunded and within its deadlines. The payment, asset, amount and recipient stay unchanged; all original signatures are retained. Fresh fees, wallet readiness, policy and key limits must pass. NEAR returns SourceRenewalResult requiring fresh intent consent and a new transaction signature. Persist a UUID Idempotency-Key. Read next-action after replay. Renewal sends no funds.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED, except for a NEAR renew-source, which keeps its existing behaviour and answers it with 404 NOT_FOUND (see responses). Neither changes anything; persist a UUID and retry."
          }
        ],
        "responses": {
          "200": {
            "description": "Identical renewal replay; the original replacement is returned without sending.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentTransaction"
                    },
                    {
                      "$ref": "#/components/schemas/SourceRenewalResult"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_REQUIRED for renew-mint, renew-approval and a Stellar-source protocol renew-source (Circle CCTP, LayerZero or Axelar): the Idempotency-Key header is missing or is not a UUID. Nothing was checked or changed; retry with a persisted UUID key. A NEAR renew-source keeps its existing behaviour and answers a missing or non-UUID key with 404 NOT_FOUND instead (see default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Authentication, scope, policy or proof failure. SOURCE_RECONCILIATION_REQUIRED, MINT_RECONCILIATION_REQUIRED or APPROVAL_RECONCILIATION_REQUIRED retains existing actions and holds; do not send replacement funds or replace a Stellar action outside Route. For a NEAR renew-source, a missing or non-UUID Idempotency-Key returns 404 NOT_FOUND (Record not found.); nothing was checked or changed, so retry with a persisted UUID key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Unsigned replacement prepared; fresh wallet signatures required.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentTransaction"
                    },
                    {
                      "$ref": "#/components/schemas/SourceRenewalResult"
                    }
                  ]
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/transaction/close": {
      "post": {
        "operationId": "closeExpiredStellarPayment",
        "summary": "Close an unfunded payment whose current Stellar or EVM action can never execute",
        "description": "Explicitly closes an unfunded standalone protocol payment whose current action provably can never execute, and atomically releases only its wallet sequence or nonce reservation and unused credit/API-limit holds, preserving the original action, any signature and hash, and the closure proof. No funds are submitted. Not available for composed payments or included/funded actions. Requires payments:write and a UUID Idempotency-Key; replays return the same closed preparation. Stellar: for an approval, burn or transfer past its signed expiry (including signed or uncertain actions), send authorizationId only. Route verifies the saved envelope, absent receipt, a fresh closed ledger past its signed expiry and an unused wallet sequence. CLOSE_UNAVAILABLE leaves the payment and reservations unchanged, and is also returned for other non-EVM payments. EVM: only for an approval, approval reset, burn or transfer that has no saved signature, submission or external-wallet handoff, after its review expires (closeEnabled with closureRequirement 'finalized-nonce-cancellation'). Supply authorizationId and cancellationHash: the hash of a canonically finalized transaction from the same sender at the exact saved nonce, either a zero-value self-transfer or any other transaction (successful or reverted) that neither repeats this payment call with changed fees nor calls, is logged by or pays the payment's provider contracts or deposit address. Missing records or an expired review alone cannot prove that EVM bytes are unusable. Because a consumed nonce kills only the payload signed at that nonce, Route also searches the sender's provider events since the payment was first revealed (the preparation, a SwapKit build attempt or the action, whichever is earliest; Circle DepositForBurn, LayerZero OFTSent, Axelar ITS InterchainTransfer, the source-token Transfer to the Allbridge bridge with its bridge() calldata, or the token Transfer to a SwapKit deposit address) for the same token, amount, destination and recipient at any other nonce; approvals need no search. EVM_CLOSURE_UNAVAILABLE means the action does not qualify (details.expiresAt when its review has not expired); EVM_CANCELLATION_REQUIRED means no qualifying finalized transaction was established, with details naming the network, sender, nonce and observedState. EVM_CLOSURE_REVIEW_REQUIRED means the payment stays in review: details.observedState is 'equivalent-execution' (the same payment was found; details.evidence is recorded in Route's append-only evidence journal and saved as the action's lastError with code WALLET_TRANSACTION_REVIEW_REQUIRED, closure is withdrawn, and Route never submits the saved call or hands it to the wallet afterwards, as for 'altered-payment': the hash repeats the payment call with changed fees), 'review-recorded' (such evidence is already saved), 'equivalent-scan-unsupported' (the payment cannot be searched by sender: SwapKit native deposits or an undecodable payment call, which are never offered automatic closure) or 'equivalent-scan-incomplete' (pending wallet transactions, RPC or provider limits, or too many blocks; nothing is recorded, retry later; details.retryable is true when a retry may complete it: once the wallet is idle, or because this attempt saved search progress and the next continues from it). Recorded equivalent-execution or unclassified-sender-transaction evidence that Route has since attributed to another of its payments (its saved hash from the same wallet, or a Stellar hook naming it) is resolved before the search runs again: the database checks that attribution itself and records it with the evidence (audited). Wallet-altered copies of the saved call are never resolved. None of these errors releases reservations. Where Route cannot search or finish, manualCloseEnabled lets a signed-in workspace member close the payment after a manual check in the dashboard; that operation is not available to API keys. Signed or handed-off actions use the wallet-broadcast recovery endpoints. A hash that is the same payment signed at another nonce, sent or still queued, returns EVM_CLOSURE_REVIEW_REQUIRED with details.observedState equivalent-execution and is recorded as review evidence, even if the caller loses access during the check. Any other transaction the wallet signed that is not a nonce proof (at another nonce, or calling, logged by or paying the payment's provider contracts or deposit address) returns details.observedState unclassified-sender-transaction and is recorded the same way, for approvals too (fail-closed); so does one the sender did not verifiably sign (observedState unclassified-transaction). A close whose check outlived its 2-minute in-progress window returns 409 WALLET_EVIDENCE_CHECK_EXPIRED (details.retryable true) and closes nothing; retry it. An altered spending approval moves no funds and can still close with a finalized nonce proof. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "responses": {
          "200": {
            "description": "Closed preparation with preserved action and closure evidence",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtocolPreparation"
                }
              }
            }
          },
          "default": {
            "description": "Authentication, scope or proof failure. CLOSE_UNAVAILABLE, EVM_CLOSURE_UNAVAILABLE, EVM_CANCELLATION_REQUIRED and EVM_CLOSURE_REVIEW_REQUIRED preserve the saved payment and reservations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "cancellationHash": {
                    "type": "string",
                    "pattern": "^0x[a-fA-F0-9]{64}$",
                    "description": "Required for an expired, unsigned, unhanded-off standalone EVM protocol action. Hash of a canonically finalized transaction from the same wallet at the saved nonce: a zero-value, empty-data self-transfer, or any other transaction that neither sends this payment nor calls, is logged by or pays its provider contracts or deposit address. Route never creates or sends this transaction for you."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}/advance-preview": {
      "post": {
        "operationId": "previewComposedAdvance",
        "summary": "Preview continuation from a verified intermediate receipt",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Indicative continuation for explicit review",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComposedAdvancePreview"
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Required scope: payments:write. POST {} after finalized intermediate delivery before allocating the next child, or after a supported finalized intermediate refund. Refund continuation is limited to NEAR and SwapKit on Ethereum, Base or Arbitrum, with at most three attempts per leg. Requotes the same provider/path for the verified received or refunded amount, checks owner/key restrictions, the original final minimum, and combined costs including refunded attempts. Allocates no child, provider deposit, wallet action or credit reservation. Signed or ambiguous attempts cannot be replaced. Limited with composed preparation to 12 requests per minute per payment."
      }
    },
    "/payments/{id}/refresh-route": {
      "post": {
        "operationId": "refreshComposedRoute",
        "summary": "Refresh remaining estimates for an unfunded composed transfer",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved remaining-route review. Does not create or submit a transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "const": "composed_route_review"
                    },
                    "paymentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "activePaymentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "remainingCostUsd": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error. See error.code and X-Request-Id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Required scope: payments:write. POST {} with a saved UUID Idempotency-Key. Mainnet composed routes only. Refreshes current and remaining path estimates under the original provider order, final minimum and owner/key limits. Requires the active preparation with no source signature, hash, submission or wallet handoff. Appends a review without replacing the child, transaction bytes, provider allocation or signature requirements. Then read the active child and use /transaction/review if its action review expired. SOURCE_RECONCILIATION_REQUIRED means keep tracking the saved transaction."
      }
    },
    "/payments/{id}/transaction/bitcoin-recover": {
      "post": {
        "operationId": "recoverBitcoinSource",
        "summary": "Verify canonical Bitcoin replacement funding or cancellation",
        "description": "Required scope: payments:write. Mainnet NEAR and SwapKit source actions only. Supply the existing authorization, the wallet replacement hash and explicit expected outcome. Requires at least six canonical confirmations, exactly the original ordered input set with verified signatures and previous outputs, and either the exact provider deposit plus wallet change or only wallet outputs. Route does not construct or broadcast replacements. Funding is adopted for normal delivery tracking and does not release holds. Cancellation closes an unfunded standalone payment or first leg and releases unused holds once; later-leg cancellation retains the funded parent for reviewed continuation. Original signatures and spent-input records remain immutable. Extra inputs, other recipients, partial amounts, incomplete evidence and already-verified funding require reconciliation. Repeat the same UUID Idempotency-Key and request body after an uncertain response.",
        "x-required-scope": "payments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "A missing or non-UUID value returns 400 IDEMPOTENCY_REQUIRED and changes nothing; persist a UUID and retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "authorizationId",
                  "transactionHash",
                  "outcome"
                ],
                "properties": {
                  "authorizationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionHash": {
                    "type": "string",
                    "pattern": "^[a-f0-9]{64}$"
                  },
                  "outcome": {
                    "enum": [
                      "funding",
                      "cancellation"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verified outcome saved; read next-action before continuing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BitcoinSourceRecovery"
                }
              }
            }
          },
          "201": {
            "description": "Verified outcome saved; read next-action before continuing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BitcoinSourceRecovery"
                }
              }
            }
          },
          "default": {
            "description": "Authentication, scope, policy or proof failure. SOURCE_RECONCILIATION_REQUIRED or MINT_RECONCILIATION_REQUIRED retains existing actions and holds; do not send replacement funds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "routeKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rt_live_<secret>",
        "description": "Use a key for the selected Route-Network. Mismatches return 403 KEY_NETWORK_MISMATCH. Legacy rt_sandbox_ keys retain their original access and restrictions."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "description": "Optional safe recovery fields. Branch on error.code; fields vary by error. NEAR TRANSACTION_NOT_READY and TRANSACTION_PRICE_EXPIRED include checkedAt, action and blockers. TRANSACTION_EXPIRED may include action: refresh-deposit-review. QUOTE_TERMS_CHANGED supplies quotedSlippageBps, requestedSlippageBps and action: requote. WALLET_TRANSACTION_REVIEW_REQUIRED supplies WalletAlteredTransaction evidence.",
                "properties": {
                  "action": {
                    "type": "string"
                  },
                  "checkedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "blockers": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PaymentCheck"
                    }
                  }
                }
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "QuoteInput": {
        "type": "object",
        "properties": {
          "sourceAssetId": {
            "type": "string",
            "description": "Exact catalog ID. Catalog assets are selectable in either role; availability is independently checked in the requested direction."
          },
          "destinationAssetId": {
            "type": "string",
            "description": "Exact catalog ID. Catalog assets are selectable in either role; availability is independently checked in the requested direction."
          },
          "amount": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Positive decimal string in source asset units within the source catalog precision; not a USD value or integer base-unit quantity."
          },
          "slippageBps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 10,
            "description": "NEAR quote tolerance in basis points, including NEAR legs in composed routes. Other adapters retain their protocol-specific minimum rules. Saved with the quote; preparation must use the same value. Omit it for the default of 10. A value that is not an integer from 0 to 1,000, including null, returns 400 INVALID_SLIPPAGE."
          },
          "autoRoute": {
            "$ref": "#/components/schemas/AutoRouteOptions"
          }
        },
        "required": [
          "sourceAssetId",
          "destinationAssetId",
          "amount"
        ],
        "additionalProperties": false
      },
      "PreparePayment": {
        "type": "object",
        "properties": {
          "mode": {
            "const": "prepare"
          },
          "quoteId": {
            "type": "string",
            "format": "uuid"
          },
          "candidateId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "Optional mainnet alternative from view=list or a candidate id in compact/full. Omit to accept the recommendation bound to the saved quote. Null and empty strings are invalid. Testnet still requires an explicit candidateId."
          }
        },
        "required": [
          "mode",
          "quoteId"
        ],
        "additionalProperties": false,
        "description": "Create a draft only. Omitted candidateId accepts the saved recommendation after expiry, policy, provider and key checks; Route refuses an unusable choice without switching routes. Persist the UUID Idempotency-Key and identical request body. Replays return the original payment, even after quote expiry. Preparation, wallet authorization and signing remain separate."
      },
      "Version": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "version"
        ],
        "additionalProperties": false
      },
      "ProviderUpdate": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "enabled": {
            "type": "boolean"
          },
          "credentialSource": {
            "type": "string",
            "enum": [
              "customer",
              "route"
            ],
            "description": "NEAR, Garden or SwapKit only: explicitly use the project credential (customer) or Route-managed connection (route). No automatic fallback."
          }
        },
        "required": [
          "version",
          "enabled"
        ],
        "additionalProperties": false
      },
      "CredentialUpdate": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "credential": {
            "type": "string",
            "writeOnly": true
          }
        },
        "required": [
          "version",
          "credential"
        ],
        "additionalProperties": false
      },
      "PolicyInput": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "valueCurrency": {
            "const": "USD"
          },
          "priority": {
            "enum": [
              "cost",
              "speed"
            ]
          },
          "maxFee": {
            "type": "string"
          },
          "maxSeconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 86400,
            "description": "Owner-selected arrival limit. Explicit null removes the deadline; speed ranking still requires comparable end-to-end timing."
          },
          "minAmount": {
            "type": "string"
          },
          "maxAmount": {
            "type": "string"
          },
          "providers": {
            "type": "array",
            "items": {
              "enum": [
                "allbridge",
                "circle",
                "near",
                "layerzero",
                "axelar",
                "garden",
                "swapkit",
                "rift"
              ]
            }
          },
          "providerRules": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/ProviderRule"
            },
            "description": "Mandatory mainnet asset-specific provider rules. All matching rules apply to the payment and each composed leg. Omit on update to retain existing rules; send [] to remove them. No provider or CCTP-mode fallback."
          }
        },
        "required": [
          "version",
          "valueCurrency",
          "priority",
          "maxFee",
          "maxSeconds",
          "minAmount",
          "maxAmount",
          "providers"
        ],
        "additionalProperties": false
      },
      "Candidate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "adapter": {
            "enum": [
              "allbridge",
              "circle",
              "near",
              "layerzero",
              "axelar",
              "garden",
              "swapkit",
              "rift"
            ]
          },
          "route": {
            "type": "string"
          },
          "status": {
            "enum": [
              "quoted",
              "unsupported",
              "unavailable"
            ]
          },
          "fees": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "amount": {
                  "type": "string"
                },
                "currency": {
                  "type": "string"
                },
                "treatment": {
                  "enum": [
                    "deducted",
                    "additional",
                    "included"
                  ]
                },
                "usd": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "network": {
                  "type": "string",
                  "description": "Network where this composed-leg fee applies."
                },
                "leg": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2
                },
                "assetSide": {
                  "enum": [
                    "source",
                    "destination",
                    "source-native",
                    "destination-native",
                    "intermediate-native",
                    "intermediate"
                  ]
                },
                "assetId": {
                  "type": "string",
                  "description": "Exact intermediate catalog asset ID for fee valuation."
                }
              },
              "required": [
                "label",
                "amount",
                "currency",
                "treatment",
                "usd"
              ]
            }
          },
          "received": {
            "type": [
              "string",
              "null"
            ]
          },
          "minimumReceived": {
            "type": [
              "string",
              "null"
            ],
            "description": "For composed routes, an indicative output from the first leg minimum; not an end-to-end guarantee. Rift returns null because its documented quote API supplies an estimate without a guaranteed minimum output."
          },
          "eta": {
            "$ref": "#/components/schemas/QuoteEta"
          },
          "capacity": {
            "type": "object",
            "properties": {
              "status": {
                "enum": [
                  "observed",
                  "unknown",
                  "blocked"
                ]
              },
              "scope": {
                "type": "string"
              }
            },
            "required": [
              "status",
              "scope"
            ]
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "status": {
                  "enum": [
                    "pass",
                    "fail",
                    "unknown"
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "status",
                "message"
              ]
            }
          },
          "decision": {
            "enum": [
              "eligible",
              "excluded",
              "needs-data"
            ]
          },
          "estimatedCostUsd": {
            "type": [
              "string",
              "null"
            ]
          },
          "costComplete": {
            "type": "boolean"
          },
          "unknowns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "executionEnabled": {
            "type": "boolean",
            "description": "True only for a released execution path; not payment authorization."
          },
          "composition": {
            "$ref": "#/components/schemas/QuoteComposition"
          },
          "gas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GasObservation"
            },
            "description": "Optional diagnostic evidence returned with view=full."
          },
          "totalFeeComplete": {
            "type": "boolean",
            "description": "All expected network charges have a disclosed comparison estimate; not execution simulation or a guarantee."
          },
          "execution": {
            "$ref": "#/components/schemas/ExecutionCapability"
          },
          "input": {
            "$ref": "#/components/schemas/ResolvedQuoteInput",
            "description": "Optional diagnostic evidence returned with view=full."
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "This candidate’s own expiry. It can be earlier than the quote’s expiresAt when the candidate is neither eligible nor preparable; an expired candidate cannot become a payment."
          },
          "limits": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Compact responses retain minimumAmount and maximumAmount when available. Additional provider limit evidence is returned with view=full."
          },
          "details": {
            "$ref": "#/components/schemas/QuoteDetails"
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional diagnostic evidence returned with view=full."
          },
          "preparation": {
            "$ref": "#/components/schemas/QuotePreparation"
          },
          "unresolvedFeeKinds": {
            "type": "array",
            "items": {
              "enum": [
                "source-gas",
                "destination-gas",
                "provider-fee"
              ]
            },
            "description": "Explicit fee-collector classification. Omitted when the observation has no classified fee gap."
          },
          "nextChecks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "stage": {
                  "enum": [
                    "quote",
                    "preparation",
                    "execution"
                  ]
                },
                "action": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "stage",
                "action"
              ]
            }
          },
          "providerRule": {
            "type": "object",
            "description": "Optional diagnostic evidence returned with view=full. Present when this policy has provider rules. Structured explanation for the provider-rule check.",
            "required": [
              "allowed",
              "applied",
              "message"
            ],
            "properties": {
              "allowed": {
                "type": "boolean"
              },
              "message": {
                "type": "string"
              },
              "applied": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "name",
                    "provider",
                    "mode",
                    "scope",
                    "matched"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "provider": {
                      "type": "string"
                    },
                    "mode": {
                      "enum": [
                        "any",
                        "fast",
                        "standard"
                      ]
                    },
                    "scope": {
                      "type": "string",
                      "description": "payment or leg-N"
                    },
                    "matched": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "reliabilityWarnings": {
            "type": "array",
            "description": "Informational exact-path delivery warnings. A cost-first policy without a deadline may still select this route.",
            "items": {
              "type": "object",
              "required": [
                "code",
                "message"
              ],
              "properties": {
                "code": {
                  "const": "RECENT_DELIVERY_FAILURES"
                },
                "message": {
                  "type": "string"
                },
                "failedCount": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 0
                },
                "pendingCount": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 0
                },
                "source": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "leg": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 1,
                  "maximum": 3
                },
                "adapter": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "id",
          "adapter",
          "route",
          "status",
          "fees",
          "received",
          "minimumReceived",
          "eta",
          "capacity",
          "checks",
          "decision",
          "estimatedCostUsd",
          "costComplete",
          "unknowns",
          "executionEnabled"
        ],
        "description": "Normalized candidate in both response views. Compact responses retain all checks, fee amounts/currencies/treatments, scoped ETA, output amounts, expiry and execution/preparation status. Optional detailed provider, gas and pricing evidence is available with view=full."
      },
      "Quote": {
        "type": "object",
        "properties": {
          "object": {
            "const": "quote"
          },
          "apiVersion": {
            "const": "v1"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "schemaVersion": {
            "const": 2
          },
          "input": {
            "type": "object",
            "description": "Exact requested catalog IDs, decimal quantity in source asset units, networks and optional slippage. Mainnet compact responses omit the repeated resolved sourceAsset and destinationAsset objects; obtain their identities from GET /assets or view=full. Testnet retains its required resolved asset fields."
          },
          "policyVersion": {
            "type": "integer",
            "minimum": 0
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "Covers the USD prices and every candidate that is eligible or can be prepared. Other candidates can expire earlier at their own expiresAt."
          },
          "expired": {
            "type": "boolean"
          },
          "candidates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Candidate"
            }
          },
          "decision": {
            "type": "object",
            "description": "Strict quote recommendations retain eligibleOrder. preparationOrder also includes source-gas-only candidates; the live preparationSelection filters this order by execution support and expiry."
          },
          "selected": {
            "type": [
              "string",
              "null"
            ],
            "description": "Best policy-eligible quote across compared adapters, or null. It may name a quote-only route. For a mainnet payment, prefer executionSelection.candidateId, then the explicit preparationSelection.candidateId fallback when its candidate preparation.enabled is true."
          },
          "executionEnabled": {
            "type": "boolean",
            "description": "True when at least one candidate has released transaction support, even if that candidate has unresolved or failed quote checks. Not payment authorization."
          },
          "valuation": {
            "$ref": "#/components/schemas/UsdValuation",
            "description": "Optional USD pricing evidence returned with view=full. Compact responses retain evaluated candidate costs and policy-check results."
          },
          "keyRestrictions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KeyRestriction"
            },
            "description": "Original key restrictions retained in the saved operation and returned with view=full. Historical records may omit this field."
          },
          "executionSelection": {
            "type": "object",
            "properties": {
              "candidateId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "eligibleOrder": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "requires": {
                "type": "string",
                "description": "Optional explanatory text in view=full. Wallet preparation and authorization remain mandatory in both views."
              }
            },
            "description": "Best unexpired eligible candidate with released execution support, or null. Prefer candidateId when creating a mainnet payment; if null, the explicit preparationSelection fallback may allow wallet preparation. A selection still requires fresh wallet checks and authorization."
          },
          "policyId": {
            "type": "string",
            "format": "uuid"
          },
          "policyName": {
            "type": "string",
            "description": "Optional diagnostic metadata returned with view=full."
          },
          "autoRoute": {
            "$ref": "#/components/schemas/AutoRouteEvaluation"
          },
          "preparationSelection": {
            "type": "object",
            "description": "Best unexpired preparation choice with released, enabled execution support. Source gas may await wallet preparation; partial costs do not establish a lowest-total-cost winner. This does not authorize spending.",
            "properties": {
              "candidateId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "order": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "provisional": {
                "type": "boolean",
                "description": "The selected candidate has incomplete costs and needs source gas confirmation."
              },
              "rankingComplete": {
                "type": "boolean",
                "description": "At least one preparation candidate is available and all available choices have complete estimated costs."
              },
              "nextAction": {
                "enum": [
                  "create-payment-and-prepare",
                  null
                ]
              },
              "requires": {
                "type": "string"
              }
            },
            "required": [
              "candidateId",
              "order",
              "provisional",
              "rankingComplete",
              "nextAction",
              "requires"
            ]
          }
        },
        "required": [
          "object",
          "apiVersion",
          "id",
          "projectId",
          "schemaVersion",
          "input",
          "policyVersion",
          "observedAt",
          "expiresAt",
          "expired",
          "candidates",
          "decision",
          "selected",
          "executionEnabled"
        ],
        "description": "Previous quote representation returned by view=compact or view=full. Compact retains every candidate and policy/preparation checks; full adds diagnostic evidence. The mainnet default is now view=best. Neither view authorizes spending; expiry and fresh wallet checks still apply."
      },
      "Payment": {
        "type": "object",
        "properties": {
          "object": {
            "const": "payment"
          },
          "mode": {
            "const": "prepare"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "quoteId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "enum": [
              "draft",
              "cancelled"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "snapshot": {
            "type": "object"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "readiness": {
            "type": "object",
            "properties": {
              "ready": {
                "const": false
              },
              "executionEnabled": {
                "type": "boolean",
                "description": "Released support for this path; not transaction authorization. Draft ready remains false."
              },
              "quoteExpired": {
                "type": "boolean"
              },
              "blockers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              },
              "lifecycle": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            },
            "required": [
              "ready",
              "executionEnabled",
              "quoteExpired",
              "blockers",
              "lifecycle"
            ]
          },
          "executionEnabled": {
            "type": "boolean",
            "description": "Live execution release status. Exact path support, owner policy and transaction action flags must also permit execution."
          },
          "preparation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PaymentPreparation"
              },
              {
                "type": "null"
              }
            ]
          },
          "paymentState": {
            "$ref": "#/components/schemas/PaymentState"
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "archiveReason": {
            "enum": [
              "user",
              "quote_expired",
              null
            ]
          },
          "archivedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "canArchive": {
            "type": "boolean"
          },
          "providerAllocation": {
            "type": [
              "object",
              "null"
            ],
            "description": "Durable Garden, SwapKit or Rift allocation. Present even if provider preparation failed. Resume this payment; do not allocate a replacement.",
            "properties": {
              "responseCaptured": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "Whether a SwapKit build or Rift order response was durably captured. False means its allocation outcome is unknown. A malformed captured response remains retained for review. Null for other adapters."
              },
              "expiresAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "For a validated SwapKit channel, the earlier of its saved quote and deposit deadlines. Before this time, POST /prepare with the same wallets resumes the same channel; afterwards the allocation needs operator review. For a refused SwapKit build, the saved quote deadline before which POST /prepare with the same wallets may retry it. Null when the build is neither validated nor refused, has no saved deposit channel deadline, or for other adapters. For a validated Rift order this is its deposit deadline; funding also requires an unexpired wallet review. Other Rift allocation states may have no known deadline."
              },
              "refusal": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "For a refused SwapKit build (state refused): SwapKit's definite pre-build refusal, a 400 naming a known check with no swap. No deposit channel exists and this payment's credit and API-key holds were released. Null otherwise.",
                "properties": {
                  "providerHttpStatus": {
                    "const": 400
                  },
                  "providerCode": {
                    "enum": [
                      "insufficientBalance",
                      "insufficientGas",
                      "outputBelowPublishedFloor",
                      "outputAmountDeviationTooHigh"
                    ]
                  },
                  "refusedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              },
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "adapter": {
                "enum": [
                  "garden",
                  "swapkit",
                  "rift"
                ]
              },
              "state": {
                "enum": [
                  "allocating",
                  "needs-review",
                  "validated",
                  "refused"
                ]
              },
              "provider_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "quoteReview": {
            "type": [
              "object",
              "null"
            ],
            "description": "Explicitly accepted terms for the existing SwapKit deposit channel. The original quote snapshot is retained. Preparation still checks current policy, wallet readiness and provider expiry.",
            "properties": {
              "accepted": {
                "const": true
              },
              "reviewHash": {
                "type": "string",
                "pattern": "^[a-f0-9]{64}$"
              },
              "minimumReceived": {
                "type": "string"
              },
              "sender": {
                "type": "string"
              },
              "recipient": {
                "type": "string"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "accepted",
              "reviewHash",
              "minimumReceived",
              "sender",
              "recipient",
              "expiresAt"
            ]
          },
          "workflow": {
            "$ref": "#/components/schemas/ComposedPayment"
          }
        },
        "required": [
          "object",
          "mode",
          "id",
          "projectId",
          "quoteId",
          "status",
          "version",
          "snapshot",
          "events",
          "readiness",
          "executionEnabled"
        ]
      },
      "AssetCatalog": {
        "type": "object",
        "properties": {
          "object": {
            "const": "asset_catalog"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "primaryNetwork": {
            "type": "string"
          },
          "networks": {
            "type": "object"
          },
          "assets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "network": {
                  "type": "string"
                },
                "symbol": {
                  "type": "string"
                },
                "decimals": {
                  "type": "integer",
                  "minimum": 0
                },
                "kind": {
                  "enum": [
                    "erc20",
                    "native",
                    "stellar",
                    "soroban",
                    "provider-token"
                  ]
                },
                "category": {
                  "type": "string"
                },
                "verification": {
                  "enum": [
                    "pending",
                    "verified",
                    "unavailable"
                  ]
                },
                "quoteProviders": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "usdPricing": {
                  "enum": [
                    "reviewed",
                    "unsupported"
                  ],
                  "description": "Whether Route has a reviewed USD price identity for this exact asset (network, token identifier and decimals). unsupported: USD policy checks report UNSUPPORTED_PRICE_ASSET, so routes to or from the asset cannot be recommended or prepared. reviewed: covers only this asset's own price; each quote still needs a fresh market observation, and the fee check separately needs a price for the source network's native fee asset, which some networks do not have yet."
                },
                "representationOf": {
                  "type": "string",
                  "description": "Catalog ID of the asset this token represents, such as an ITS or bridged representation. A representation is a different asset."
                },
                "address": {
                  "type": "string",
                  "description": "Chain identity: the EVM token contract, the Stellar asset contract, a provider-chain token address, or 'native'. EVM contracts may be lowercase or EIP-55 checksummed; compare them case-insensitively. Match assets on this and issuer, never on symbol alone."
                },
                "issuer": {
                  "type": "string",
                  "description": "Stellar classic issuer account. Present only for Stellar classic assets; native Circle USDC on Stellar has issuer GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN."
                },
                "providerChain": {
                  "type": "string",
                  "description": "Provider tokens only: the provider's chain label for this token."
                },
                "nearAssetId": {
                  "type": "string",
                  "description": "Provider tokens only: the exact NEAR Intents asset identifier behind this catalog ID."
                },
                "riftAssetId": {
                  "type": "string",
                  "description": "Reviewed Rift identity carried by the catalog. Preserve it alongside exact network, contract and decimals; do not substitute symbols or SDK identities."
                },
                "assetIssuer": {
                  "type": "string",
                  "description": "Token issuer label; assets from different issuers remain separate."
                },
                "assetDescription": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "network",
                "symbol",
                "decimals",
                "kind",
                "quoteProviders",
                "address"
              ]
            }
          }
        },
        "required": [
          "object",
          "projectId",
          "primaryNetwork",
          "networks",
          "assets"
        ]
      },
      "AdapterCatalog": {
        "type": "object",
        "properties": {
          "object": {
            "const": "adapter_catalog"
          },
          "adapters": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "capabilities": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "type": "boolean"
                    },
                    "preparePayment": {
                      "type": "boolean"
                    },
                    "execute": {
                      "type": "boolean",
                      "description": "Live operational release flag. Exact path, current policy and wallet readiness must also permit execution."
                    },
                    "trackTransfer": {
                      "type": "boolean"
                    },
                    "prepareTransaction": {
                      "type": "boolean"
                    },
                    "preparationCoverage": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "walletAuthorization": {
                      "type": "boolean",
                      "description": "Live operational release flag. Exact path, current policy and wallet readiness must also permit execution."
                    },
                    "walletIntentApproval": {
                      "type": "boolean",
                      "description": "NEAR supported EVM, Stellar, Bitcoin, Solana/Fogo, NEAR, TRON, Sui and Aptos wallets. Message consent, not transaction authorization."
                    },
                    "transactionHandoff": {
                      "type": "boolean",
                      "description": "Implemented capability; does not imply signing/submission is enabled."
                    },
                    "multiAction": {
                      "type": "boolean"
                    },
                    "minimumOutputGuaranteed": {
                      "type": "boolean",
                      "description": "Rift is false: quotes are estimates without a protected minimum."
                    },
                    "requiresVariableOutputAcceptance": {
                      "type": "boolean",
                      "description": "Rift is true: prepare requires explicit customer consent to variable output."
                    }
                  },
                  "required": [
                    "quote",
                    "preparePayment",
                    "execute",
                    "trackTransfer"
                  ],
                  "description": "Per-adapter implemented capabilities. Rift supports direct reviewed EVM/Bitcoin order preparation, funding and tracking with explicit variable-output acceptance. HyperCore and composed Rift execution are unsupported; each provider report still requires independent chain settlement evidence."
                },
                "lifecycle": {
                  "type": "object"
                },
                "stellarDestinationExecution": {
                  "type": "object",
                  "description": "Circle only. Managed means sponsorship is configured; provider availability and quota can still delay delivery.",
                  "properties": {
                    "default": {
                      "enum": [
                        "managed",
                        "customer"
                      ]
                    },
                    "managed": {
                      "type": "boolean"
                    },
                    "customer": {
                      "const": true
                    },
                    "provider": {
                      "const": "openzeppelin-channels"
                    }
                  },
                  "required": [
                    "default",
                    "managed",
                    "customer",
                    "provider"
                  ]
                },
                "platformAvailability": {
                  "$ref": "#/components/schemas/ProviderAvailability"
                }
              },
              "required": [
                "id",
                "name",
                "capabilities",
                "lifecycle"
              ]
            }
          },
          "network": {
            "const": "mainnet"
          }
        },
        "required": [
          "object",
          "adapters"
        ]
      },
      "ProviderList": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProviderConnection"
            }
          },
          "routeConnections": {
            "type": "object",
            "description": "Availability of Route-managed access. These booleans never contain credentials and do not promise a tradeable pair.",
            "properties": {
              "near": {
                "type": "boolean"
              },
              "garden": {
                "type": "boolean"
              },
              "swapkit": {
                "type": "boolean"
              }
            },
            "required": [
              "near",
              "garden",
              "swapkit"
            ]
          }
        },
        "required": [
          "projectId",
          "providers",
          "routeConnections"
        ]
      },
      "Policy": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "policy": {
            "type": "object",
            "properties": {
              "valueCurrency": {
                "const": "USD"
              },
              "priority": {
                "enum": [
                  "cost",
                  "speed"
                ]
              },
              "maxFee": {
                "type": "string"
              },
              "maxSeconds": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 1,
                "maximum": 86400,
                "description": "Owner-selected arrival limit. Explicit null removes the deadline; speed ranking still requires comparable end-to-end timing."
              },
              "minAmount": {
                "type": "string"
              },
              "maxAmount": {
                "type": "string"
              },
              "providers": {
                "type": "array",
                "items": {
                  "enum": [
                    "allbridge",
                    "circle",
                    "near",
                    "layerzero",
                    "axelar",
                    "garden",
                    "swapkit",
                    "rift"
                  ]
                }
              },
              "providerRules": {
                "type": "array",
                "maxItems": 20,
                "items": {
                  "$ref": "#/components/schemas/ProviderRule"
                },
                "description": "Mandatory mainnet asset-specific provider rules. All matching rules apply to the payment and each composed leg. Omit on update to retain existing rules; send [] to remove them. No provider or CCTP-mode fallback."
              }
            }
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "network": {
            "enum": [
              "mainnet",
              "testnet",
              "both"
            ]
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArrivalWarning"
            },
            "description": "Arrival-evidence warnings for speed priority or a delivery deadline, derived when the policy is read or saved. Empty when neither is set and for test-token policies."
          }
        },
        "required": [
          "version",
          "policy"
        ]
      },
      "PaymentList": {
        "type": "object",
        "properties": {
          "object": {
            "const": "list"
          },
          "payments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "status": {
                  "enum": [
                    "draft",
                    "cancelled"
                  ]
                },
                "version": {
                  "type": "integer",
                  "minimum": 0
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "input": {
                  "type": "object"
                },
                "route": {
                  "type": "string"
                },
                "archivedAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "archiveReason": {
                  "enum": [
                    "user",
                    "quote_expired",
                    null
                  ]
                },
                "archivedBy": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "canArchive": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "status",
                "version",
                "created_at",
                "input",
                "route"
              ]
            }
          },
          "executionEnabled": {
            "type": "boolean",
            "description": "Live execution release status. Exact path support, owner policy and transaction action flags must also permit execution."
          },
          "view": {
            "enum": [
              "active",
              "archived",
              "all"
            ]
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasMore": {
            "type": "boolean"
          }
        },
        "required": [
          "object",
          "payments",
          "executionEnabled"
        ]
      },
      "Update": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "version": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "ok"
        ]
      },
      "CredentialUpdateResult": {
        "type": "object",
        "description": "Provider credential change. warnings is empty after a save.",
        "required": [
          "ok",
          "version",
          "credentialPresent",
          "warnings"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "credentialPresent": {
            "type": "boolean",
            "description": "Whether a customer credential is now saved for this provider."
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProviderCredentialWarning"
            },
            "description": "Removal is never blocked. A warning names payments whose automatic tracking may be interrupted."
          }
        },
        "additionalProperties": false
      },
      "ProviderCredentialWarning": {
        "type": "object",
        "required": [
          "code",
          "count",
          "message"
        ],
        "properties": {
          "code": {
            "const": "UNSETTLED_PROVIDER_PAYMENTS",
            "description": "Payments tracked with this project's own key for the provider have funding in flight (a source hash or an unconfirmed wallet handoff of a funding transaction) and no terminal outcome. Payments that use Route's key, cancelled or unfunded payments, and payments with only a pending spending approval are not counted."
          },
          "count": {
            "type": "integer",
            "minimum": 1
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "Empty": {
        "type": "object",
        "additionalProperties": false
      },
      "RouteAsset": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "symbol": {
            "type": "string"
          },
          "decimals": {
            "type": "integer",
            "minimum": 0,
            "maximum": 24
          },
          "kind": {
            "enum": [
              "erc20",
              "native",
              "stellar",
              "soroban",
              "provider-token"
            ]
          },
          "issuer": {
            "type": "string"
          },
          "nearAssetId": {
            "type": "string"
          },
          "providerChain": {
            "type": "string"
          },
          "gardenAssetId": {
            "type": "string"
          },
          "gardenChainId": {
            "type": "string"
          },
          "swapkitAssetId": {
            "type": "string",
            "description": "Exact SwapKit catalog identifier resolved by Route; not a customer override."
          },
          "swapkitChainId": {
            "type": "string",
            "description": "Exact SwapKit catalog identifier resolved by Route; not a customer override."
          },
          "riftAssetId": {
            "type": "string",
            "description": "Reviewed Rift identity carried by the catalog. Preserve it alongside exact network, contract and decimals; do not substitute symbols or SDK identities."
          }
        },
        "required": [
          "address",
          "symbol",
          "decimals"
        ]
      },
      "ResolvedQuoteInput": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string"
          },
          "destination": {
            "type": "string"
          },
          "amount": {
            "type": "string"
          },
          "sourceAsset": {
            "$ref": "#/components/schemas/RouteAsset"
          },
          "destinationAsset": {
            "$ref": "#/components/schemas/RouteAsset"
          }
        },
        "required": [
          "source",
          "destination",
          "amount",
          "sourceAsset",
          "destinationAsset"
        ]
      },
      "QuoteLeg": {
        "type": "object",
        "properties": {
          "adapter": {
            "enum": [
              "allbridge",
              "circle",
              "near",
              "layerzero",
              "axelar",
              "garden",
              "swapkit",
              "rift"
            ]
          },
          "route": {
            "type": "string"
          },
          "status": {
            "enum": [
              "quoted",
              "unsupported",
              "unavailable"
            ]
          },
          "fees": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "amount": {
                  "type": "string"
                },
                "currency": {
                  "type": "string"
                },
                "treatment": {
                  "enum": [
                    "deducted",
                    "additional",
                    "included"
                  ]
                },
                "usd": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "network": {
                  "type": "string",
                  "description": "Network where this composed-leg fee applies."
                },
                "leg": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2
                },
                "assetSide": {
                  "enum": [
                    "source",
                    "destination",
                    "source-native",
                    "destination-native",
                    "intermediate-native",
                    "intermediate"
                  ]
                },
                "assetId": {
                  "type": "string",
                  "description": "Exact intermediate catalog asset ID for fee valuation."
                }
              },
              "required": [
                "label",
                "amount",
                "currency",
                "treatment"
              ]
            }
          },
          "received": {
            "type": [
              "string",
              "null"
            ]
          },
          "minimumReceived": {
            "type": [
              "string",
              "null"
            ]
          },
          "eta": {
            "$ref": "#/components/schemas/QuoteEta"
          },
          "capacity": {
            "type": "object",
            "properties": {
              "status": {
                "enum": [
                  "observed",
                  "unknown",
                  "blocked"
                ]
              },
              "scope": {
                "type": "string"
              }
            },
            "required": [
              "status",
              "scope"
            ]
          },
          "unknowns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "executionEnabled": {
            "const": false
          },
          "input": {
            "$ref": "#/components/schemas/ResolvedQuoteInput"
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "gas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GasObservation"
            },
            "description": "Optional per-leg gas evidence returned with view=full."
          },
          "totalFeeComplete": {
            "type": "boolean",
            "description": "All expected network charges have a disclosed comparison estimate; not execution simulation or a guarantee."
          },
          "details": {
            "$ref": "#/components/schemas/QuoteDetails"
          }
        },
        "required": [
          "adapter",
          "route",
          "status",
          "fees",
          "received",
          "minimumReceived",
          "eta",
          "capacity",
          "unknowns",
          "executionEnabled",
          "input",
          "observedAt",
          "expiresAt"
        ],
        "description": "A composed route leg. Compact responses retain required leg fields, minimal resolved asset identities and optional normalized diagnostic details; gas evidence and other provider metadata are available with view=full."
      },
      "QuoteComposition": {
        "type": "object",
        "description": "Two or three ordered, non-atomic quote legs. Requote each next transfer after its verified intermediate receipt. Every leg needs released execution support; executable intermediate wallets must be on Ethereum, Base or Arbitrum.",
        "properties": {
          "atomic": {
            "const": false
          },
          "requiresRequote": {
            "const": true
          },
          "outputBasis": {
            "const": "minimum-intermediate-output"
          },
          "intermediate": {
            "type": "object",
            "properties": {
              "network": {
                "type": "string"
              },
              "asset": {
                "$ref": "#/components/schemas/RouteAsset"
              },
              "amount": {
                "type": "string"
              }
            },
            "required": [
              "network",
              "asset",
              "amount"
            ]
          },
          "legs": {
            "type": "array",
            "minItems": 2,
            "maxItems": 3,
            "items": {
              "$ref": "#/components/schemas/QuoteLeg"
            }
          },
          "strategy": {
            "enum": [
              "auto-route-v1",
              "auto-route-v2"
            ]
          },
          "intermediates": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "items": {
              "type": "object",
              "properties": {
                "network": {
                  "type": "string"
                },
                "asset": {
                  "$ref": "#/components/schemas/RouteAsset"
                },
                "amount": {
                  "type": "string"
                }
              },
              "required": [
                "network",
                "asset",
                "amount"
              ]
            },
            "description": "Ordered intermediate assets for a three-leg route. The legacy intermediate field is the first entry."
          }
        },
        "required": [
          "atomic",
          "requiresRequote",
          "outputBasis",
          "intermediate",
          "legs"
        ]
      },
      "UsdPrice": {
        "type": "object",
        "description": "Fresh exact-asset USD valuation from configured market sources. CoinGecko, DefiLlama, optional CoinMarketCap and reviewed Kraken markets retain upstream timestamps; caching never extends expiry.",
        "properties": {
          "usd": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "enum": [
              "CoinGecko",
              "DefiLlama",
              "Kraken",
              "CoinMarketCap"
            ]
          },
          "assetId": {
            "type": "string"
          },
          "market": {
            "type": "string",
            "description": "Market identity when supplied by the pricing source: a reviewed USD pair for Kraken, or cmc:<numeric ID> for CoinMarketCap. Asset IDs and chain/contract mappings are verified separately; symbols alone never select prices.",
            "anyOf": [
              {
                "enum": [
                  "USDC/USD",
                  "ETH/USD",
                  "APT/USD",
                  "ADI/USD",
                  "SUI/USD"
                ]
              },
              {
                "pattern": "^cmc:[1-9][0-9]*$"
              }
            ]
          },
          "basis": {
            "enum": [
              "trade",
              "order-book-midpoint"
            ],
            "description": "Kraken valuation basis. Midpoints require fresh bids and asks with a spread no greater than 2%; they are valuation estimates, not executable quotes."
          }
        },
        "required": [
          "usd",
          "updatedAt",
          "expiresAt",
          "source",
          "assetId"
        ]
      },
      "UsdValuation": {
        "type": "object",
        "properties": {
          "currency": {
            "const": "USD"
          },
          "source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsdPrice"
              },
              {
                "type": "null"
              }
            ]
          },
          "destination": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsdPrice"
              },
              {
                "type": "null"
              }
            ]
          },
          "gas": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsdPrice"
              },
              {
                "type": "null"
              }
            ]
          },
          "destinationGas": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsdPrice"
              },
              {
                "type": "null"
              }
            ]
          },
          "networkGas": {
            "type": "object",
            "additionalProperties": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/UsdPrice"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "inputUsd": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "assets": {
            "type": "object",
            "description": "Fresh exact-identity intermediate asset prices for composed fee conversion. Missing entries remain unpriced.",
            "additionalProperties": {
              "type": [
                "object",
                "null"
              ]
            }
          },
          "issues": {
            "type": "array",
            "description": "Empty when requested prices were resolved. Older saved observations can omit this field. A missing optional gas price does not itself disqualify a route; policy checks determine eligibility.",
            "items": {
              "$ref": "#/components/schemas/UsdPriceIssue"
            }
          }
        },
        "required": [
          "currency",
          "source",
          "destination",
          "gas",
          "inputUsd",
          "reason"
        ]
      },
      "QuoteEta": {
        "type": "object",
        "properties": {
          "seconds": {
            "type": [
              "number",
              "null"
            ]
          },
          "scope": {
            "type": "string"
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "stage": {
            "enum": [
              "attestation",
              "after-deposit",
              "provider-transfer",
              "end-to-end"
            ]
          },
          "basis": {
            "enum": [
              "live",
              "documented",
              "historical",
              "modeled"
            ]
          },
          "referenceOnly": {
            "type": "boolean",
            "description": "Historical or broader-traffic reference; cannot establish current arrival under policy."
          },
          "confidence": {
            "enum": [
              "low",
              "medium",
              "high"
            ]
          },
          "degraded": {
            "type": "boolean"
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time"
          },
          "sampleTransactions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Detailed quote evidence available with view=full."
          },
          "minSeconds": {
            "type": "number",
            "minimum": 0
          },
          "maxSeconds": {
            "type": "number",
            "minimum": 0
          },
          "sampleCount": {
            "type": "number",
            "minimum": 0,
            "description": "Detailed quote evidence available with view=full."
          },
          "pendingCount": {
            "type": "number",
            "minimum": 0,
            "description": "Detailed quote evidence available with view=full."
          },
          "failedCount": {
            "type": "number",
            "minimum": 0,
            "description": "Detailed quote evidence available with view=full."
          },
          "windowHours": {
            "type": "number",
            "minimum": 0,
            "description": "Detailed quote evidence available with view=full."
          },
          "unavailableReason": {
            "type": "string",
            "description": "Reason an ETA is unavailable, such as INSUFFICIENT_HISTORY, UPSTREAM_RESTRICTED, UPSTREAM_TRANSIENT, READ_TIMEOUT or NETWORK_READ_FAILED."
          },
          "model": {
            "type": "object",
            "description": "Detailed quote evidence available with view=full. Optional arrival-v1 comparison model. Starts at funding broadcast after wallet signing/approvals and ends at recipient receipt with source/destination finality. Engineering allowances, not measured percentiles or an SLA. Inspect assumptions and the preserved provider stage.",
            "properties": {
              "version": {
                "const": "arrival-v1"
              },
              "start": {
                "const": "source-funding-broadcast"
              },
              "finish": {
                "const": "recipient-receipt-and-chain-finality"
              },
              "provider": {
                "type": "object",
                "properties": {
                  "seconds": {
                    "type": "number"
                  },
                  "minSeconds": {
                    "type": "number"
                  },
                  "maxSeconds": {
                    "type": "number"
                  },
                  "stage": {
                    "type": "string"
                  },
                  "source": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  }
                }
              },
              "components": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "min": {
                      "type": "number",
                      "minimum": 0
                    },
                    "max": {
                      "type": "number",
                      "minimum": 0
                    }
                  }
                }
              },
              "assumptions": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "sources": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "seconds",
          "scope",
          "source"
        ]
      },
      "GasObservation": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "network": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "unavailableReason": {
            "type": "string"
          },
          "gasUnits": {
            "type": "string"
          },
          "gasPriceWei": {
            "type": "string"
          },
          "block": {
            "type": "string"
          },
          "amount": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "estimated",
              "unavailable"
            ]
          },
          "basis": {
            "enum": [
              "historical-model",
              "intrinsic-model",
              "utxo-model"
            ]
          },
          "sampleCount": {
            "type": "integer",
            "minimum": 0
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sampleTransactions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "confidence": {
            "enum": [
              "low",
              "medium"
            ],
            "description": "Comparison model confidence. Older OFT references and sparse recent samples are low confidence; actual wallet fees are revalidated before signing."
          },
          "marginBps": {
            "type": "integer",
            "enum": [
              2500,
              5000,
              10000
            ],
            "description": "Budgeting margin over observed gas; not a guaranteed upper bound."
          },
          "sampleWindowHours": {
            "type": "integer",
            "enum": [
              24,
              168
            ]
          },
          "newestSampleAt": {
            "type": "string",
            "format": "date-time"
          },
          "transactionVbytes": {
            "type": "integer",
            "minimum": 1,
            "description": "Assumed Bitcoin transaction virtual bytes for a comparison budget; actual inputs and signed size are checked before execution."
          },
          "feeRateSatVbyte": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "description": "Modeled satoshis per virtual byte after budgeting margin and upward rounding."
          },
          "estimatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When current gas prices, fee rates or network fee statistics were used to compute this budget. Distinct from the age of a historical execution sample."
          },
          "referenceOnly": {
            "type": "boolean",
            "description": "True for an exact OFT reference up to seven days old, with unchanged source/token runtime and EIP-1967 implementation code, current fee pricing, low confidence and a 100% margin. Does not imply current wallet readiness or delivery timing."
          },
          "components": {
            "type": "array",
            "description": "Breakdown of this gas amount, including budgeting margin. Components sum to amount; do not charge them again. Provider relay/destination fees are separate quote fees.",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "enum": [
                    "execution",
                    "l1-data",
                    "operator",
                    "network"
                  ]
                },
                "currency": {
                  "type": "string"
                },
                "amount": {
                  "type": "string"
                }
              },
              "required": [
                "kind",
                "currency",
                "amount"
              ]
            }
          }
        },
        "required": [
          "label",
          "network",
          "status",
          "amount",
          "currency",
          "basis",
          "sampleCount",
          "assumptions",
          "source"
        ]
      },
      "PrepareDeposit": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/NearPrepareDeposit"
          },
          {
            "$ref": "#/components/schemas/ProtocolPrepare"
          },
          {
            "$ref": "#/components/schemas/ComposedPrepare"
          },
          {
            "$ref": "#/components/schemas/RiftPrepare"
          }
        ]
      },
      "RegisterSource": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "sourceHash": {
            "type": "string",
            "description": "Chain-specific source hash: EVM 0x plus 64 hex digits, Stellar 64 hex digits (optional 0x), Bitcoin 64 hex digits, Solana/Fogo base58 transaction signature; NEAR/Sui base58 hash; TRON 64 lowercase hex digits; Aptos 0x plus 64 hex digits."
          }
        },
        "required": [
          "version",
          "sourceHash"
        ],
        "additionalProperties": false
      },
      "PaymentCheck": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "enum": [
              "pass",
              "fail",
              "unknown"
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "message"
        ]
      },
      "NearDeposit": {
        "type": "object",
        "description": "Signed provider quote and public deposit plan. Does not sign, submit or reserve a wallet nonce. Memo is required for Stellar source. Review expiry blocks funding, not tracking.",
        "properties": {
          "schemaVersion": {
            "const": 1
          },
          "adapter": {
            "const": "near"
          },
          "network": {
            "const": "mainnet"
          },
          "quoteHash": {
            "type": "string"
          },
          "request": {
            "type": "object"
          },
          "response": {
            "type": "object",
            "description": "Original provider-signed quote."
          },
          "depositAddress": {
            "type": "string"
          },
          "depositMemo": {
            "type": [
              "string",
              "null"
            ]
          },
          "received": {
            "type": "string"
          },
          "minimumReceived": {
            "type": "string"
          },
          "refundFee": {
            "type": [
              "string",
              "null"
            ]
          },
          "withdrawalFeeIncluded": {
            "type": [
              "string",
              "null"
            ]
          },
          "secondsAfterDepositConfirmation": {
            "type": "integer"
          },
          "reviewExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "refundDeadline": {
            "type": "string",
            "format": "date-time"
          },
          "transaction": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "family": {
                    "const": "evm"
                  },
                  "chainId": {
                    "type": "string"
                  },
                  "from": {
                    "type": "string"
                  },
                  "to": {
                    "type": "string"
                  },
                  "value": {
                    "type": "string"
                  },
                  "data": {
                    "type": "string"
                  }
                },
                "required": [
                  "family",
                  "chainId",
                  "from",
                  "to",
                  "value",
                  "data"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "family": {
                    "const": "stellar"
                  },
                  "network": {
                    "const": "public"
                  },
                  "from": {
                    "type": "string"
                  },
                  "to": {
                    "type": "string"
                  },
                  "assetCode": {
                    "type": "string"
                  },
                  "assetIssuer": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "amount": {
                    "type": "string"
                  },
                  "memo": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "id"
                      },
                      "value": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "value"
                    ]
                  }
                },
                "required": [
                  "family",
                  "network",
                  "from",
                  "to",
                  "assetCode",
                  "assetIssuer",
                  "amount",
                  "memo"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "family": {
                    "enum": [
                      "bitcoin",
                      "solana",
                      "near",
                      "tron",
                      "sui",
                      "aptos",
                      "utxo",
                      "xrp"
                    ]
                  },
                  "network": {
                    "enum": [
                      "btc",
                      "sol",
                      "fogo",
                      "near",
                      "tron",
                      "sui",
                      "aptos",
                      "ltc",
                      "doge",
                      "xrp"
                    ]
                  },
                  "from": {
                    "type": "string"
                  },
                  "to": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string"
                  },
                  "asset": {
                    "$ref": "#/components/schemas/RouteAsset"
                  }
                },
                "required": [
                  "family",
                  "network",
                  "from",
                  "to",
                  "amount",
                  "asset"
                ]
              }
            ],
            "description": "Deposit plan only, not the signed transaction payload. Use POST /payments/{id}/transaction after intent approval."
          },
          "executionEnabled": {
            "const": false
          },
          "walletReady": {
            "const": false
          },
          "reviewRefreshEnabled": {
            "type": "boolean",
            "description": "May request review of an unsubmitted EVM NEAR deposit; fresh checks can still block it."
          }
        },
        "required": [
          "schemaVersion",
          "adapter",
          "network",
          "quoteHash",
          "request",
          "response",
          "depositAddress",
          "depositMemo",
          "received",
          "minimumReceived",
          "transaction",
          "reviewExpiresAt",
          "executionEnabled",
          "walletReady"
        ]
      },
      "NearTracking": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "object",
            "description": "Provider report tied to the saved signed quote. Its receivedAmount remains the original provider amount; independently verified actual Bitcoin receipts are exposed separately in received and bitcoinPayout. See /docs/recovery.md#bitcoin-fee-adjustment-discrepancies."
          },
          "status": {
            "enum": [
              "awaiting-deposit",
              "source-pending",
              "incomplete-deposit",
              "processing",
              "delivery-reported",
              "refund-reported",
              "needs-review",
              "verification-pending",
              "source-reverted",
              "completed",
              "refunded"
            ]
          },
          "message": {
            "type": "string"
          },
          "sourceVerified": {
            "type": "boolean"
          },
          "sourceFinalized": {
            "type": "boolean",
            "description": "Canonical source receipt satisfies Route finality. Bitcoin requires six confirmations; sourceVerified may become true earlier."
          },
          "destinationVerified": {
            "type": "boolean",
            "description": "The destination receipt verifies the exact recipient and amount. This may be true before sourceFinalized; display delivery separately from completion."
          },
          "destinationFinalized": {
            "type": "boolean",
            "description": "Verified destination receipt satisfies Route finality. Bitcoin destinations require six confirmations."
          },
          "refundVerified": {
            "type": "boolean"
          },
          "refundFinalized": {
            "type": "boolean"
          },
          "completed": {
            "type": "boolean"
          },
          "sourceHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "destinationHash": {
            "type": "string"
          },
          "refundHash": {
            "type": "string"
          },
          "observedDeliverySeconds": {
            "type": "number"
          },
          "sourceAmountMinor": {
            "type": [
              "string",
              "null"
            ]
          },
          "settlementDiscrepancies": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/BitcoinSettlementDiscrepancy"
                },
                {
                  "$ref": "#/components/schemas/TronSettlementDiscrepancy"
                }
              ]
            },
            "description": "Present when canonical Bitcoin settlement evidence requires amount reconciliation. Preserve the payment; do not fund again. These diagnostics do not override completed or receipt-verification flags."
          },
          "received": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)(\\.\\d{1,8})?$",
            "description": "Verified actual Bitcoin recipient amount in BTC decimal units. New BTC completion transitions require all finality flags and a persisted payout claim. Historical completed records may omit this optional field."
          },
          "bitcoinPayout": {
            "$ref": "#/components/schemas/BitcoinPayoutEvidence"
          },
          "sourceSubmissionObservation": {
            "$ref": "#/components/schemas/SourceSubmissionObservation"
          }
        },
        "required": [
          "provider",
          "status",
          "message",
          "completed",
          "sourceVerified",
          "sourceFinalized",
          "sourceHash"
        ]
      },
      "PaymentPreparation": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/NearPaymentPreparation"
          },
          {
            "$ref": "#/components/schemas/ProtocolPreparation"
          },
          {
            "$ref": "#/components/schemas/ComposedPayment"
          }
        ]
      },
      "WebhookEndpoint": {
        "type": "object",
        "required": [
          "id",
          "name",
          "url",
          "enabled",
          "version"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "enabled": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "deliveryStatus": {
            "type": "string",
            "enum": [
              "ready",
              "disabled",
              "awaiting-activation"
            ],
            "description": "Receiver activation state. An enabled endpoint still requires an approved HTTPS origin before delivery."
          },
          "policy_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Endpoint scope fixed from its creating API key, or attributed from creation evidence for an endpoint created before 1.44.0-preview; null is project-wide. API keys cannot inspect or manage project-wide endpoints."
          },
          "scope_review_required": {
            "type": "boolean",
            "description": "The upgrade could not establish whether a dashboard user or which policy's API key created this legacy endpoint, so it was disabled. A dashboard webhook manager must review and re-enable it as project-wide; API keys cannot see it."
          }
        }
      },
      "WebhookResult": {
        "type": "object",
        "properties": {
          "endpoint": {
            "$ref": "#/components/schemas/WebhookEndpoint"
          },
          "secret": {
            "type": "string",
            "description": "Shown exactly once on creation/rotation."
          },
          "endpoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEndpoint"
            }
          },
          "deliveries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "deliveryStatus": {
                  "type": "string",
                  "enum": [
                    "ready",
                    "disabled",
                    "awaiting-activation"
                  ],
                  "description": "Receiver activation state. An enabled endpoint still requires an approved HTTPS origin before delivery."
                },
                "status": {
                  "enum": [
                    "pending",
                    "delivered",
                    "dead",
                    "disabled",
                    "expired"
                  ]
                },
                "version": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "deliveryEnabled": {
            "type": "boolean"
          },
          "queued": {
            "type": "boolean"
          }
        }
      },
      "KeyGuardrails": {
        "type": "object",
        "additionalProperties": false,
        "description": "Immutable optional per-key controls. Missing or null controls are unrestricted; empty lists are invalid. USD values exclude source network gas.",
        "properties": {
          "maxPaymentUsd": {
            "type": [
              "string",
              "null"
            ]
          },
          "rollingLimit": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "amountUsd",
                  "period"
                ],
                "properties": {
                  "amountUsd": {
                    "type": "string"
                  },
                  "period": {
                    "type": "string",
                    "enum": [
                      "day",
                      "week",
                      "month"
                    ],
                    "description": "Rolling 24 hours, 7 days or 30 days."
                  }
                }
              }
            ]
          },
          "allowedProviders": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string",
              "enum": [
                "allbridge",
                "circle",
                "near",
                "layerzero",
                "axelar",
                "garden",
                "swapkit",
                "rift"
              ]
            },
            "minItems": 1,
            "maxItems": 100,
            "uniqueItems": true
          },
          "allowedSourceNetworks": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "uniqueItems": true
          },
          "allowedDestinationNetworks": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "uniqueItems": true
          },
          "allowedSourceAssets": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "uniqueItems": true
          },
          "allowedDestinationAssets": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "uniqueItems": true
          },
          "recipients": {
            "type": [
              "array",
              "null"
            ],
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "network",
                "address"
              ],
              "properties": {
                "network": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "KeyRestriction": {
        "type": "object",
        "required": [
          "keyId",
          "guardrails"
        ],
        "properties": {
          "keyId": {
            "type": "string",
            "format": "uuid"
          },
          "guardrails": {
            "$ref": "#/components/schemas/KeyGuardrails"
          }
        }
      },
      "WalletApprovalChallenge": {
        "type": "object",
        "description": "Immutable server-issued message. Its intent digest binds the saved provider quote, transaction plan and key restrictions. Never replace fields before signing.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "intent": {
            "type": "object",
            "description": "Bound origin, project, payment, preparation, policy and provider versions, key restrictions, payment intent, quote hash and deposit/transaction plan."
          },
          "intentDigest": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "signer": {
            "type": "string"
          },
          "sourceNetwork": {
            "type": "string",
            "description": "Exact supported source network identifier from the catalog."
          },
          "signing": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "method": {
                    "const": "eth_signTypedData_v4"
                  },
                  "typedData": {
                    "type": "object",
                    "properties": {
                      "domain": {
                        "type": "object"
                      },
                      "primaryType": {
                        "const": "PaymentIntentApproval"
                      },
                      "types": {
                        "type": "object"
                      },
                      "message": {
                        "type": "object"
                      }
                    },
                    "required": [
                      "domain",
                      "primaryType",
                      "types",
                      "message"
                    ]
                  }
                },
                "required": [
                  "method",
                  "typedData"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "method": {
                    "const": "sep53_signMessage"
                  },
                  "networkPassphrase": {
                    "const": "Public Global Stellar Network ; September 2015"
                  },
                  "message": {
                    "type": "string",
                    "description": "Unprefixed human-readable message; Freighter adds the SEP-53 prefix."
                  }
                },
                "required": [
                  "method",
                  "networkPassphrase",
                  "message"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "method": {
                    "const": "bip322_signMessage"
                  },
                  "message": {
                    "type": "string"
                  }
                },
                "required": [
                  "method",
                  "message"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "method": {
                    "const": "solana_signMessage"
                  },
                  "message": {
                    "type": "string"
                  }
                },
                "required": [
                  "method",
                  "message"
                ]
              },
              {
                "type": "object",
                "required": [
                  "method",
                  "message",
                  "nonce",
                  "recipient"
                ],
                "properties": {
                  "method": {
                    "const": "near_signMessage"
                  },
                  "message": {
                    "type": "string"
                  },
                  "nonce": {
                    "type": "string",
                    "description": "32-byte base64 NEP-413 nonce."
                  },
                  "recipient": {
                    "type": "string"
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "method",
                  "message"
                ],
                "properties": {
                  "method": {
                    "const": "tron_signMessageV2"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "method",
                  "message"
                ],
                "properties": {
                  "method": {
                    "const": "sui_signPersonalMessage"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "method",
                  "message"
                ],
                "properties": {
                  "method": {
                    "const": "aptos_signRawMessage"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "method",
                  "network",
                  "message"
                ],
                "properties": {
                  "method": {
                    "const": "utxo_signMessage"
                  },
                  "network": {
                    "enum": [
                      "ltc",
                      "doge"
                    ]
                  },
                  "message": {
                    "type": "string",
                    "description": "Exact message, signed with the selected network compact-message format: Litecoin BIP137 P2WPKH or Dogecoin compressed P2PKH."
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "method",
                  "message"
                ],
                "properties": {
                  "method": {
                    "const": "xrp_signMessage"
                  },
                  "message": {
                    "type": "string",
                    "description": "Sign the UTF-8 bytes of \"Route XRP intent:\\n\" followed by this exact message with the enabled master key. Return a JSON string containing publicKey and signature."
                  }
                }
              }
            ]
          }
        },
        "required": [
          "id",
          "intent",
          "intentDigest",
          "expiresAt",
          "signer",
          "sourceNetwork",
          "signing"
        ]
      },
      "WalletIntentApproval": {
        "type": "object",
        "description": "Off-chain sender-key consent only. Historical signatureVerified may remain true when expired, stale or revoked. This never authorizes a transaction or overrides readiness blockers; stored signatures are omitted.",
        "properties": {
          "object": {
            "const": "wallet_intent_approval"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "enum": [
              "awaiting-signature",
              "approved",
              "revoked",
              "expired",
              "stale"
            ]
          },
          "signatureVerified": {
            "type": "boolean"
          },
          "approvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "challenge": {
            "$ref": "#/components/schemas/WalletApprovalChallenge"
          },
          "assessment": {
            "type": "object",
            "description": "Initial readiness or the most recently saved fresh confirmation assessment, including unresolved blockers; not continuously refreshed."
          },
          "confirmationKeyRestrictions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KeyRestriction"
            }
          },
          "mode": {
            "const": "intent-only"
          },
          "transactionSigningEnabled": {
            "const": false
          },
          "executionEnabled": {
            "const": false
          }
        },
        "required": [
          "object",
          "id",
          "status",
          "signatureVerified",
          "approvedAt",
          "revokedAt",
          "expiresAt",
          "challenge",
          "assessment",
          "confirmationKeyRestrictions",
          "mode",
          "transactionSigningEnabled",
          "executionEnabled"
        ]
      },
      "WalletApprovalResult": {
        "type": "object",
        "properties": {
          "approval": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WalletIntentApproval"
              },
              {
                "type": "null"
              }
            ]
          },
          "required": {
            "type": "boolean"
          },
          "method": {
            "const": "transaction-signature"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "approval"
        ]
      },
      "ConfirmWalletApproval": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "approvalId": {
            "type": "string",
            "format": "uuid"
          },
          "signature": {
            "type": "string",
            "description": "EVM: 65-byte 0x hex. Stellar SEP-53 and Solana/Fogo: canonical base64 64-byte signature. Bitcoin: base64 BIP322 simple proof, optional smp prefix."
          }
        },
        "required": [
          "approvalId",
          "signature"
        ]
      },
      "RevokeWalletApproval": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "approvalId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "approvalId"
        ]
      },
      "PaymentTransaction": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/NearPaymentTransaction"
          },
          {
            "$ref": "#/components/schemas/ProtocolTransaction"
          }
        ]
      },
      "TransactionResult": {
        "type": "object",
        "properties": {
          "transaction": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PaymentTransaction"
              },
              {
                "type": "null"
              }
            ]
          },
          "executionEnabled": {
            "type": "boolean"
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProtocolTransaction"
            },
            "description": "Present for protocol payments; current action plus immutable history."
          },
          "reviewRefreshEnabled": {
            "type": "boolean",
            "description": "May request review of an unsubmitted EVM NEAR deposit; fresh checks can still block it."
          },
          "sourceRenewalEnabled": {
            "type": "boolean",
            "description": "An expired NEAR Stellar source is eligible for a renewal proof; not permission to resend."
          }
        },
        "required": [
          "transaction",
          "executionEnabled"
        ]
      },
      "PrepareTransaction": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "approvalId": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "integer",
                "minimum": 1
              }
            },
            "required": [
              "approvalId",
              "version"
            ]
          },
          {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "version": {
                "type": "integer",
                "minimum": 1
              }
            },
            "required": [
              "version"
            ]
          }
        ],
        "description": "Choose by the prepared adapter: NEAR needs approvalId; protocol actions must omit it. Version is the current preparation version."
      },
      "SaveTransactionSignature": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "signedTransaction": {
            "type": "string",
            "maxLength": 100000,
            "description": "Exact saved action signed by its sender: EVM serialized transaction hex; Stellar signed XDR base64; Bitcoin signed/finalized PSBT base64 or raw transaction hex; Solana/Fogo signed serialized transaction base64; NEAR signed Borsh base64; TRON signed transaction JSON string; Sui JSON string containing bytes and signature; Aptos signed BCS base64. Never a private key."
          }
        },
        "required": [
          "authorizationId",
          "signedTransaction"
        ]
      },
      "SubmitTransaction": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "authorizationId"
        ]
      },
      "ExecutionCapability": {
        "type": "object",
        "properties": {
          "supported": {
            "type": "boolean"
          },
          "enabled": {
            "type": "boolean"
          },
          "mode": {
            "enum": [
              "wallet-signature",
              "quote-only",
              "multi-step-wallet-signature"
            ]
          },
          "reason": {
            "type": "string"
          }
        },
        "required": [
          "supported",
          "enabled",
          "mode",
          "reason"
        ]
      },
      "NearPrepareDeposit": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "sender": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "refundTo": {
            "type": "string"
          },
          "slippageBps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "description": "Optional. Defaults to the selected quote’s saved tolerance. A different value returns 409 QUOTE_TERMS_CHANGED before provider allocation; change it on a new quote instead."
          },
          "minimumReceived": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Optional. Defaults to the selected quote’s minimum. May be raised but never lowered; a fresh executable quote must meet this bound."
          },
          "refundDeadline": {
            "type": "string",
            "format": "date-time",
            "description": "Five minutes to one day ahead."
          }
        },
        "required": [
          "version",
          "sender",
          "recipient",
          "refundTo",
          "refundDeadline"
        ],
        "additionalProperties": false
      },
      "NearPaymentTransaction": {
        "type": "object",
        "description": "Exact customer-signed NEAR source attempt on supported EVM, Stellar, Bitcoin, Solana/Fogo, NEAR, TRON, Sui and Aptos networks. Signed bytes are not returned. submitted means network acknowledgement, not delivery. Unknown/submitting attempts must be tracked, never automatically replaced. Wallet handoffs awaiting a hash are projected as submission-unknown with signingEnabled and submissionEnabled false. Once verified, state is submitted; normal receipt tracking establishes finality and delivery.",
        "properties": {
          "object": {
            "const": "payment_transaction"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "approvalId": {
            "type": "string",
            "format": "uuid"
          },
          "state": {
            "enum": [
              "ready",
              "signed",
              "submitting",
              "submitted",
              "submission-unknown",
              "cancelled"
            ]
          },
          "expired": {
            "type": "boolean"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "transaction": {
            "type": "object",
            "description": "Exact unsigned payload: EVM transaction.transaction; Stellar transaction.xdr and networkPassphrase; Bitcoin transaction.psbt; Solana/Fogo transaction.serialized (base64). See /docs/payment-transactions.md. NEAR: unsignedBase64 (Borsh); TRON: transaction (JSON/protobuf); Sui: unsignedBase64 (BCS); Aptos: unsignedBase64 (RawTransaction BCS). See the signing guide for return encodings. These four account families use an external sign-only signer. Litecoin/Dogecoin use family utxo with network ltc/doge, a base64 PSBT and immutable input/fee evidence; return signed PSBT or raw hex. XRP uses family xrp, network xrp, transaction JSON and unsignedHex; return the canonical signed hex blob. These families require sign-only external signers."
          },
          "transactionDigest": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "sourceHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "signingEnabled": {
            "type": "boolean"
          },
          "submissionEnabled": {
            "type": "boolean"
          },
          "executionEnabled": {
            "type": "boolean",
            "description": "Live execution release status. Exact path support, owner policy and transaction action flags must also permit execution."
          },
          "assessment": {
            "type": "object"
          },
          "submissionAssessment": {
            "type": [
              "object",
              "null"
            ]
          },
          "lastError": {
            "type": [
              "object",
              "null"
            ],
            "description": "Latest failed NEAR readiness diagnostic, with code, message, details.blockers, checkedAt and phase. Persisted only while the same unsubmitted attempt/review is current. Successful renewal, signature acceptance or submission preflight clears it. Older failures may have no detail; submission uncertainty uses SUBMISSION_UNKNOWN. New records may include observation.category (a sanitized RPC or transport category) and observation.automaticResubmissionAllowed=false. This observation is not canonical execution or cancellation evidence. Code WALLET_TRANSACTION_REVIEW_REQUIRED (WalletAlteredTransaction evidence) takes precedence over later diagnostics: the database keeps unresolved evidence as lastError; after an uncertain Route send it carries the SUBMISSION_UNKNOWN diagnostic as submission."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "submittedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "review": {
            "type": [
              "object",
              "null"
            ],
            "description": "Current append-only deposit review; outer expiresAt and approvalId are effective values. Original transaction bytes and digest stay unchanged.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "checkedAt": {
                "type": "string",
                "format": "date-time"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "reviewRefreshEnabled": {
            "type": "boolean",
            "description": "May request review of an unsubmitted EVM NEAR deposit; fresh checks can still block it."
          },
          "actionBlocker": {
            "type": [
              "object",
              "null"
            ],
            "description": "Present on GET transaction. Current state or expiry blocker. details preserves recovery instructions such as action: refresh-deposit-review. Code WALLET_TRANSACTION_REVIEW_REQUIRED carries the recorded WalletAlteredTransaction evidence in details. Does not perform a fresh wallet or policy assessment.",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object"
              }
            }
          },
          "walletBroadcastAvailable": {
            "type": "boolean",
            "description": "EVM-only alternative before saving a signature. POST /transaction/broadcast repeats current authorization checks. False once unresolved review evidence is recorded for a burn, transfer or NEAR source transaction (a wallet-altered copy, the same payment found at another nonce, or another reported transaction the wallet signed)."
          },
          "walletBroadcast": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/WalletBroadcast"
              },
              {
                "type": "null"
              }
            ]
          },
          "cancellation": {
            "type": [
              "object",
              "null"
            ],
            "description": "Finalized intermediate source cancellation proof. Original signature/hash records remain saved; this action must not be sent again."
          },
          "sourceRecovery": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/BitcoinSourceRecoveryProof"
              }
            ]
          }
        },
        "required": [
          "object",
          "id",
          "approvalId",
          "state",
          "expired",
          "expiresAt",
          "transaction",
          "transactionDigest",
          "sourceHash",
          "signingEnabled",
          "submissionEnabled",
          "executionEnabled",
          "assessment",
          "submissionAssessment",
          "lastError",
          "createdAt",
          "submittedAt"
        ]
      },
      "NearPaymentPreparation": {
        "type": "object",
        "properties": {
          "object": {
            "const": "payment_preparation"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "adapter": {
            "const": "near"
          },
          "network": {
            "const": "mainnet"
          },
          "state": {
            "enum": [
              "preparing",
              "prepared",
              "needs-review"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "intent": {
            "type": "object"
          },
          "deposit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NearDeposit"
              },
              {
                "type": "null"
              }
            ]
          },
          "sourceHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "tracking": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NearTracking"
              },
              {
                "type": "null"
              }
            ]
          },
          "lastError": {
            "type": [
              "object",
              "null"
            ],
            "description": "MINIMUM_OUTPUT_NOT_MET includes details.requiredMinimum, providerMinimum, providerExpected, asset, slippageBps and action: reconcile. Original intent remains unchanged and deposit is null. Other errors require manual reconciliation."
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "readiness": {
            "type": "object",
            "properties": {
              "walletReady": {
                "type": "boolean"
              },
              "executionEnabled": {
                "type": "boolean"
              },
              "checks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PaymentCheck"
                }
              },
              "policyChecks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PaymentCheck"
                }
              },
              "blockers": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PaymentCheck"
                }
              },
              "unsignedTransaction": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Review payload only; obtain the saved signable attempt through /transaction after intent approval. EVM fields, Stellar XDR, Bitcoin PSBT, Solana-family serialization or a NEAR/TRON/Sui/Aptos deposit plan. Preparation does not reserve wallet slots."
              },
              "estimatedCostUsd": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "costComplete": {
                "type": "boolean"
              }
            },
            "required": [
              "walletReady",
              "executionEnabled",
              "blockers"
            ]
          },
          "executionEnabled": {
            "type": "boolean",
            "description": "Live execution release status. Exact path support, owner policy and transaction action flags must also permit execution."
          },
          "keyRestrictions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KeyRestriction"
            },
            "description": "Original key restrictions retained for this operation. Historical records may omit this field."
          },
          "walletApproval": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WalletIntentApproval"
              },
              {
                "type": "null"
              }
            ]
          },
          "transaction": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PaymentTransaction"
              },
              {
                "type": "null"
              }
            ],
            "description": "Stored attempt; read the transaction endpoint for current release/action flags."
          },
          "execution": {
            "$ref": "#/components/schemas/ExecutionCapability"
          },
          "canReconcile": {
            "type": "boolean",
            "description": "This rejected direct NEAR attempt can request the read-only /reconcile check. No deposit instructions or wallet action have been issued."
          },
          "recovery": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NearPreparationRecovery"
              },
              {
                "type": "null"
              }
            ]
          },
          "reviewRefreshEnabled": {
            "type": "boolean",
            "description": "May request review of an unsubmitted EVM NEAR deposit; fresh checks can still block it."
          },
          "nextAction": {
            "type": "string",
            "enum": [
              "completed",
              "refresh-deposit-review",
              "track",
              "approve-wallet-intent",
              "prepare-transaction",
              "sign",
              "submit",
              "confirm-wallet-broadcast",
              "cancelled",
              "review-required",
              "renew-source"
            ],
            "description": "Current NEAR preparation hint. Unknown future values pause signing/submission. Read live flags and blockers before acting."
          },
          "sourceRenewalEnabled": {
            "type": "boolean",
            "description": "Use next-action and POST transaction/renew to verify expiry, unused sequence and the still-unfunded provider deposit before obtaining new wallet consent."
          },
          "renewalHistory": {
            "type": "array",
            "maxItems": 20,
            "description": "Newest twenty source renewals. Original signed actions remain immutable in storage; no private keys or signed payloads are returned.",
            "items": {
              "$ref": "#/components/schemas/StellarSourceRenewalHistory"
            }
          }
        },
        "required": [
          "id",
          "paymentId",
          "adapter",
          "network",
          "state",
          "version",
          "deposit",
          "sourceHash",
          "tracking",
          "readiness",
          "executionEnabled"
        ]
      },
      "ProtocolPrepare": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "sender": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "destinationFeePayer": {
            "type": "string"
          },
          "destinationFeeBudget": {
            "type": "string",
            "description": "Customer mode only: owner-selected maximum XLM mint fee. Required with destinationFeePayer. Not accepted in managed mode."
          },
          "destinationExecution": {
            "type": "string",
            "enum": [
              "managed",
              "customer"
            ],
            "description": "Circle to Stellar only. Defaults to managed when no destinationFeePayer is supplied. Legacy fee-payer requests remain customer-funded. Fixed for the prepared payment."
          }
        },
        "required": [
          "version",
          "sender",
          "recipient"
        ],
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "destinationExecution": {
                  "const": "customer"
                }
              },
              "required": [
                "destinationExecution"
              ]
            },
            "then": {
              "required": [
                "destinationFeePayer",
                "destinationFeeBudget"
              ]
            }
          },
          {
            "if": {
              "properties": {
                "destinationExecution": {
                  "const": "managed"
                }
              },
              "required": [
                "destinationExecution"
              ]
            },
            "then": {
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "destinationFeePayer"
                    ]
                  },
                  {
                    "required": [
                      "destinationFeeBudget"
                    ]
                  }
                ]
              }
            }
          }
        ],
        "dependentRequired": {
          "destinationFeePayer": [
            "destinationFeeBudget"
          ],
          "destinationFeeBudget": [
            "destinationFeePayer"
          ]
        }
      },
      "ProtocolTransaction": {
        "type": "object",
        "description": "One immutable protocol action. Inspect kind: approval and approval-reset only change token allowance and incur network fees; they do not send the payment. Wait for approval canContinue: true after a verified finalized Stellar allowance event or successful canonical EVM block inclusion, then request the burn or transfer with fresh terms. expiresAt belongs to this action, not a later transfer. Signed bytes are never returned. Each action is submitted at most once. Unsubmitted EVM approvals support explicit review refresh without replacing the payload. expiresAt is the effective review deadline; originalExpiresAt preserves original evidence. Wallet handoffs awaiting a hash are projected as submission-unknown with signingEnabled and submissionEnabled false. Once verified, state is submitted; normal receipt tracking establishes finality and delivery.",
        "properties": {
          "object": {
            "const": "payment_transaction"
          },
          "authorization": {
            "const": "transaction-signature"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sequence": {
            "type": "integer",
            "minimum": 1
          },
          "kind": {
            "enum": [
              "approval-reset",
              "approval",
              "burn",
              "transfer",
              "mint"
            ]
          },
          "network": {
            "type": "string",
            "description": "Exact network identifier for this saved wallet action. Resolve supported networks through the asset and adapter catalogs."
          },
          "sender": {
            "type": "string"
          },
          "state": {
            "enum": [
              "ready",
              "signed",
              "submitting",
              "submitted",
              "submission-unknown",
              "cancelled"
            ]
          },
          "transaction": {
            "$ref": "#/components/schemas/ProtocolAction"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "New burns/transfers/customer-signed mints: five minutes from action construction. EVM approvals/resets and Stellar CCTP approvals/resets: 15 minutes. Existing actions retain original deadlines. Current fees, transaction validity and policy are rechecked before signing/submission; review time does not reserve a quoted rate."
          },
          "signingEnabled": {
            "type": "boolean"
          },
          "submissionEnabled": {
            "type": "boolean"
          },
          "executionEnabled": {
            "type": "boolean"
          },
          "sourceHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "receipt": {
            "$ref": "#/components/schemas/ProtocolReceipt"
          },
          "originalExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "expired": {
            "type": "boolean"
          },
          "reviewRefreshEnabled": {
            "type": "boolean",
            "description": "Eligible to request fresh checks; not a guarantee that checks will pass."
          },
          "review": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "checkedAt": {
                "type": "string",
                "format": "date-time"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "id",
              "checkedAt",
              "expiresAt"
            ]
          },
          "assessment": {
            "$ref": "#/components/schemas/ProtocolAssessment"
          },
          "canContinue": {
            "type": "boolean",
            "description": "True after a successful canonical EVM approval/reset receipt proves the exact allowance event (one block inclusion); receipt.finalized can remain false. Stellar CCTP approval/reset requires finalized success and the exact token allowance event, including its expiration ledger. Other action kinds still require finalized success. Request the next action using the latest preparation version. Route rechecks approval dependencies and current wallet state before proceeding."
          },
          "intentApprovalRequired": {
            "const": false
          },
          "lastError": {
            "type": [
              "object",
              "null"
            ],
            "description": "Latest saved diagnostic for this action. Code WALLET_TRANSACTION_REVIEW_REQUIRED carries WalletAlteredTransaction evidence (reason equivalent-execution when the same payment was found at another nonce, reason unclassified-sender-transaction for any other reported transaction the wallet signed that is neither the saved transaction nor a recognized cancellation): the payment stays in review until a verified terminal receipt, and neither confirming the exact original, a review refresh, a signature nor a send outcome clears it. Code EQUIVALENT_EVIDENCE_SUPERSEDED records equivalent-execution or unclassified-sender-transaction evidence that Route later attributed to another of its payments. After an uncertain Route send of the saved original, the evidence carries that send's SUBMISSION_UNKNOWN diagnostic as submission."
          },
          "actionBlocker": {
            "description": "Explains why some or all wallet actions are blocked. Recorded wallet evidence uses WALLET_TRANSACTION_REVIEW_REQUIRED; a saved provider contract that differs from reviewed addresses uses DEPLOYMENT_CHANGED, disabling signing, submission and new handoffs. Existing handoffs blocked by payment evidence or a deployment mismatch withhold send parameters. Historical transactions remain available for recovery and tracking.",
            "oneOf": [
              {
                "type": "object",
                "description": "Present only while recorded review evidence blocks this action (code WALLET_TRANSACTION_REVIEW_REQUIRED, evidence in details). For a burn or transfer, signingEnabled, submissionEnabled and walletBroadcastAvailable are then false and an existing walletBroadcast has no params. For a signed approval with a recorded altered copy, submissionEnabled is false.",
                "required": [
                  "code",
                  "message",
                  "details"
                ],
                "properties": {
                  "code": {
                    "const": "WALLET_TRANSACTION_REVIEW_REQUIRED"
                  },
                  "message": {
                    "type": "string"
                  },
                  "details": {
                    "type": "object"
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "code",
                  "message"
                ],
                "properties": {
                  "code": {
                    "const": "DEPLOYMENT_CHANGED"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "walletBroadcastAvailable": {
            "type": "boolean",
            "description": "EVM-only alternative before saving a signature. POST /transaction/broadcast repeats current authorization checks. False once unresolved review evidence is recorded for a burn, transfer or NEAR source transaction (a wallet-altered copy, the same payment found at another nonce, or another reported transaction the wallet signed)."
          },
          "walletBroadcast": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/WalletBroadcast"
              },
              {
                "type": "null"
              }
            ]
          },
          "mintRenewalEnabled": {
            "type": "boolean",
            "description": "The current expired customer Stellar mint is eligible for a renewal proof. This flag does not authorize replacement or submission; POST /transaction/renew must still verify chain evidence."
          },
          "approvalRenewalEnabled": {
            "type": "boolean",
            "description": "The current expired Stellar CCTP approval (or legacy approval-reset) with no included receipt is eligible for a renewal proof at POST /transaction/renew. This flag does not authorize replacement, signing or submission; renewal must still verify ledger expiry, an absent receipt and an unused wallet sequence."
          },
          "sourceRenewalEnabled": {
            "type": "boolean",
            "description": "Current expired unsigned Stellar burn or transfer may request a proof-gated replacement on the same payment and wallet sequence. Requires fresh terms and a new signature; signed source actions cannot renew."
          },
          "closeEnabled": {
            "type": "boolean",
            "description": "The current standalone action is eligible to request safe closure. Stellar closure requires the documented expired-envelope nonexecution evidence. An unsigned EVM action becomes eligible only after its review expires and then requires the hash of a finalized wallet transaction that consumed its saved nonce (see closureRequirement). It is never eligible when the payment cannot be searched by sender for the same payment at another nonce (SwapKit native deposits, an undecodable payment call), or when evidence that the payment may have executed is saved in lastError. Eligibility alone is not proof that closure will pass."
          },
          "closure": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "closedAt": {
                "type": "string",
                "format": "date-time"
              },
              "proof": {
                "type": "object",
                "description": "Saved closure evidence. EVM proofs carry proofType 'self-cancellation', 'nonce-consumed' or 'manual-attestation' (closed in the dashboard after a member's manual check; nonceProofType names the verified nonce proof, equivalentScan.status is 'unsupported' or 'incomplete' with Route's reason, and attestation records the member, session, time, reason and statement; Route did not verify the manual check), the consuming transaction hash, sender, nonce, chain, block and finalized block; nonce-consumed proofs also record transactionTo and whether the transaction succeeded. equivalentScan records the search for the same payment at other nonces: status 'clear' with the provider, searched contract (and token for Allbridge) and sender, identityRevealedAt, fromBlock (at or before the payment was first revealed), toBlock (at or after the finalized block) and checkedAt, or 'not-required' for approvals. attributedTransactions lists matching transactions that Route already saved for another of the project's payments; resumedAfterBlock is present when the search continued from progress saved by an earlier attempt."
              }
            },
            "required": [
              "closedAt",
              "proof"
            ]
          },
          "submissionStartedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Recorded Route submission attempt time. A missing value does not prove that a signed transaction was never broadcast elsewhere."
          },
          "cancellation": {
            "type": [
              "object",
              "null"
            ],
            "description": "Finalized intermediate source cancellation proof. Original signature/hash records remain saved; this action must not be sent again."
          },
          "sourceRecovery": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/BitcoinSourceRecoveryProof"
              }
            ]
          },
          "manualCloseEnabled": {
            "type": "boolean",
            "description": "True for every expired, unsigned EVM burn or transfer: a signed-in workspace member may use the dashboard's close after manual check. Route runs its own search first and closes on its own proof when that search completes; the member's attestation closes the payment only when Route cannot search the wallet for the same payment at another nonce or its search cannot complete. The finalized nonce proof and recorded-evidence refusals still apply. Not available to API keys; Route does not verify the manual check."
          },
          "closureRequirement": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "finalized-nonce-cancellation",
              null
            ],
            "description": "For unsigned EVM closure, supply cancellationHash proving the saved nonce was consumed by a finalized transaction from the same wallet: a zero-value self-transfer, or another transaction that does not send this payment or touch its provider. Route does not create or submit that transaction."
          }
        },
        "required": [
          "object",
          "authorization",
          "id",
          "kind",
          "transaction",
          "state",
          "expiresAt",
          "signingEnabled",
          "submissionEnabled",
          "executionEnabled",
          "canContinue"
        ]
      },
      "ProtocolPreparation": {
        "type": "object",
        "description": "Protocol payment preparation, no NEAR deposit address or intent approval. Includes direct Rift orders: deposit.contracts.riftDeposit retains the REST order and accepted intent. Internal minimumReceived \"0\" means no guarantee and must not be shown as a protected minimum. Use the saved quote estimate and minimumOutputGuaranteed:false.",
        "properties": {
          "object": {
            "const": "payment_preparation"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "adapter": {
            "enum": [
              "circle",
              "allbridge",
              "layerzero",
              "axelar",
              "swapkit",
              "rift"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "intent": {
            "type": "object"
          },
          "deposit": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "kind": {
                    "const": "protocol"
                  }
                }
              },
              {
                "type": "null"
              }
            ],
            "description": "Null only while a SwapKit preparation (state preparing, or needs-review with lastError after a failed attempt) holds its credit and API-key budget reservations and its deposit channel is not yet attached. Resume it with the same payment intent while providerAllocation.expiresAt is in the future; Route does not build another channel. Rift may also retain a reserved preparation while order allocation is unresolved; only the same quote and wallet terms may be resumed."
          },
          "transaction": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ProtocolTransaction"
              },
              {
                "type": "null"
              }
            ]
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProtocolTransaction"
            }
          },
          "nextAction": {
            "$ref": "#/components/schemas/ProtocolNextAction"
          },
          "readiness": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProtocolReadiness"
              },
              {
                "type": "object",
                "description": "A SwapKit preparation without deposit instructions has no wallet assessment yet. Its preparation-pending blocker stops funding until the deposit is attached.",
                "required": [
                  "blockers",
                  "executionEnabled"
                ],
                "properties": {
                  "blockers": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PaymentCheck"
                    }
                  },
                  "executionEnabled": {
                    "type": "boolean"
                  }
                }
              }
            ]
          },
          "tracking": {
            "$ref": "#/components/schemas/ProtocolTracking"
          },
          "executionEnabled": {
            "type": "boolean"
          },
          "destinationExecution": {
            "type": [
              "object",
              "null"
            ],
            "description": "Managed Circle-to-Stellar delivery. A relay submission is not proof of settlement. `failed` (Channels reported the relay failed or expired, or replaced it more than 16 times) and `submission-unknown` (no saved Channels relay ID, so Route cannot poll the attempt) require review. `lastError` holds the saved relay evidence. When `lastError.retryAllowed` is true, Route re-mints the same saved call once automatically after `lastError.remintAfter`, only while the CCTP nonce is unused at a fresh Stellar ledger and the call still simulates without new authorization; there is no second automatic re-mint. A message minted by a relay Route did not record stays in review with `lastError.code` `DESTINATION_MINTED_UNRECORDED`.",
            "properties": {
              "mode": {
                "const": "managed"
              },
              "provider": {
                "const": "openzeppelin-channels"
              },
              "state": {
                "type": "string",
                "enum": [
                  "waiting-for-source",
                  "paused",
                  "submitting",
                  "submitted",
                  "submission-unknown",
                  "failed",
                  "completed",
                  "cancelled"
                ]
              },
              "transactionHash": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Latest relay hash reported by Channels for the current relay attempt; tracking verifies this hash."
              },
              "relayHashes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[a-f0-9]{64}$"
                },
                "description": "Present only after Channels resubmitted the relay under a new hash: every reported hash, oldest (the first saved hash) first. Route verifies the latest one."
              },
              "relayAttempts": {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "type": "object",
                  "properties": {
                    "attempt": {
                      "type": "integer"
                    },
                    "transactionId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "relayHashes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "pattern": "^[a-f0-9]{64}$"
                      }
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "submission-unknown",
                        "failed"
                      ]
                    },
                    "lastError": {
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "attemptedAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "remintedAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    }
                  }
                },
                "description": "Present only after Route's single automatic re-mint: the earlier relay attempt it replaced, with its Channels relay ID, every hash Channels reported, its state and saved evidence. Completion follows whichever recorded relay minted the message."
              },
              "customerSignatureRequired": {
                "const": false
              },
              "customerFee": {
                "type": "object",
                "properties": {
                  "amount": {
                    "const": "0"
                  },
                  "currency": {
                    "const": "XLM"
                  }
                }
              },
              "lastError": {
                "type": [
                  "object",
                  "null"
                ]
              }
            },
            "additionalProperties": true
          },
          "network": {
            "const": "mainnet"
          },
          "state": {
            "type": "string",
            "enum": [
              "preparing",
              "prepared",
              "needs-review"
            ]
          },
          "walletApproval": {
            "type": "object",
            "properties": {
              "required": {
                "const": false
              },
              "method": {
                "const": "transaction-signature"
              }
            },
            "required": [
              "required",
              "method"
            ]
          }
        },
        "required": [
          "object",
          "id",
          "adapter",
          "version",
          "deposit",
          "actions",
          "nextAction",
          "readiness"
        ]
      },
      "ComposedPrepare": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version",
          "sender",
          "recipient"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "sender": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "intermediate": {
            "type": "string",
            "description": "Customer-controlled EVM wallet on the route’s intermediate network, required for two legs. For BTC → Base USDC → Stellar USDC, supply a Base wallet with ETH for approval/transfer fees. Missing or invalid addresses return INVALID_INTERMEDIATE_WALLETS with details.field=intermediate and details.network=base."
          },
          "refundTo": {
            "type": "string"
          },
          "minimumReceived": {
            "type": "string"
          },
          "slippageBps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 10,
            "description": "Defaults to the saved NEAR leg’s tolerance. A new preparation must match it; refreshed NEAR legs preserve it."
          },
          "intermediates": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "items": {
              "type": "string"
            },
            "description": "Customer-controlled wallets in composition.intermediates order, required for three legs. Each needs ETH on its own network. Invalid addresses return INVALID_INTERMEDIATE_WALLETS with details.field identifying the position (for example intermediates[0]) and details.network."
          }
        },
        "oneOf": [
          {
            "required": [
              "intermediate"
            ],
            "not": {
              "required": [
                "intermediates"
              ]
            }
          },
          {
            "required": [
              "intermediates"
            ],
            "not": {
              "required": [
                "intermediate"
              ]
            }
          }
        ]
      },
      "ComposedPayment": {
        "type": "object",
        "required": [
          "object",
          "id",
          "legs",
          "nextAction",
          "completed"
        ],
        "properties": {
          "object": {
            "const": "composed_payment"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "state": {
            "type": "string"
          },
          "atomic": {
            "const": false
          },
          "completed": {
            "type": "boolean"
          },
          "activePaymentId": {
            "type": "string",
            "format": "uuid"
          },
          "minimumReceived": {
            "type": "string"
          },
          "nextAction": {
            "type": "string",
            "enum": [
              "completed",
              "advance",
              "prepare",
              "continue-leg",
              "retry-refund",
              "retry-cancellation",
              "review-required",
              "cancelled"
            ]
          },
          "wallets": {
            "type": "object"
          },
          "legs": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "minItems": 1,
            "maxItems": 3
          },
          "recovery": {
            "type": "object",
            "properties": {
              "intermediates": {
                "type": "array",
                "maxItems": 2,
                "items": {
                  "$ref": "#/components/schemas/ComposedIntermediateReceipt"
                }
              },
              "preview": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "automaticResend": {
                "const": false
              },
              "attempts": {
                "type": "array",
                "maxItems": 7,
                "description": "Immutable child-attempt history. legs contains only the latest attempt for each route step.",
                "items": {
                  "type": "object",
                  "properties": {
                    "leg": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 3
                    },
                    "attempt": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 3
                    },
                    "paymentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "preparationId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "resumesPaymentId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "refundEvidence": {
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "tracking": {
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "expectedLegs": {
            "type": "integer",
            "enum": [
              2,
              3
            ]
          },
          "paymentState": {
            "$ref": "#/components/schemas/PaymentState"
          }
        }
      },
      "NearPreparationRecovery": {
        "type": "object",
        "description": "Read-only provider observation for a signed minimum-output rejection. Does not cancel a deposit address, release budget reservations or authorize funding. Fresh quotes and new payments require an explicit client decision. Not supported for a composed child.",
        "properties": {
          "state": {
            "enum": [
              "unfunded-rejected-quote",
              "funding-observed"
            ]
          },
          "canRequote": {
            "type": "boolean",
            "description": "True only when the signed provider status reports PENDING_DEPOSIT without funding/transfer evidence and Route has issued no funding instructions or wallet action. Observation at observedAt, not a guarantee against future external funding."
          },
          "nextAction": {
            "enum": [
              "requote",
              "contact-support"
            ]
          },
          "automaticRetry": {
            "const": false
          },
          "providerStatus": {
            "type": "string"
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "quoteHash": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "state",
          "canRequote",
          "nextAction",
          "automaticRetry",
          "providerStatus",
          "observedAt",
          "quoteHash",
          "message"
        ]
      },
      "DepositReview": {
        "type": "object",
        "required": [
          "object",
          "id",
          "preparationId",
          "version",
          "expiresAt",
          "walletApproval",
          "transaction",
          "nextAction"
        ],
        "properties": {
          "object": {
            "const": "deposit_review"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "preparationId": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "walletApproval": {
            "$ref": "#/components/schemas/WalletIntentApproval"
          },
          "transaction": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NearPaymentTransaction"
              },
              {
                "type": "null"
              }
            ]
          },
          "nextAction": {
            "const": "approve-wallet-intent"
          }
        }
      },
      "GardenCredentialUpdate": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "credential": {
            "type": "string",
            "writeOnly": true,
            "minLength": 16,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$",
            "description": "Garden App ID. Sent upstream as garden-app-id. Stored encrypted and never returned."
          }
        },
        "required": [
          "version",
          "credential"
        ],
        "additionalProperties": false
      },
      "ProviderConnection": {
        "type": "object",
        "properties": {
          "adapter": {
            "type": "string",
            "enum": [
              "allbridge",
              "circle",
              "near",
              "layerzero",
              "axelar",
              "garden",
              "swapkit",
              "rift"
            ]
          },
          "enabled": {
            "type": "boolean",
            "description": "Effective enablement: false during a platform pause, even if configuredEnabled is true."
          },
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "credential_source": {
            "type": "string",
            "enum": [
              "customer",
              "route"
            ],
            "description": "Explicit credential source for NEAR, Garden or SwapKit. Not applicable to providers without credentials."
          },
          "credential_present": {
            "type": "boolean",
            "description": "Whether the selected connection has a configured credential."
          },
          "customer_credential_present": {
            "type": "boolean",
            "description": "Whether a customer credential is stored, including while Route mode is selected."
          },
          "checked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "check_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "platformAvailability": {
            "$ref": "#/components/schemas/ProviderAvailability"
          },
          "configuredEnabled": {
            "type": "boolean",
            "description": "Owner preference retained while a platform pause makes enabled false."
          }
        },
        "required": [
          "adapter",
          "enabled",
          "version",
          "credential_source",
          "credential_present",
          "customer_credential_present",
          "checked_at",
          "check_status"
        ]
      },
      "SwapKitCredentialUpdate": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "credential": {
            "type": "string",
            "writeOnly": true,
            "minLength": 16,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$",
            "description": "Your SwapKit API key. Write-only; stored encrypted for the project."
          }
        },
        "required": [
          "version",
          "credential"
        ],
        "additionalProperties": false
      },
      "AutoRouteOptions": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "intent"
        ],
        "properties": {
          "intent": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "Optimization preference sent to TypeSafe with bounded public quote summaries. Exact assets, amount and owner/key limits remain authoritative. Do not include secrets or personal information."
          },
          "intermediateAssetIds": {
            "type": "array",
            "maxItems": 2,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "maxLength": 250
            },
            "description": "Optional verified catalog assets on networks distinct from both endpoints. Omit for up to two native-USDC intermediates chosen from Base, Arbitrum and Ethereum. Empty means direct paths only."
          },
          "maxLegs": {
            "type": "integer",
            "enum": [
              2,
              3
            ],
            "default": 2,
            "description": "Opt into three-leg search across both ordered intermediate pairs. Defaults to two legs."
          },
          "requoteSlippageBps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 0,
            "description": "Explicit extra tolerance below the final quoted minimum for multi-step routes, in basis points. Applied once to the route, in addition to provider slippage. The resulting minimum is saved at preparation and never reduced on refresh. Direct routes are unchanged."
          }
        }
      },
      "AutoRouteEvaluation": {
        "type": "object",
        "required": [
          "version",
          "model",
          "objective",
          "confidence",
          "creditMultiplier",
          "search",
          "selectedCandidateId"
        ],
        "properties": {
          "version": {
            "const": "auto-route-v1"
          },
          "model": {
            "type": "string"
          },
          "objective": {
            "enum": [
              "cost",
              "speed",
              "return",
              "balanced"
            ]
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Intent interpretation confidence, not a probability of payment success."
          },
          "creditMultiplier": {
            "const": 4
          },
          "probabilities": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            },
            "description": "Optional evaluation evidence returned with view=full."
          },
          "intent": {
            "type": "string",
            "description": "Optional evaluation evidence returned with view=full."
          },
          "interpretedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Optional evaluation evidence returned with view=full."
          },
          "ranking": {
            "const": "deterministic"
          },
          "selectedCandidateId": {
            "type": [
              "string",
              "null"
            ]
          },
          "authorizationRequired": {
            "const": true
          },
          "search": {
            "type": "object",
            "properties": {
              "maxLegs": {
                "enum": [
                  2,
                  3
                ]
              },
              "intermediateAssetIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "firstLegsPerIntermediate": {
                "const": 3
              },
              "exhaustive": {
                "const": false
              },
              "complete": {
                "type": "boolean",
                "description": "False when a provider could not quote at least one searched intermediate leg, or a leg request failed; composed paths through that leg were not compared. Pairs a provider does not support, paused providers, unavailable providers that a matching provider rule excludes, and legs excluded by provider rules, API-key restrictions or provider coverage do not make the search incomplete. Older saved comparisons may omit this field."
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Intermediate search outcomes: unavailable provider quotes with the provider's reason, failed leg requests, missing intermediate USD prices, legs excluded by provider rules, API-key restrictions or provider coverage, and a three-step request that had only one intermediate."
              },
              "secondLegsPerFirst": {
                "type": [
                  "integer",
                  "null"
                ],
                "enum": [
                  1,
                  null
                ],
                "description": "1 when three-step paths were searched; otherwise null, including a three-step request with only one intermediate asset. Older saved comparisons may show 1 in that case."
              }
            }
          },
          "evidenceVersion": {
            "type": "string",
            "enum": [
              "route-evidence-v3",
              "route-evidence-v4"
            ],
            "description": "Optional evaluation evidence returned with view=full. Version of the bounded evidence shared with TypeSafe. Older saved evaluations may omit this field."
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArrivalWarning"
            },
            "description": "Present for speed and balanced preferences. Older saved evaluations may omit this field."
          }
        },
        "description": "Intent interpretation and deterministic selection for Auto-route. The compact view retains required evaluation fields, objective, search bounds/completeness, selection and warnings. Optional detailed evaluation evidence is available with view=full."
      },
      "QuotePreparation": {
        "type": "object",
        "description": "Quote-stage preparation eligibility. This never authorizes a signature or funds a payment. Older saved observations may omit this field.",
        "properties": {
          "eligible": {
            "type": "boolean",
            "description": "All quote checks pass, or only classified source gas remains unresolved with all required USD prices available."
          },
          "enabled": {
            "type": "boolean",
            "description": "Live quote projection: eligible, unexpired and supported by an enabled execution builder. Omitted in stored draft snapshots."
          },
          "deferredChecks": {
            "type": "array",
            "items": {
              "enum": [
                "source-gas"
              ]
            }
          },
          "reason": {
            "type": "string"
          }
        },
        "required": [
          "eligible",
          "deferredChecks",
          "reason"
        ]
      },
      "ProtocolAction": {
        "type": "object",
        "description": "Exact unsigned protocol action. context is provider-specific evidence; do not use it to reconstruct or modify the transaction.",
        "required": [
          "kind",
          "network",
          "family",
          "sender",
          "nonce",
          "expiresAt",
          "feeMinor",
          "feeCurrency",
          "transaction",
          "context"
        ],
        "properties": {
          "kind": {
            "enum": [
              "approval-reset",
              "approval",
              "burn",
              "transfer",
              "mint"
            ]
          },
          "network": {
            "type": "string"
          },
          "family": {
            "enum": [
              "evm",
              "stellar",
              "bitcoin"
            ]
          },
          "sender": {
            "type": "string"
          },
          "nonce": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "feeMinor": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "feeCurrency": {
            "enum": [
              "ETH",
              "XLM",
              "BTC"
            ]
          },
          "context": {
            "type": "object"
          },
          "transaction": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ProtocolEvmPayload"
              },
              {
                "$ref": "#/components/schemas/ProtocolStellarPayload"
              },
              {
                "$ref": "#/components/schemas/ProtocolBitcoinPayload"
              }
            ]
          },
          "psbt": {
            "type": "string",
            "description": "Bitcoin only: base64 PSBT, also present in the nested transaction payload. Sign without modifying the input/output plan."
          },
          "inputs": {
            "type": "array",
            "description": "Bitcoin only: the inputs from the nested transaction payload.",
            "items": {
              "type": "object"
            }
          },
          "submissionStartedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ProtocolEvmPayload": {
        "type": "object",
        "description": "Sign this exact EIP-155 legacy payload; hexadecimal RPC quantities remain strings.",
        "required": [
          "from",
          "to",
          "data",
          "value",
          "chainId",
          "nonce",
          "gas",
          "gasPrice"
        ],
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "data": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "chainId": {
            "type": "string"
          },
          "nonce": {
            "type": "string"
          },
          "gas": {
            "type": "string"
          },
          "gasPrice": {
            "type": "string"
          }
        }
      },
      "ProtocolStellarPayload": {
        "type": "object",
        "required": [
          "xdr",
          "networkPassphrase",
          "hash"
        ],
        "properties": {
          "xdr": {
            "type": "string"
          },
          "networkPassphrase": {
            "type": "string"
          },
          "hash": {
            "type": "string"
          }
        }
      },
      "ProtocolAssessment": {
        "type": "object",
        "description": "Saved observation, not a continuous guarantee. Rechecked before signature acceptance and submission. All required current checks must pass; approvalOnly assessments cover permission costs separately from transfer costs. Older immutable assessments may omit the later approvalOnly and notice fields; treat absent metadata as unknown.",
        "required": [
          "checkedAt",
          "expiresAt",
          "walletReady",
          "executionEnabled",
          "checks",
          "policyChecks",
          "blockers",
          "valuation",
          "costComplete",
          "estimatedCostUsd",
          "eta",
          "unsignedTransaction"
        ],
        "properties": {
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "walletReady": {
            "type": "boolean"
          },
          "executionEnabled": {
            "type": "boolean"
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentCheck"
            }
          },
          "policyChecks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentCheck"
            }
          },
          "blockers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentCheck"
            }
          },
          "valuation": {
            "$ref": "#/components/schemas/UsdValuation"
          },
          "costComplete": {
            "type": "boolean"
          },
          "estimatedCostUsd": {
            "type": [
              "string",
              "null"
            ]
          },
          "eta": {
            "$ref": "#/components/schemas/QuoteEta"
          },
          "unsignedTransaction": {
            "$ref": "#/components/schemas/ProtocolAction"
          },
          "approvalOnly": {
            "type": "boolean"
          },
          "notice": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ProtocolReadiness": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ProtocolAssessment"
          }
        ],
        "description": "Assessment plus live preparation blockers and the service execution switch. executionEnabled alone does not mean all checks passed. Read the current transaction flags and blockers."
      },
      "ProtocolNextAction": {
        "type": "string",
        "enum": [
          "completed",
          "track",
          "refresh-approval-review",
          "sign",
          "submit",
          "prepare-mint",
          "prepare-transaction",
          "confirm-wallet-broadcast",
          "cancelled",
          "renew-mint",
          "renew-approval",
          "close-payment",
          "review-required",
          "refresh-source-review",
          "renew-source",
          "close-payment"
        ],
        "description": "Current mainnet protocol hints. Honor state, flags, checks and expiry. New future values must pause automated signing/submission; preserve IDs and continue safe reads rather than guessing. Testnet uses a different nextStep/action-object contract."
      },
      "ProtocolReceipt": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "network": {
            "type": "string"
          },
          "hash": {
            "type": "string"
          },
          "included": {
            "type": "boolean"
          },
          "finalized": {
            "type": "boolean"
          },
          "successful": {
            "type": "boolean"
          },
          "feeMinor": {
            "type": [
              "string",
              "null"
            ]
          },
          "includedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "submissionObservation": {
            "$ref": "#/components/schemas/StellarSubmissionObservation"
          },
          "sourceSubmissionObservation": {
            "$ref": "#/components/schemas/SourceSubmissionObservation"
          }
        },
        "required": [
          "network",
          "hash",
          "included",
          "finalized",
          "successful"
        ],
        "description": "Saved verified receipt evidence. An approval may allow continuation before finality; payment transfers retain their finality rules. A Stellar transaction the wallet submitted outside Route, adopted after a renewal or close check found it, is saved with included true and finalized false until tracking attaches its verified evidence."
      },
      "ProtocolTracking": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "status": {
            "type": "string"
          },
          "sourceVerified": {
            "type": "boolean"
          },
          "sourceFinalized": {
            "type": "boolean"
          },
          "destinationVerified": {
            "type": "boolean"
          },
          "destinationFinalized": {
            "type": "boolean"
          },
          "completed": {
            "type": "boolean"
          },
          "sourceHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "destinationHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "sourceSubmissionObservation": {
            "$ref": "#/components/schemas/SourceSubmissionObservation"
          },
          "refundHash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Refund transaction on the source network once status is refunded."
          },
          "refundVerified": {
            "type": "boolean"
          },
          "refundFinalized": {
            "type": "boolean"
          },
          "refundConfirmation": {
            "$ref": "#/components/schemas/ManualRefundConfirmation"
          },
          "providerStatus": {
            "type": "string",
            "enum": [
              "awaiting_deposit",
              "funded",
              "underfunded",
              "expired",
              "executing",
              "delivered",
              "refunded",
              "frozen"
            ],
            "description": "Rift REST provider status. Delivered/refunded alone do not establish independent chain settlement."
          },
          "verification": {
            "type": "string",
            "enum": [
              "pending",
              "independent-chain"
            ]
          },
          "providerReportedAmountMinor": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "description": "Rift reported atomic amount: destination token for delivered, source token for refunded. Provider report only."
          }
        },
        "description": "Evidence fields are optional until observed. Missing means not established, never true. completed requires the payment-specific verified source and destination finality checks. Other provider-specific evidence may also appear. status closed is terminal: a proof-gated Stellar closure proved the current action can never execute and closed the payment, so no receipt is awaited. Rift provider delivery/refund without independently attributed finalized chain evidence remains verification-pending."
      },
      "PaymentNextAction": {
        "type": "object",
        "required": [
          "object",
          "schemaVersion",
          "network",
          "paymentId",
          "activePaymentId",
          "flow",
          "adapter",
          "paymentVersion",
          "preparationVersion",
          "authorizationId",
          "observedAt",
          "status",
          "expiresAt",
          "action",
          "checks",
          "blockers",
          "tracking",
          "links",
          "notice"
        ],
        "properties": {
          "object": {
            "const": "payment_next_action"
          },
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "network": {
            "const": "mainnet"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "activePaymentId": {
            "type": "string",
            "format": "uuid",
            "description": "For a composed workflow, the currently active child payment; otherwise paymentId."
          },
          "flow": {
            "type": "string",
            "enum": [
              "near",
              "protocol",
              "testnet",
              "composed"
            ]
          },
          "adapter": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentVersion": {
            "type": "integer",
            "minimum": 1
          },
          "preparationVersion": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "authorizationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "$ref": "#/components/schemas/PaymentState"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Current relevant review or quote deadline, when present. Expiry does not undo a broadcast or invalidate signed EVM bytes on-chain."
          },
          "action": {
            "$ref": "#/components/schemas/PaymentNextStep"
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Saved checks in their existing flow-specific shape. Empty does not establish fresh wallet or fee readiness."
          },
          "blockers": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Saved blockers in their existing flow-specific shape; action may still require review for expiry, unknown state or unavailable execution."
          },
          "tracking": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Saved flow-specific settlement evidence. No provider/chain refresh is performed by reading this projection."
          },
          "links": {
            "type": "object",
            "required": [
              "payment",
              "nextAction"
            ],
            "properties": {
              "payment": {
                "type": "string"
              },
              "nextAction": {
                "type": "string"
              }
            }
          },
          "notice": {
            "type": "string"
          }
        },
        "description": "Observational projection of the existing payment. Does not authorize a signature, reserve liquidity, retry an operation, or prove current chain state. Every mutation revalidates its own evidence. Preserve the existing payment on an uncertain outcome."
      },
      "PaymentNextStep": {
        "type": "object",
        "required": [
          "type",
          "actor",
          "message",
          "operation",
          "payload"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "prepare-payment",
              "request-intent-approval",
              "sign-intent",
              "prepare-transaction",
              "sign-transaction",
              "submit-transaction",
              "refresh-review",
              "track",
              "continue-leg",
              "advance",
              "reconcile",
              "completed",
              "refunded",
              "cancelled",
              "review-required",
              "confirm-wallet-broadcast",
              "renew-mint",
              "renew-approval",
              "close-payment",
              "renew-source"
            ],
            "description": "Unknown future action types must pause automatic signing and submission; update the integration before continuing."
          },
          "actor": {
            "type": "string",
            "enum": [
              "app",
              "wallet",
              "operator",
              "none"
            ],
            "description": "The party responsible for the next step. wallet requires separately authorized sign-only handling; operator requires review."
          },
          "message": {
            "type": "string"
          },
          "operation": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PaymentNextOperation"
              },
              {
                "type": "null"
              }
            ]
          },
          "payload": {
            "description": "Wallet review/signing payload only when applicable; otherwise null. Flow-specific challenge or unsigned transaction, not a private key or saved signed transaction. Preserve and independently review its exact contents."
          },
          "walletRequirements": {
            "type": "array",
            "description": "Optional address requirements on the initial unprepared composed prepare-payment action only. Collect these public addresses as payment intent fields; intermediate wallets must be customer-controlled and funded with ETH. The operation retains requiredInput=[paymentIntent], body={version} and payload=null. This metadata does not authorize signing or funding.",
            "minItems": 3,
            "maxItems": 4,
            "items": {
              "$ref": "#/components/schemas/PaymentWalletRequirement"
            },
            "example": [
              {
                "field": "sender",
                "network": "btc"
              },
              {
                "field": "recipient",
                "network": "stellar"
              },
              {
                "field": "intermediate",
                "network": "base"
              }
            ]
          }
        }
      },
      "PaymentNextOperation": {
        "type": "object",
        "required": [
          "method",
          "path",
          "body",
          "idempotencyKeyRequired",
          "requiredInput"
        ],
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "GET",
              "POST"
            ]
          },
          "path": {
            "type": "string",
            "pattern": "^/v1/payments/",
            "description": "Origin-relative Route endpoint, including /v1. Use the trusted Route API origin; do not prepend /v1 a second time or follow arbitrary hosts."
          },
          "body": {
            "type": "object",
            "additionalProperties": true,
            "description": "Saved-state request fields such as the correct version or authorizationId. Supplement only the listed required inputs for this action; never overwrite these identities."
          },
          "idempotencyKeyRequired": {
            "type": "boolean",
            "description": "When true, persist a new UUID for this logical operation before the request. Reuse it and the identical body after a lost response. It does not grant authority to run the operation."
          },
          "requiredInput": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true,
            "description": "Missing caller inputs, such as paymentIntent, signature or signedTransaction. An empty list does not mean a signature or submission is preauthorized."
          }
        }
      },
      "BitcoinSettlementDiscrepancy": {
        "type": "object",
        "required": [
          "code",
          "network",
          "purpose",
          "transactionHash",
          "providerReportedAmountMinor",
          "observedRecipientAmountMinor",
          "differenceMinor",
          "minimumAmountMinor",
          "meetsMinimum",
          "finalized",
          "confirmations",
          "blockHeight",
          "blockHash"
        ],
        "properties": {
          "code": {
            "const": "BITCOIN_SETTLEMENT_AMOUNT_MISMATCH"
          },
          "network": {
            "const": "btc"
          },
          "purpose": {
            "type": "string",
            "enum": [
              "delivery",
              "refund"
            ]
          },
          "transactionHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "providerReportedAmountMinor": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "observedRecipientAmountMinor": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "differenceMinor": {
            "type": "string",
            "pattern": "^-?[0-9]+$"
          },
          "minimumAmountMinor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$"
          },
          "meetsMinimum": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "finalized": {
            "type": "boolean"
          },
          "confirmations": {
            "type": "integer",
            "minimum": 1
          },
          "blockHeight": {
            "type": "integer",
            "minimum": 0
          },
          "blockHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          }
        },
        "description": "Canonical recipient net credit differs from the provider-reported settlement amount, in satoshis. Diagnostic evidence only; no payment-specific allocation is established and completion/refund remains unverified. Minimum fields are null for refunds. A larger output does not establish a safe automatic completion rule."
      },
      "RecoveryStage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "network",
          "hash",
          "verified",
          "finalized",
          "includedAt"
        ],
        "properties": {
          "network": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9_-]{1,64}$"
          },
          "hash": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9:_-]{1,128}$"
          },
          "verified": {
            "type": "boolean"
          },
          "finalized": {
            "type": "boolean"
          },
          "includedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "Saved funding, delivery or refund evidence. A hash alone does not prove submission; verified and finalized are distinct."
      },
      "RecoveryReceipt": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "observed",
          "included",
          "successful",
          "finalized"
        ],
        "properties": {
          "observed": {
            "type": "boolean"
          },
          "included": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "successful": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "finalized": {
            "type": [
              "boolean",
              "null"
            ]
          }
        },
        "description": "Observed means this saved transaction view includes a receipt observation. Null flags mean unavailable evidence, not false. Separate verified tracking may exist even when this receipt is unobserved."
      },
      "RecoveryTransaction": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "network",
          "state",
          "hash",
          "submissionAttempted",
          "receipt",
          "expiresAt",
          "reviewExpired"
        ],
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "approval",
              "approval-reset",
              "burn",
              "transfer",
              "mint",
              "deposit",
              "unknown"
            ]
          },
          "network": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9_-]{1,64}$"
          },
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "signed",
              "submitting",
              "submitted",
              "submission-unknown",
              "expired",
              "unknown",
              "cancelled"
            ]
          },
          "hash": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9:_-]{1,128}$",
            "description": "The saved transaction hash. For a never-signed Stellar action with a recorded submissionObservation, the saved envelope hash that observation is bound to; a Stellar hash excludes signatures, so it is also the landed hash if a wallet broadcast the action. A hash alone does not prove submission."
          },
          "submissionAttempted": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "receipt": {
            "$ref": "#/components/schemas/RecoveryReceipt"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "reviewExpired": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "submissionObservation": {
            "$ref": "#/components/schemas/StellarSubmissionObservation"
          },
          "sourceSubmissionObservation": {
            "$ref": "#/components/schemas/SourceSubmissionObservation"
          }
        },
        "description": "An allowlisted saved action summary. No unsigned payload, signing challenge, signature or signed transaction bytes are included. Testnet exposes its latest saved action; this is not a complete historical action ledger."
      },
      "RecoveryDiscrepancy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "network",
          "purpose",
          "transactionHash",
          "providerReportedAmountMinor",
          "observedRecipientAmountMinor",
          "differenceMinor",
          "minimumAmountMinor",
          "meetsMinimum",
          "finalized",
          "confirmations",
          "blockHeight",
          "blockHash"
        ],
        "properties": {
          "code": {
            "enum": [
              "BITCOIN_SETTLEMENT_AMOUNT_MISMATCH",
              "TRON_SETTLEMENT_AMOUNT_MISMATCH"
            ]
          },
          "network": {
            "enum": [
              "btc",
              "tron"
            ]
          },
          "purpose": {
            "type": "string",
            "enum": [
              "delivery",
              "refund"
            ]
          },
          "transactionHash": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9:_-]{1,128}$"
          },
          "providerReportedAmountMinor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{1,78}$"
          },
          "observedRecipientAmountMinor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{1,78}$"
          },
          "differenceMinor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^-?\\d{1,78}$"
          },
          "minimumAmountMinor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{1,78}$"
          },
          "meetsMinimum": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "finalized": {
            "type": "boolean"
          },
          "confirmations": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "blockHeight": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "blockHash": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9:_-]{1,128}$"
          }
        },
        "description": "BTC values are satoshis encoded as decimal strings. Meeting a minimum does not prove which payment owns a larger payout. Exact provider-to-chain attribution remains required.",
        "oneOf": [
          {
            "properties": {
              "code": {
                "const": "BITCOIN_SETTLEMENT_AMOUNT_MISMATCH"
              },
              "network": {
                "const": "btc"
              }
            }
          },
          {
            "properties": {
              "code": {
                "const": "TRON_SETTLEMENT_AMOUNT_MISMATCH"
              },
              "network": {
                "const": "tron"
              }
            }
          }
        ]
      },
      "RecoveryWalletReservation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "kind",
          "authorizationId",
          "network",
          "sender",
          "nonce",
          "transactionHash",
          "outputIndex"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "sequence",
              "bitcoin-input",
              "utxo-input"
            ]
          },
          "authorizationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "network": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9_-]{1,64}$"
          },
          "sender": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9:_-]{1,128}$"
          },
          "nonce": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{1,78}$"
          },
          "transactionHash": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-zA-Z0-9:_-]{1,128}$"
          },
          "outputIndex": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          }
        },
        "description": "Saved wallet sequence or reserved Bitcoin input; transactionHash/outputIndex identify a reserved input outpoint, not a completed payout."
      },
      "RecoveryApiLimitReservation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "apiKeyId",
          "preparationId",
          "amountUsd",
          "state",
          "reservedAt",
          "committedAt"
        ],
        "properties": {
          "apiKeyId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "preparationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "amountUsd": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{1,78}(\\.\\d{1,42})?$"
          },
          "state": {
            "type": "string",
            "enum": [
              "reserved",
              "committed",
              "unknown",
              "released"
            ]
          },
          "reservedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "committedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "API-key spending-limit accounting. apiKeyId is a public record identifier, never the secret key. A committed source amount is not proof of destination delivery."
      },
      "RecoveryCreditReservation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "paymentId",
          "credits",
          "state",
          "updatedAt"
        ],
        "properties": {
          "paymentId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "credits": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{1,78}$"
          },
          "state": {
            "type": "string",
            "enum": [
              "reserved",
              "charged",
              "released",
              "unknown"
            ]
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "Route usage-credit accounting; separate from payment value and chain fees."
      },
      "RecoverySafety": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "automaticReplacementAllowed",
          "reservationReleaseAllowed"
        ],
        "properties": {
          "automaticReplacementAllowed": {
            "type": "boolean",
            "const": false
          },
          "reservationReleaseAllowed": {
            "type": "boolean",
            "const": false
          }
        },
        "description": "This report cannot authorize payment replacement or release wallet, spending-limit or credit reservations."
      },
      "RecoveryOperation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "method",
          "path",
          "body",
          "idempotencyKeyRequired",
          "requiredInput"
        ],
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "GET",
              "POST"
            ]
          },
          "path": {
            "type": "string",
            "pattern": "^/v1/payments/[a-fA-F0-9-]{36}/(prepare|wallet-approval(/confirm)?|transaction(/signature|/review|/renew|/close|/broadcast-confirm)?|execute|refresh|next-action|advance|reconcile)$",
            "description": "Reference to the root or active payment. Validate the returned payment identity and use the trusted Route origin; never execute from this report alone."
          },
          "body": {
            "type": "object",
            "additionalProperties": false,
            "required": [],
            "properties": {
              "version": {
                "type": "integer",
                "minimum": 1
              },
              "authorizationId": {
                "type": "string",
                "format": "uuid"
              },
              "approvalId": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          "idempotencyKeyRequired": {
            "type": "boolean"
          },
          "requiredInput": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "paymentIntent",
                "signedTransaction",
                "signature",
                "transactionHash"
              ]
            }
          }
        },
        "description": "Known control fields only. Required signing inputs are named but never included."
      },
      "RecoveryNextStep": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "actor",
          "message",
          "operation"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "prepare-payment",
              "request-intent-approval",
              "sign-intent",
              "prepare-transaction",
              "sign-transaction",
              "submit-transaction",
              "refresh-review",
              "track",
              "continue-leg",
              "advance",
              "reconcile",
              "completed",
              "refunded",
              "cancelled",
              "review-required",
              "confirm-wallet-broadcast",
              "renew-mint",
              "renew-approval",
              "close-payment",
              "renew-source"
            ]
          },
          "actor": {
            "type": "string",
            "enum": [
              "app",
              "wallet",
              "operator",
              "none"
            ]
          },
          "message": {
            "type": "string"
          },
          "operation": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RecoveryOperation"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "Saved next-step reference without the wallet payload. Use next-action and detailed payment reads to review current operation requirements."
      },
      "RecoveryEvidence": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source",
          "destination",
          "refund",
          "transactions",
          "settlementDiscrepancies",
          "lastObservedAt"
        ],
        "properties": {
          "source": {
            "$ref": "#/components/schemas/RecoveryStage"
          },
          "destination": {
            "$ref": "#/components/schemas/RecoveryStage"
          },
          "refund": {
            "$ref": "#/components/schemas/RecoveryStage"
          },
          "transactions": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/RecoveryTransaction"
            }
          },
          "settlementDiscrepancies": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/RecoveryDiscrepancy"
            }
          },
          "lastObservedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "RecoveryWalletReservationGroup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "observed",
          "items",
          "truncated",
          "note"
        ],
        "properties": {
          "observed": {
            "type": "boolean"
          },
          "items": {
            "type": "array",
            "maxItems": 150,
            "items": {
              "$ref": "#/components/schemas/RecoveryWalletReservation"
            }
          },
          "truncated": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          }
        },
        "description": "Observed distinguishes a saved reservation read from unavailable evidence. Empty unobserved groups do not mean no reservations exist. Truncated means additional records were omitted."
      },
      "RecoveryApiLimitReservationGroup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "observed",
          "items",
          "truncated",
          "note"
        ],
        "properties": {
          "observed": {
            "type": "boolean"
          },
          "items": {
            "type": "array",
            "maxItems": 150,
            "items": {
              "$ref": "#/components/schemas/RecoveryApiLimitReservation"
            }
          },
          "truncated": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          }
        },
        "description": "Observed distinguishes a saved reservation read from unavailable evidence. Empty unobserved groups do not mean no reservations exist. Truncated means additional records were omitted."
      },
      "RecoveryCreditReservationGroup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "observed",
          "items",
          "truncated",
          "note"
        ],
        "properties": {
          "observed": {
            "type": "boolean"
          },
          "items": {
            "type": "array",
            "maxItems": 150,
            "items": {
              "$ref": "#/components/schemas/RecoveryCreditReservation"
            }
          },
          "truncated": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          }
        },
        "description": "Observed distinguishes a saved reservation read from unavailable evidence. Empty unobserved groups do not mean no reservations exist. Truncated means additional records were omitted."
      },
      "RecoveryReservations": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "wallet",
          "apiLimit",
          "credits"
        ],
        "properties": {
          "wallet": {
            "$ref": "#/components/schemas/RecoveryWalletReservationGroup"
          },
          "apiLimit": {
            "$ref": "#/components/schemas/RecoveryApiLimitReservationGroup"
          },
          "credits": {
            "$ref": "#/components/schemas/RecoveryCreditReservationGroup"
          }
        },
        "description": "Mainnet performs bounded project-scoped saved reservation reads. Testnet returns each group unobserved with an empty items array; it does not inspect mainnet reservation tables."
      },
      "PaymentRecoveryReport": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "schemaVersion",
          "network",
          "paymentId",
          "activePaymentId",
          "preparationId",
          "authorizationId",
          "generatedAt",
          "status",
          "outcome",
          "owner",
          "summary",
          "nextStep",
          "evidence",
          "requiredEvidence",
          "reservations",
          "safety",
          "notice"
        ],
        "properties": {
          "object": {
            "const": "payment_recovery"
          },
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "network": {
            "const": "mainnet"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "activePaymentId": {
            "type": "string",
            "format": "uuid"
          },
          "preparationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "authorizationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9_-]{1,64}$"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "no-action-issued",
              "awaiting-wallet-action",
              "unsigned-review-expired",
              "signed-not-submitted",
              "submission-uncertain",
              "source-confirmed",
              "destination-pending",
              "settlement-discrepancy",
              "intermediate-held",
              "completed",
              "refunded",
              "closed",
              "operator-review"
            ]
          },
          "owner": {
            "type": "string",
            "enum": [
              "app",
              "wallet",
              "operator",
              "none"
            ]
          },
          "summary": {
            "type": "string"
          },
          "nextStep": {
            "$ref": "#/components/schemas/RecoveryNextStep"
          },
          "evidence": {
            "$ref": "#/components/schemas/RecoveryEvidence"
          },
          "requiredEvidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reservations": {
            "$ref": "#/components/schemas/RecoveryReservations"
          },
          "safety": {
            "$ref": "#/components/schemas/RecoverySafety"
          },
          "notice": {
            "type": "string"
          }
        },
        "description": "Read-only saved evidence for an existing payment. Does not refresh providers or chains, sign, submit, mint, allocate deposits, replace payments, or release reservations. Existing POST /refresh may perform previously authorized managed destination minting; it is not equivalent to this GET. Reports omit credentials, signatures, transaction payloads and raw provider responses. Wallet addresses and transaction hashes remain sensitive operational information."
      },
      "BitcoinWithdrawalAllocation": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "schemaVersion": {
            "const": 1
          },
          "method": {
            "const": "near-omni-bitcoin-withdrawal-v1"
          },
          "network": {
            "const": "btc"
          },
          "quoteHash": {
            "type": "string"
          },
          "depositAddress": {
            "type": "string"
          },
          "sourceHash": {
            "type": "string"
          },
          "intentHash": {
            "type": "string"
          },
          "sourceNearHash": {
            "type": "string"
          },
          "intentNearHash": {
            "type": "string"
          },
          "submissionNearHash": {
            "type": "string"
          },
          "verificationNearHash": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "scriptPubKey": {
            "type": "string"
          },
          "originNonce": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "destinationNonce": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "amountMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "providerAmountMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "withdrawalAmountMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "bridgeFeeMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "maxNetworkFeeMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "networkFeeMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "transactionHash": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "blockHash": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "outputIndex": {
            "type": "integer",
            "minimum": 0
          },
          "blockHeight": {
            "type": "integer",
            "minimum": 1
          },
          "verifiedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "schemaVersion",
          "method",
          "network",
          "quoteHash",
          "depositAddress",
          "sourceHash",
          "intentHash",
          "sourceNearHash",
          "intentNearHash",
          "submissionNearHash",
          "verificationNearHash",
          "recipient",
          "scriptPubKey",
          "originNonce",
          "destinationNonce",
          "amountMinor",
          "providerAmountMinor",
          "withdrawalAmountMinor",
          "bridgeFeeMinor",
          "maxNetworkFeeMinor",
          "networkFeeMinor",
          "transactionHash",
          "blockHash",
          "outputIndex",
          "blockHeight",
          "verifiedAt"
        ]
      },
      "BitcoinPayoutEvidence": {
        "type": "object",
        "additionalProperties": false,
        "description": "Canonical BTC delivery evidence. New BTC completion transitions require an exclusive persisted claimId. Historical completed records may omit this optional evidence; its absence alone must not downgrade them. exact-recipient-net reserves the aggregate transaction/recipient net credit; near-omni-output additionally binds one verified withdrawal/output. Refunds do not use this claim path.",
        "properties": {
          "schemaVersion": {
            "const": 1
          },
          "method": {
            "enum": [
              "exact-recipient-net",
              "near-omni-output"
            ]
          },
          "transactionHash": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "recipient": {
            "type": "string"
          },
          "amountMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "providerAmountMinor": {
            "type": "string",
            "pattern": "^(0|[1-9]\\d*)$"
          },
          "blockHeight": {
            "type": "integer",
            "minimum": 1
          },
          "blockHash": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "confirmations": {
            "type": "integer",
            "minimum": 1
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "allocation": {
            "$ref": "#/components/schemas/BitcoinWithdrawalAllocation"
          },
          "claimId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "schemaVersion",
          "method",
          "transactionHash",
          "recipient",
          "amountMinor",
          "providerAmountMinor",
          "blockHeight",
          "blockHash",
          "confirmations",
          "observedAt"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "method": {
                  "const": "near-omni-output"
                }
              }
            },
            "then": {
              "required": [
                "allocation"
              ]
            },
            "else": {
              "not": {
                "required": [
                  "allocation"
                ]
              }
            }
          }
        ]
      },
      "WalletBroadcast": {
        "type": "object",
        "required": [
          "authorizationId",
          "state",
          "createdAt",
          "expiresAt",
          "transactionHash",
          "verifiedAt",
          "method",
          "params",
          "notice"
        ],
        "properties": {
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "state": {
            "enum": [
              "awaiting-transaction",
              "verified",
              "cancelled"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "transactionHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "verifiedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "method": {
            "enum": [
              "eth_sendTransaction",
              null
            ],
            "description": "null after a finalized cancellation, or once unresolved review evidence is recorded for a burn, transfer or NEAR source transaction (the handoff is then kept for review and notice explains it). Never open the wallet without params."
          },
          "params": {
            "type": "array",
            "minItems": 0,
            "maxItems": 1,
            "description": "Empty whenever method is null. An altered spending approval keeps its params.",
            "items": {
              "type": "object",
              "description": "Exact EVM transaction including type 0x0, from, to, value, data, chainId, nonce, gas and gasPrice. Preserve every supplied field."
            }
          },
          "notice": {
            "type": "string"
          },
          "cancellation": {
            "type": [
              "object",
              "null"
            ],
            "description": "Immutable finalized nonce cancellation evidence, separate from the payment source transaction."
          }
        }
      },
      "WalletBroadcastRecovery": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "paymentId",
          "authorizationId",
          "state",
          "message",
          "transactionHash",
          "network",
          "sender",
          "nonce",
          "checkedAt",
          "finalized",
          "blockNumber",
          "blockHash",
          "canClose",
          "paymentClosed",
          "automaticResubmissionAllowed"
        ],
        "properties": {
          "object": {
            "const": "wallet_broadcast_recovery"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "state": {
            "enum": [
              "not-observed",
              "pending-nonce",
              "original-verified",
              "altered-payment",
              "equivalent-execution",
              "unclassified-sender-transaction",
              "cancellation-pending",
              "cancellation-verified",
              "closed",
              "reported-transaction",
              "unclassified-transaction",
              "different-transaction"
            ],
            "description": "reported-transaction: the reported hash is recorded as pending evidence for the payment and the network does not show it yet (or it is the saved call sent without a handoff); it blocks every action of the payment until a later check classifies or clears it. unclassified-transaction: the network shows the reported transaction but Route cannot verify that the sender signed it (relayed or sponsored execution, L2 system or deposit type, unsigned or unknown envelope, another key); it is recorded and blocks. not-observed is returned only when no hash was supplied. different-transaction is no longer returned (kept so existing clients keep validating); such transactions are now evidence."
          },
          "message": {
            "type": "string"
          },
          "transactionHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "network": {
            "type": "string"
          },
          "sender": {
            "type": "string"
          },
          "nonce": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "finalized": {
            "type": "boolean"
          },
          "blockNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "blockHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "canClose": {
            "type": "boolean"
          },
          "paymentClosed": {
            "type": "boolean"
          },
          "automaticResubmissionAllowed": {
            "const": false
          },
          "parentPaymentId": {
            "type": "string",
            "format": "uuid",
            "description": "Present for composed source cancellation. First-leg closure ends the unfunded parent; intermediate closure retains its funded reservations for reviewed continuation. Absent for standalone payments."
          }
        }
      },
      "WalletAlteredTransaction": {
        "type": "object",
        "description": "Review evidence for a wallet transaction that kept the saved payment call (sender, contract, calldata, value and chain) but changed its nonce, fees or transaction type. Returned as error.details with 409 WALLET_TRANSACTION_REVIEW_REQUIRED, recorded in Route's append-only evidence journal and saved as the action's lastError. Route then never submits the saved signature or hands the saved call to the wallet. The same code with reason equivalent-execution records the same payment sent or queued at another nonce: found by the search a close or cancellation runs, or a signed transaction reported to a close, recovery, confirmation or cancellation that is the same payment without being the saved call (re-quoted, another value or envelope type, an unreadable call to the payment contract, or any call to its provider contracts or deposit address, including a NEAR source's 1Click deposit address; match same-payment or provider-contract). That evidence carries reason, match, provider, paymentTag, contract, observedValue, pending and transactionData. The same code with reason unclassified-sender-transaction records any other transaction the wallet signed that was reported for the action and is neither the saved transaction nor a recognized cancellation (fail-closed: Route cannot establish that it is not this payment), at any nonce and in any envelope (for example the saved call batched through the wallet's delegated execution, another provider contract or bridge, or an unrelated transfer), with contract, observedValue, pending and transactionData. Only a wallet-altered copy carries the observed gas fields, which are optional (observedGas, observedGasPrice, observedMaxFeePerGas); search evidence has no observedType and may have a null observedNonce. Route never attaches it to the payment and never releases the saved nonce or any reservation. Cancellation cannot close that action afterwards. Do not send replacement funds. Freeze on report (payment scope): every transaction hash reported for any action of a payment to broadcast-recover, broadcast-cancel, broadcast-confirm, /transaction/close or close after manual check (testnet: broadcast-recover, broadcast-cancel and broadcast-confirm) is recorded in Route's append-only evidence journal for the whole payment before Route reads the network or checks the payment's shape, unless it is that action's own saved or wallet-confirmed transaction or its recorded cancellation. Until an inspection shows it is the action's own transaction or a finalized recognized cancellation at the saved nonce (the report is then cleared; a cancellation or nonce proof that is not final yet clears nothing, and broadcast-confirm never clears one), it is pending evidence (reason reported-transaction; recovery state reported-transaction when the network does not show it yet, and it stays pending if the lookup fails); an inspection otherwise classifies the same row as altered-payment, equivalent-execution, unclassified-sender-transaction, or unclassified-transaction (a transaction the network shows that the sender did not verifiably sign: a relayed or sponsored EIP-7702 or ERC-4337 execution, an L2 system or deposit transaction, an unsigned or unknown envelope, or another key). Evidence on any action blocks every action of the payment: Route submits no saved signature (execute), starts no new wallet handoff and prepares no further action (POST /transaction; testnet /prepare and /transaction) with 409 WALLET_TRANSACTION_REVIEW_REQUIRED and the evidence in error.details, and no cancellation or closure releases the payment's holds. Only a spending approval's byte-identical call to the same spender, in any envelope (reason absent, altered-payment), is exempt; it refuses only that approval's own submission. Only Route's audited attribution of the hash to another Route payment with matching terms lifts the block (protocol payments); NEAR and testnet evidence that is not attributable needs operator review. A same-payment copy that nobody reports to Route cannot be seen.",
        "required": [
          "code",
          "message",
          "transactionHash",
          "network",
          "sender",
          "nonce",
          "checkedAt",
          "automaticAttachmentAllowed"
        ],
        "properties": {
          "code": {
            "const": "WALLET_TRANSACTION_REVIEW_REQUIRED"
          },
          "message": {
            "type": "string"
          },
          "transactionHash": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$"
          },
          "network": {
            "type": "string"
          },
          "sender": {
            "type": "string"
          },
          "nonce": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Nonce of the saved action."
          },
          "observedNonce": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Nonce of the observed transaction. Absent on reported-transaction evidence, and null where it could not be read (search evidence, or an unclassified-transaction without a nonce)."
          },
          "observedType": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Observed envelope type, in decimal: 0 legacy (EIP-155, or without replay protection as evidence only), 1 EIP-2930, 2 EIP-1559, 3 blob, 4 set-code; unclassified-transaction evidence can carry any type the network reports (for example 126 for an OP-stack deposit), or null. Absent on search and reported-transaction evidence."
          },
          "observedGas": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Optional: present only on a wallet-altered copy (no reason), which Route rebuilt from its signed envelope; other evidence lacks it."
          },
          "observedGasPrice": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Optional: present only on a wallet-altered copy (no reason), which Route rebuilt from its signed envelope; other evidence lacks it. Null for EIP-1559 transactions."
          },
          "observedMaxFeePerGas": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Optional: present only on a wallet-altered copy (no reason), which Route rebuilt from its signed envelope; other evidence lacks it. Set only for EIP-1559 transactions."
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "automaticAttachmentAllowed": {
            "const": false
          },
          "reason": {
            "enum": [
              "altered-payment",
              "equivalent-execution",
              "unclassified-sender-transaction",
              "unclassified-transaction",
              "reported-transaction"
            ],
            "description": "equivalent-execution: the same payment sent or queued at another nonce. unclassified-sender-transaction: another transaction the sender signed that was reported for the action and is neither the saved transaction nor a recognized cancellation. Absent on a wallet-altered copy of the saved call. unclassified-transaction: a reported transaction the network shows but the sender did not verifiably sign (relayed or sponsored execution, L2 system or deposit type, unsigned or unknown envelope, another key). reported-transaction: a reported hash Route recorded before reading it, still pending (not visible yet, or the lookup failed)."
          },
          "match": {
            "enum": [
              "same-payment",
              "provider-contract"
            ],
            "description": "For a reported signed transaction: decoded as the same payment (or an unreadable call to the payment contract), or a call to one of the payment's provider contracts or its deposit address."
          },
          "pending": {
            "type": "boolean",
            "description": "For a reported signed transaction: true while it is still queued, not yet in a block."
          },
          "transactionData": {
            "type": [
              "string",
              "null"
            ],
            "description": "The observed transaction's calldata, when Route read it."
          },
          "submission": {
            "type": "object",
            "required": [
              "code",
              "message",
              "observation"
            ],
            "properties": {
              "code": {
                "const": "SUBMISSION_UNKNOWN"
              },
              "message": {
                "type": "string"
              },
              "observation": {
                "type": "object"
              }
            },
            "description": "Only on a saved lastError: Route's own send of the saved original was reserved before this evidence was recorded, and its outcome is uncertain (transaction state submission-unknown). This is that send's SUBMISSION_UNKNOWN diagnostic. The evidence stays the lastError so the payment reads review-required; track the saved hash and never resend."
          },
          "contract": {
            "type": [
              "string",
              "null"
            ],
            "description": "For equivalent-execution and unclassified-sender-transaction evidence: the observed transaction's target (null for a contract creation)."
          },
          "observedValue": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "For a reported signed transaction: its native value in wei."
          },
          "observedFrom": {
            "type": [
              "string",
              "null"
            ],
            "description": "Only on unclassified-transaction evidence: the from address the network reports (for example a relayer or bundler)."
          },
          "signer": {
            "enum": [
              "other",
              "unverified"
            ],
            "description": "Only on unclassified-transaction evidence: other when the network reports another account as from; unverified when it reports the sender but Route cannot rebuild a sender signature."
          },
          "reported": {
            "type": "object",
            "properties": {
              "operation": {
                "type": "string"
              },
              "reportedAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "description": "When the evidence started as a reported hash: the operation it was reported to and when. Kept when an inspection classifies the report."
          }
        }
      },
      "ProtocolBitcoinPayload": {
        "type": "object",
        "required": [
          "family",
          "network",
          "psbt",
          "unsignedHex",
          "inputs",
          "feeMinor",
          "feeCurrency",
          "feeDecimals",
          "feeRate",
          "expiresAt",
          "slot"
        ],
        "properties": {
          "family": {
            "const": "bitcoin"
          },
          "network": {
            "const": "btc"
          },
          "psbt": {
            "type": "string"
          },
          "unsignedHex": {
            "type": "string",
            "pattern": "^[0-9a-f]+$"
          },
          "inputs": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "object",
              "required": [
                "txid",
                "index",
                "amount",
                "script"
              ],
              "properties": {
                "txid": {
                  "type": "string",
                  "pattern": "^[0-9a-f]{64}$"
                },
                "index": {
                  "type": "integer",
                  "minimum": 0
                },
                "amount": {
                  "type": "string"
                },
                "script": {
                  "type": "string"
                }
              }
            }
          },
          "feeMinor": {
            "type": "string"
          },
          "feeCurrency": {
            "const": "BTC"
          },
          "feeDecimals": {
            "const": 8
          },
          "feeRate": {
            "type": "integer",
            "minimum": 1
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "slot": {
            "type": "string"
          }
        }
      },
      "ProviderAvailability": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "paused"
            ]
          },
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "status",
          "code",
          "reason"
        ]
      },
      "SwapKitQuoteReviewAcceptance": {
        "type": "object",
        "description": "Accepts revised SwapKit terms for the same deposit channel. maxEstimatedTotalFeeUsd is rejected.",
        "properties": {
          "reviewHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "The reviewHash returned by GET quote-review."
          },
          "minimumReceived": {
            "type": "string",
            "description": "The minimumReceived returned by GET quote-review, unchanged."
          }
        },
        "required": [
          "reviewHash",
          "minimumReceived"
        ],
        "additionalProperties": false
      },
      "NearCapturedQuoteReviewAcceptance": {
        "type": "object",
        "description": "Accepts a captured NEAR allocation, for standalone payments and composed legs.",
        "properties": {
          "reviewHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "The reviewHash returned by GET quote-review."
          },
          "minimumReceived": {
            "type": "string",
            "description": "The minimumReceived returned by GET quote-review, unchanged."
          },
          "maxEstimatedTotalFeeUsd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,18})?$",
            "description": "Maximum total estimated USD cost you accept. For a composed leg it spans the parent, including previous attempts and the remaining transfers. Cannot exceed owner policy."
          }
        },
        "required": [
          "reviewHash",
          "minimumReceived",
          "maxEstimatedTotalFeeUsd"
        ],
        "additionalProperties": false
      },
      "PaymentQuoteReview": {
        "type": "object",
        "properties": {
          "object": {
            "const": "payment_quote_review"
          },
          "allocationId": {
            "type": "string",
            "format": "uuid"
          },
          "reviewHash": {
            "type": "string"
          },
          "accepted": {
            "type": "boolean"
          },
          "originalMinimumReceived": {
            "type": "string"
          },
          "minimumReceived": {
            "type": "string"
          },
          "expectedReceived": {
            "type": [
              "string",
              "null"
            ]
          },
          "fees": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "notice": {
            "type": "string"
          }
        },
        "required": [
          "object",
          "allocationId",
          "reviewHash",
          "accepted",
          "minimumReceived"
        ]
      },
      "ProviderRule": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "sourceAssetIds",
          "destinationAssetIds",
          "provider",
          "mode"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,64}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60
          },
          "sourceAssetIds": {
            "type": "array",
            "maxItems": 500,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "description": "Exact verified mainnet catalog IDs. Empty means any source asset."
          },
          "destinationAssetIds": {
            "type": "array",
            "maxItems": 500,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300
            },
            "description": "Exact verified mainnet catalog IDs. Empty means any destination asset."
          },
          "provider": {
            "enum": [
              "allbridge",
              "circle",
              "near",
              "layerzero",
              "axelar",
              "garden",
              "swapkit",
              "rift"
            ]
          },
          "mode": {
            "enum": [
              "any",
              "fast",
              "standard"
            ],
            "description": "Fast/Standard require direct circle. Other providers use any."
          }
        },
        "allOf": [
          {
            "anyOf": [
              {
                "properties": {
                  "sourceAssetIds": {
                    "minItems": 1
                  }
                }
              },
              {
                "properties": {
                  "destinationAssetIds": {
                    "minItems": 1
                  }
                }
              }
            ]
          },
          {
            "if": {
              "properties": {
                "provider": {
                  "not": {
                    "const": "circle"
                  }
                }
              }
            },
            "then": {
              "properties": {
                "mode": {
                  "const": "any"
                }
              }
            }
          }
        ]
      },
      "StellarSubmissionObservation": {
        "type": [
          "object",
          "null"
        ],
        "additionalProperties": false,
        "properties": {
          "network": {
            "type": "string",
            "enum": [
              "stellar",
              "stellar-testnet"
            ]
          },
          "hash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "state": {
            "type": "string",
            "enum": [
              "not-observed",
              "expired-unobserved",
              "sequence-consumed",
              "sequence-gap",
              "unavailable"
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "ledger": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "closedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "accountSequence": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]{1,19}$"
          },
          "transactionSequence": {
            "type": "string",
            "pattern": "^[0-9]{1,19}$"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "Saved, hash-bound Stellar observation after a missing receipt. Expiry uses the envelope time bound and a fresh closed ledger. Sequence consumption does not identify which transaction consumed it. This is never permission to replace a transfer or release reservations.",
        "required": [
          "network",
          "hash",
          "state",
          "checkedAt",
          "ledger",
          "closedAt",
          "accountSequence",
          "transactionSequence",
          "expiresAt"
        ]
      },
      "SourceSubmissionObservation": {
        "type": [
          "object",
          "null"
        ],
        "additionalProperties": false,
        "properties": {
          "network": {
            "type": "string",
            "enum": [
              "btc",
              "sol",
              "fogo",
              "near",
              "tron",
              "sui",
              "aptos"
            ]
          },
          "hash": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9]{64,88}$"
          },
          "state": {
            "type": "string",
            "enum": [
              "not-observed",
              "pending",
              "receipt-reported",
              "inputs-conflicted",
              "blockhash-expired",
              "failure-reported",
              "unavailable"
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "conflictingHashes": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            }
          },
          "blockHeight": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "lastValidBlockHeight": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          }
        },
        "description": "Hash-bound observation of a saved Bitcoin or Solana/Fogo source action. Reported receipts, spends and errors are not verified settlement or refund proof; they never authorize replacement or reservation release.",
        "required": [
          "network",
          "hash",
          "state",
          "checkedAt",
          "conflictingHashes",
          "blockHeight",
          "lastValidBlockHeight"
        ]
      },
      "ComposedAdvanceReview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "leg",
          "sourceAmount",
          "sourceReceiptHash",
          "adapter",
          "route",
          "minimumReceived",
          "maxEstimatedTotalFeeUsd",
          "policyVersion",
          "expiresAt"
        ],
        "properties": {
          "leg": {
            "type": "integer",
            "enum": [
              2,
              3
            ]
          },
          "sourceAmount": {
            "type": "string"
          },
          "sourceReceiptHash": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{64}$"
          },
          "adapter": {
            "type": "string",
            "enum": [
              "near",
              "circle",
              "allbridge",
              "layerzero",
              "axelar",
              "swapkit"
            ]
          },
          "route": {
            "type": "string"
          },
          "minimumReceived": {
            "type": "string",
            "description": "Lower bound on the indicative final output when advancing; the saved workflow minimum also applies."
          },
          "maxEstimatedTotalFeeUsd": {
            "type": "string",
            "description": "Upper bound on the combined estimate at advance. Includes preceding saved execution estimates and remaining preview costs. Not an on-chain fee cap; wallet signing rechecks fees and owner limits."
          },
          "policyVersion": {
            "type": "integer",
            "minimum": 1
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "cancellationHash": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{64}$",
            "description": "Present for cancellation recovery. Binds acceptance to the exact finalized cancellation. Return the complete review unchanged."
          }
        }
      },
      "ComposedAdvancePreview": {
        "type": "object",
        "required": [
          "object",
          "paymentId",
          "leg",
          "sender",
          "recipient",
          "input",
          "candidate",
          "review",
          "previousCostUsd",
          "remainingCostUsd",
          "finalMinimumReceived",
          "continuation",
          "notice",
          "remainingQuotes",
          "costComplete"
        ],
        "properties": {
          "object": {
            "const": "composed_advance_preview"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "leg": {
            "type": "integer",
            "enum": [
              2,
              3
            ]
          },
          "sender": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "input": {
            "type": "object"
          },
          "candidate": {
            "type": "object"
          },
          "review": {
            "$ref": "#/components/schemas/ComposedAdvanceReview"
          },
          "previousCostUsd": {
            "type": "string",
            "description": "Saved execution estimates for preceding legs, not final gas accounting."
          },
          "remainingCostUsd": {
            "type": "string"
          },
          "finalMinimumReceived": {
            "type": "string"
          },
          "continuation": {
            "type": "object"
          },
          "notice": {
            "type": "string"
          },
          "remainingQuotes": {
            "type": "array",
            "maxItems": 1,
            "items": {
              "type": "object",
              "required": [
                "leg",
                "input",
                "candidate"
              ],
              "properties": {
                "leg": {
                  "const": 3
                },
                "input": {
                  "type": "object"
                },
                "candidate": {
                  "type": "object"
                }
              }
            }
          },
          "costComplete": {
            "type": "boolean",
            "description": "Whether the next leg estimate covers all known fee components. Wallet preparation still verifies actual fee and policy readiness."
          }
        }
      },
      "ComposedIntermediateReceipt": {
        "type": "object",
        "required": [
          "afterLeg",
          "paymentId",
          "network",
          "wallet",
          "asset",
          "received",
          "receiptHash",
          "verified",
          "nextPaymentId",
          "disposition",
          "balanceChecked"
        ],
        "properties": {
          "afterLeg": {
            "type": "integer",
            "enum": [
              1,
              2
            ]
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "network": {
            "type": "string"
          },
          "wallet": {
            "type": "string"
          },
          "asset": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RouteAsset"
              },
              {
                "type": "null"
              }
            ]
          },
          "received": {
            "type": [
              "string",
              "null"
            ]
          },
          "receiptHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "verified": {
            "type": "boolean"
          },
          "nextPaymentId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "disposition": {
            "enum": [
              "unverified",
              "awaiting-continuation",
              "saved-next-leg",
              "forwarded",
              "refund-review",
              "cancellation-review"
            ]
          },
          "balanceChecked": {
            "const": false
          }
        }
      },
      "StellarSourceRenewalHistory": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "previousAuthorizationId",
          "authorizationId",
          "previousSourceHash",
          "renewedAt",
          "proof"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "previousAuthorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "previousSourceHash": {
            "type": "string",
            "description": "Original Stellar hash or Solana/Fogo base58 signature."
          },
          "renewedAt": {
            "type": "string",
            "format": "date-time"
          },
          "proof": {
            "type": "object",
            "description": "Saved Stellar unused-sequence proof or Solana/Fogo finalized linked-block signature history proving non-execution. Never a submission instruction.",
            "additionalProperties": true
          }
        }
      },
      "SourceRenewalResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "previousAuthorizationId",
          "authorizationId",
          "preparationId",
          "version",
          "expiresAt",
          "walletApproval",
          "transaction",
          "nextAction"
        ],
        "properties": {
          "object": {
            "const": "source_renewal"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "previousAuthorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "preparationId": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "walletApproval": {
            "$ref": "#/components/schemas/WalletIntentApproval"
          },
          "transaction": {
            "$ref": "#/components/schemas/NearPaymentTransaction"
          },
          "nextAction": {
            "type": "string",
            "enum": [
              "approve-wallet-intent",
              "read-next-action"
            ]
          }
        }
      },
      "BitcoinSourceRecoveryProof": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "network",
          "kind",
          "originalHash",
          "hash",
          "sender",
          "depositAddress",
          "amountMinor",
          "feeMinor",
          "feeCurrency",
          "finalized",
          "confirmations",
          "blockHeight",
          "blockHash",
          "checkedAt"
        ],
        "properties": {
          "network": {
            "const": "btc"
          },
          "kind": {
            "enum": [
              "funding",
              "cancellation"
            ]
          },
          "originalHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "hash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "sender": {
            "type": "string"
          },
          "depositAddress": {
            "type": "string"
          },
          "amountMinor": {
            "type": "string"
          },
          "feeMinor": {
            "type": "string"
          },
          "feeCurrency": {
            "const": "BTC"
          },
          "finalized": {
            "const": true
          },
          "confirmations": {
            "type": "integer",
            "minimum": 6
          },
          "blockHeight": {
            "type": "integer",
            "minimum": 0
          },
          "blockHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "depositUnfunded": {
            "type": "boolean",
            "const": true,
            "description": "Required for cancellation: the provider deposit has no confirmed or mempool funding."
          }
        }
      },
      "BitcoinSourceRecovery": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "paymentId",
          "authorizationId",
          "outcome",
          "transactionHash",
          "originalTransactionHash",
          "proof",
          "paymentClosed",
          "nextAction",
          "automaticResubmissionAllowed"
        ],
        "properties": {
          "object": {
            "const": "bitcoin_source_recovery"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "authorizationId": {
            "type": "string",
            "format": "uuid"
          },
          "outcome": {
            "enum": [
              "funding",
              "cancellation"
            ]
          },
          "transactionHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "originalTransactionHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "proof": {
            "$ref": "#/components/schemas/BitcoinSourceRecoveryProof"
          },
          "paymentClosed": {
            "type": "boolean"
          },
          "nextAction": {
            "const": "read-next-action"
          },
          "automaticResubmissionAllowed": {
            "const": false
          }
        }
      },
      "NearCapturedQuoteReview": {
        "type": "object",
        "properties": {
          "object": {
            "const": "near_captured_quote_review"
          },
          "accepted": {
            "type": "boolean"
          },
          "paymentId": {
            "type": "string",
            "format": "uuid"
          },
          "parentPaymentId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "minimumReceived": {
            "type": "string"
          },
          "previousMinimumReceived": {
            "type": "string"
          },
          "finalMinimumReceived": {
            "type": "string"
          },
          "estimatedTotalFeeUsd": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "acceptedAt": {
            "type": "string",
            "format": "date-time"
          },
          "nextAction": {
            "const": "approve-wallet-intent"
          },
          "remainingQuotes": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "notice": {
            "type": "string"
          }
        },
        "required": [
          "object",
          "accepted",
          "paymentId",
          "parentPaymentId",
          "reviewHash",
          "minimumReceived",
          "expiresAt",
          "notice"
        ]
      },
      "UsdPriceIssue": {
        "type": "object",
        "description": "Why one exact asset or native fee currency has no accepted fresh price. These diagnostics do not override routing or budget checks.",
        "additionalProperties": false,
        "properties": {
          "component": {
            "enum": [
              "source",
              "destination",
              "network-gas"
            ]
          },
          "network": {
            "type": "string"
          },
          "assetId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Exact market lookup identity, including its chain or pricing namespace; not a Route catalog asset ID. Null when no verified mapping exists."
          },
          "code": {
            "enum": [
              "UNSUPPORTED_PRICE_ASSET",
              "PRICE_TEMPORARILY_UNAVAILABLE",
              "PRICE_STALE",
              "PRICE_UNVERIFIED"
            ]
          },
          "retryable": {
            "type": "boolean"
          },
          "retryAfterSeconds": {
            "type": "integer",
            "minimum": 1,
            "maximum": 60,
            "description": "Bounded backoff before this instance retries a rate-limited market service. Other configured sources may still succeed."
          },
          "attempts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "source": {
                  "enum": [
                    "CoinGecko",
                    "DefiLlama",
                    "Kraken",
                    "CoinMarketCap"
                  ]
                },
                "code": {
                  "enum": [
                    "RATE_LIMITED",
                    "UNAVAILABLE",
                    "STALE",
                    "INVALID",
                    "NOT_LISTED"
                  ]
                }
              },
              "required": [
                "source",
                "code"
              ]
            }
          }
        },
        "required": [
          "component",
          "network",
          "assetId",
          "code",
          "retryable",
          "attempts"
        ]
      },
      "TronSettlementDiscrepancy": {
        "type": "object",
        "required": [
          "code",
          "network",
          "purpose",
          "transactionHash",
          "providerReportedAmountMinor",
          "observedRecipientAmountMinor",
          "differenceMinor",
          "minimumAmountMinor",
          "meetsMinimum",
          "finalized",
          "confirmations",
          "blockHeight",
          "blockHash"
        ],
        "properties": {
          "code": {
            "const": "TRON_SETTLEMENT_AMOUNT_MISMATCH"
          },
          "network": {
            "const": "tron"
          },
          "purpose": {
            "type": "string",
            "enum": [
              "delivery",
              "refund"
            ]
          },
          "transactionHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "providerReportedAmountMinor": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "observedRecipientAmountMinor": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "differenceMinor": {
            "type": "string",
            "pattern": "^-?[0-9]+$"
          },
          "minimumAmountMinor": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$"
          },
          "meetsMinimum": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "finalized": {
            "type": "boolean"
          },
          "confirmations": {
            "type": "integer",
            "minimum": 1
          },
          "blockHeight": {
            "type": "integer",
            "minimum": 0
          },
          "blockHash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          }
        },
        "description": "Exact solidified TRON recipient credit differs from the provider report. Keep tracking the existing payment; completion requires an attributed payout, not just an amount above the minimum."
      },
      "PaymentState": {
        "type": "string",
        "enum": [
          "DRAFT",
          "ARCHIVED",
          "CANCELLED",
          "PREPARING",
          "AWAITING_ACTION",
          "WALLET_SUBMISSION_UNKNOWN",
          "SOURCE_PENDING",
          "DESTINATION_PENDING",
          "DELIVERED_PENDING_FINALITY",
          "REFUND_PENDING_FINALITY",
          "VERIFICATION_PENDING",
          "INTERMEDIATE_HELD",
          "COMPLETED",
          "REFUNDED",
          "REQUIRES_ATTENTION",
          "FAILED"
        ],
        "description": "Normalized business payment state. WALLET_SUBMISSION_UNKNOWN means an external wallet may have sent funds and Route has not verified the hash: reconcile the saved action, never resend automatically. INTERMEDIATE_HELD means a composed payment has finalized an intermediate receipt and is waiting for its next authorized step. VERIFICATION_PENDING includes temporary receipt, provider-status or destination-lookup outages that tracking retries (lastError TRACKING_UNAVAILABLE, PROVIDER_TRACKING_UNAVAILABLE or DESTINATION_DISCOVERY_UNAVAILABLE) while the source or destination is otherwise pending; an uncertain send, a wallet handoff or a required wallet action keeps its own state. Workflow/provider status remains separate."
      },
      "ManualRefundConfirmation": {
        "type": "object",
        "description": "Present only when a workspace member confirmed a SwapKit refund in the dashboard because SwapKit could not confirm it. Route verified on chain that the transaction is finalized and successful, credits the payment's source asset to its refund address, was included after the deposit, has identifiable senders none of which is the payment's sender, refund or recipient address, and credits an amount from minimumAmount to maximumAmount; it then reserved the transaction as this payment's exclusive payout. Chain checks cannot prove that SwapKit sent the transaction; the member's confirmation is that attestation. API keys cannot create this confirmation.",
        "required": [
          "method",
          "confirmedBy",
          "confirmedAt",
          "transactionHash",
          "amount",
          "providerCheck",
          "minimumAmount",
          "maximumAmount",
          "senders",
          "fromDepositAddress"
        ],
        "additionalProperties": false,
        "properties": {
          "method": {
            "const": "manual"
          },
          "confirmedBy": {
            "type": "string",
            "format": "uuid",
            "description": "User ID of the workspace member who confirmed the refund. The workspace audit log records the same member."
          },
          "confirmedAt": {
            "type": "string",
            "format": "date-time"
          },
          "transactionHash": {
            "type": "string",
            "description": "Equal to refundHash."
          },
          "amount": {
            "type": "string",
            "description": "Decimal source-asset amount credited to the refund address."
          },
          "providerCheck": {
            "type": "string",
            "enum": [
              "credential-unavailable",
              "tracking-unavailable",
              "not-reported",
              "reported-unverified"
            ],
            "description": "Why SwapKit could not confirm: no usable SwapKit connection, its tracking could not be read or did not describe the saved deposit, it reported no refund or delivery, or it reported this same transaction as its refund in a form Route could not verify. Any SwapKit report that the swap completed, and a refund report naming another transaction, block manual confirmation."
          },
          "minimumAmount": {
            "type": "string",
            "description": "Lowest decimal amount accepted (the dust floor): the deposit less the saved quote's source-asset fees and destination-asset fees converted at the quote's own rate (deposit / expected output), with Route's 10% fee headroom, less the accepted slippage and a 10% refund network allowance; never below half the deposit, and exactly half the deposit when the quote deducts a fee in another asset."
          },
          "maximumAmount": {
            "type": "string",
            "description": "Highest decimal amount accepted: the verified deposit."
          },
          "senders": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Addresses that sent or funded the credit: the EVM transaction sender and the token senders to the refund address, or the Bitcoin spent-output addresses. None is the payment's sender, refund or recipient address."
          },
          "fromDepositAddress": {
            "type": "boolean",
            "description": "Whether one of the senders is the payment's SwapKit deposit address. Vault-based providers refund from other addresses, so this is recorded, not required."
          }
        }
      },
      "ArrivalWarning": {
        "type": "object",
        "required": [
          "code",
          "message",
          "arrivalModel"
        ],
        "description": "Speed priority, a delivery deadline or an Auto-route speed or balanced preference needs end-to-end arrival evidence. Route models it only for reviewed direct paths, and only until the arrival model review expires. Managed CCTP delivery to Stellar also needs Circle attestation timing, whose separate review expiry the message names; after that review lapses the message excludes that path. Derived when read or saved; never stored with the policy. Warnings do not block saving.",
        "properties": {
          "code": {
            "enum": [
              "ARRIVAL_EVIDENCE_LIMITED",
              "ARRIVAL_EVIDENCE_UNAVAILABLE"
            ],
            "description": "ARRIVAL_EVIDENCE_LIMITED: only modeled direct paths can satisfy the setting. ARRIVAL_EVIDENCE_UNAVAILABLE: the model review has lapsed and no route can satisfy it."
          },
          "message": {
            "type": "string"
          },
          "arrivalModel": {
            "type": "object",
            "required": [
              "version",
              "reviewedAt",
              "expiresAt",
              "current"
            ],
            "properties": {
              "version": {
                "const": "arrival-v1"
              },
              "reviewedAt": {
                "type": "string",
                "format": "date-time"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              },
              "current": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "RiftPrepare": {
        "type": "object",
        "description": "Direct Rift order. Requires customer acceptance of variable output: no guaranteed minimum or slippage protection. The sender is also the refund address. Replays retain the same quote and addresses.",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "sender": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "acceptVariableOutput": {
            "type": "boolean",
            "const": true,
            "description": "Explicit customer acceptance is required. Never default this silently in a user interface."
          }
        },
        "required": [
          "version",
          "sender",
          "recipient",
          "acceptVariableOutput"
        ],
        "additionalProperties": false
      },
      "QuoteSummary": {
        "type": "object",
        "description": "Observation for one provider path. Decimal receipts use destination asset units and estimatedCostUsd uses USD. Missing estimates are null. A recommendation is limited to observed paths and does not guarantee a globally best price or authorize spending.",
        "properties": {
          "received": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Estimated recipient amount in destination asset units."
          },
          "minimumReceived": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Quoted minimum recipient amount in destination asset units, when available. Later preparation must validate the actual payment terms."
          },
          "estimatedCostUsd": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Estimated total cost in USD. When costComplete is false, source gas still needs confirmation and the ranking can change."
          },
          "costComplete": {
            "type": "boolean",
            "description": "Whether quoted total cost is complete; wallet, policy and actual transaction fee checks remain mandatory."
          },
          "legs": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "description": "Number of provider transfers. Multi-leg routes are non-atomic and require later-leg re-quotes after settlement and separate wallet authorization."
          }
        },
        "required": [
          "received",
          "minimumReceived",
          "estimatedCostUsd",
          "costComplete",
          "legs"
        ],
        "additionalProperties": false
      },
      "QuoteBest": {
        "type": "object",
        "description": "Default mainnet view (view=best): one saved recommendation summary. Accept it with POST /payments using mode=prepare and quoteId. Reading this response never creates a payment.",
        "properties": {
          "object": {
            "const": "quote"
          },
          "apiVersion": {
            "const": "v1"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "ready-for-preparation",
              "requires-fee-confirmation",
              "unavailable",
              "expired"
            ],
            "description": "Ready means quote checks passed for wallet preparation, not authorization to spend. Fee confirmation permits only the source-gas deferral. Unavailable or expired has no automatic next action."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "input": {
            "type": "object",
            "properties": {
              "sourceAssetId": {
                "type": "string"
              },
              "destinationAssetId": {
                "type": "string"
              },
              "amount": {
                "type": "string",
                "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
                "description": "Positive decimal quantity in source asset units, within its catalog precision. Not USD or integer base units."
              }
            },
            "required": [
              "sourceAssetId",
              "destinationAssetId",
              "amount"
            ],
            "additionalProperties": false
          },
          "nextAction": {
            "enum": [
              "create-payment-and-prepare",
              null
            ]
          },
          "network": {
            "const": "mainnet"
          },
          "quote": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/QuoteSummary"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "object",
          "apiVersion",
          "id",
          "status",
          "expiresAt",
          "input",
          "nextAction",
          "quote"
        ],
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "enum": [
                    "unavailable",
                    "expired"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "quote": {
                  "type": "null"
                },
                "nextAction": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "quote": {
                  "$ref": "#/components/schemas/QuoteSummary"
                },
                "nextAction": {
                  "const": "create-payment-and-prepare"
                }
              }
            }
          }
        ]
      },
      "QuoteListCandidate": {
        "type": "object",
        "properties": {
          "candidateId": {
            "type": "string",
            "description": "Use as candidateId to explicitly create a payment for this alternative."
          },
          "status": {
            "enum": [
              "ready-for-preparation",
              "requires-fee-confirmation"
            ]
          },
          "received": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Estimated recipient amount in destination asset units."
          },
          "minimumReceived": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Quoted minimum recipient amount in destination asset units, when available. Later preparation must validate the actual payment terms."
          },
          "estimatedCostUsd": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
            "description": "Estimated total cost in USD. When costComplete is false, source gas still needs confirmation and the ranking can change."
          },
          "costComplete": {
            "type": "boolean",
            "description": "Whether quoted total cost is complete; wallet, policy and actual transaction fee checks remain mandatory."
          },
          "legs": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "description": "Number of provider transfers. Multi-leg routes are non-atomic and require later-leg re-quotes after settlement and separate wallet authorization."
          }
        },
        "required": [
          "candidateId",
          "status",
          "received",
          "minimumReceived",
          "estimatedCostUsd",
          "costComplete",
          "legs"
        ],
        "additionalProperties": false
      },
      "QuoteList": {
        "type": "object",
        "description": "view=list: ranked alternatives that can safely proceed to preparation. Fully checked execution choices precede source-gas-only preparation choices. Blocked and diagnostic candidates remain available with compact/full. Incomplete costs can change the ranking after preparation.",
        "properties": {
          "object": {
            "const": "quote"
          },
          "apiVersion": {
            "const": "v1"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "ready-for-preparation",
              "requires-fee-confirmation",
              "unavailable",
              "expired"
            ],
            "description": "Ready means quote checks passed for wallet preparation, not authorization to spend. Fee confirmation permits only the source-gas deferral. Unavailable or expired has no automatic next action."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "input": {
            "type": "object",
            "properties": {
              "sourceAssetId": {
                "type": "string"
              },
              "destinationAssetId": {
                "type": "string"
              },
              "amount": {
                "type": "string",
                "pattern": "^(0|[1-9]\\d*)(\\.\\d+)?$",
                "description": "Positive decimal quantity in source asset units, within its catalog precision. Not USD or integer base units."
              }
            },
            "required": [
              "sourceAssetId",
              "destinationAssetId",
              "amount"
            ],
            "additionalProperties": false
          },
          "nextAction": {
            "enum": [
              "create-payment-and-prepare",
              null
            ]
          },
          "network": {
            "const": "mainnet"
          },
          "recommendedCandidateId": {
            "type": [
              "string",
              "null"
            ]
          },
          "candidates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuoteListCandidate"
            }
          }
        },
        "required": [
          "object",
          "apiVersion",
          "id",
          "status",
          "expiresAt",
          "input",
          "nextAction",
          "recommendedCandidateId",
          "candidates"
        ],
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "enum": [
                    "unavailable",
                    "expired"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "recommendedCandidateId": {
                  "type": "null"
                },
                "nextAction": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "recommendedCandidateId": {
                  "type": "string"
                },
                "nextAction": {
                  "const": "create-payment-and-prepare"
                }
              }
            }
          }
        ]
      },
      "QuoteResponse": {
        "description": "Mainnet defaults to best. List returns safely selectable alternatives; compact and full retain their previous representations. View affects presentation only, not the saved quote, its idempotency identity, expiry or billing.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/QuoteBest"
          },
          {
            "$ref": "#/components/schemas/QuoteList"
          },
          {
            "$ref": "#/components/schemas/Quote"
          }
        ]
      },
      "PaymentWalletRequirement": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "enum": [
              "sender",
              "recipient",
              "intermediate",
              "intermediates"
            ],
            "description": "Top-level preparation field. Use intermediate for two legs or intermediates for three legs."
          },
          "network": {
            "type": "string",
            "description": "Exact Route network identifier for this wallet, such as btc, stellar, base or arbitrum."
          },
          "index": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1,
            "description": "Zero-based position in the intermediates array, present for three-leg routes only."
          }
        },
        "required": [
          "field",
          "network"
        ],
        "additionalProperties": false
      },
      "QuoteDetails": {
        "type": "object",
        "description": "Optional provider metadata. Compact responses retain only bounded normalized errorCode, quoteErrorCode, reason and the capacity diagnostics described here. Other provider metadata is available with view=full. Capacity diagnostics contain no raw upstream message, body or URL and never change eligibility.",
        "properties": {
          "capacityErrorCode": {
            "type": "string",
            "maxLength": 100,
            "pattern": "^[A-Z][A-Z0-9_]{0,99}(?![\\s\\S])",
            "description": "Route-normalized capacity read failure code; optional for historical quotes."
          },
          "capacityErrorKind": {
            "type": "string",
            "enum": [
              "timeout",
              "aborted",
              "network",
              "upstream",
              "rpc",
              "validation",
              "unexpected"
            ]
          },
          "capacityErrorNetwork": {
            "type": "string",
            "enum": [
              "ethereum",
              "base",
              "arbitrum",
              "stellar"
            ]
          },
          "capacityErrorHost": {
            "type": "string",
            "maxLength": 253,
            "pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?(?![\\s\\S])",
            "description": "Public RPC hostname only, without credentials, port, path or query."
          },
          "capacityErrorMethod": {
            "type": "string",
            "enum": [
              "eth_chainId",
              "eth_getBlockByNumber",
              "eth_call",
              "getNetwork",
              "getLatestLedger",
              "simulateTransaction"
            ]
          },
          "capacityErrorCheck": {
            "type": "string",
            "enum": [
              "source_connect",
              "destination_connect",
              "source_burn_limit",
              "source_local_messenger",
              "destination_local_messenger",
              "source_remote_messenger",
              "destination_transmitter",
              "destination_token_mapping",
              "source_minter_paused",
              "source_transmitter_paused",
              "source_token_paused",
              "destination_minter_paused",
              "destination_transmitter_paused",
              "destination_token_paused",
              "destination_messenger_paused"
            ],
            "description": "Fixed name of the failed wallet-free capacity check."
          }
        },
        "additionalProperties": {
          "type": [
            "string",
            "boolean"
          ]
        }
      }
    }
  },
  "externalDocs": {
    "description": "Route developer guide and quickstart",
    "url": "https://route.click/docs/"
  }
}
