{
  "openapi": "3.1.0",
  "info": {
    "title": "route",
    "version": "2.14.0",
    "description": "Route compares swap paths offchain and executes swaps on Robinhood Chain. The API returns quotes and unsigned transactions. It does not sign or submit for you. Route charges no platform fee; pool fees, provider charges and gas may still apply. Contracts are experimental and unaudited. The production API is public and requires no API key. Use the documented /api/v2 endpoints for integrations."
  },
  "servers": [
    {
      "url": "https://www.route.fun",
      "description": "Public Route API"
    }
  ],
  "paths": {
    "/api/openapi": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "Download this specification",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 JSON document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "Network unavailable or service locked (DEPLOYMENT_LOCKED).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": " No API key or site login is required on the public production service. Request limits and validation still apply."
      }
    },
    "/api/v2/config": {
      "get": {
        "operationId": "getHybridConfig",
        "summary": "Read routing configuration",
        "description": "Active per-provider fee-free executors, enabledProviders, direct venues and bounded search limits. 0x needs its separate deployed executor and a server-side API credential; an unavailable provider does not remove the other routes. feeSettings and top-level feeRecipient/feeAdmin are zero addresses because no fee recipient or administrator exists; feeRecipientChangeable is false. executors applies to native ETH output; tokenOutputExecutors applies to ERC20 output. Output-dependent settlement preserves native forwarding-recipient behavior without extra recipient lookups. The maps may be identical; their actual addresses, not a feature flag, identify the current deployment.\n\nNo API key or site login is required on the public production service. Request limits and validation still apply.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HybridConfig"
                }
              }
            }
          },
          "400": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds before retry. Concurrency BUSY uses 2; minute admission exhaustion uses the remaining window, 1 to 60. Honor this header instead of retrying on every edit.",
                "schema": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                }
              }
            }
          },
          "503": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/tokens": {
      "get": {
        "operationId": "getAssets",
        "summary": "Find token metadata",
        "description": "Returns curated defaults when address is omitted. Import by ERC-20 address; metadata and decimals are checked onchain, but issuer safety is not established. Successful imported metadata is cached for up to 60 seconds per RPC client; concurrent same-token checks share pending reads.\n\nPrices and executable quotes are not cached by this metadata layer. The curated list includes ETH, USDG, WETH, AI (Artificial Inu), MEME (A Meme Coin), DELTA (Delta), PONS (Pons), and ROUTE (Route, 0x4a72b9702f991b790788f8afa9e7112541f4e8f8). ROUTE is the default receive token on the swap website.\n\nToken verification is tied to the exact Robinhood Chain contract address, not its symbol. It is not a security audit or a guarantee that a token can be sold. No API key or site login is required on the public production service.\n\nRequest limits and validation still apply.",
        "parameters": [
          {
            "name": "address",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(ETH|0x[0-9a-fA-F]{40})$",
              "description": "Native ETH or an ERC-20 address on chain 4663. Zero address also means native ETH. Do not pass other token symbols."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetList"
                }
              }
            }
          },
          "400": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds before retry. Concurrency BUSY uses 2; minute admission exhaustion uses the remaining window, 1 to 60. Honor this header instead of retrying on every edit.",
                "schema": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                }
              }
            }
          },
          "503": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/quote": {
      "get": {
        "operationId": "getBestQuote",
        "summary": "Compare swap routes",
        "description": "Search verified direct pools, up to four Kyber variants, and one 0x firm quote when enabled. 0x output already includes its provider fees; Route adds no fee. Validate fixed AllowanceHolder, decoded input/recipient/output bindings and the active onchain Settler registry. Deduplicate and build candidates, then simulate complete calldata at one shared block using synthetic caller balance and exact-allowance fixtures; real token code is not replaced.\n\nExclude reverting candidates and prefer simulated candidates over unverified ones. Rank by simulated user output minus RPC-estimated gas using a common conversion model, or output alone if conversion is missing. Unsupported token layouts/RPC failures are explicitly unverified, not proof of executability.\n\nUp to 3 hops and 3 disjoint split branches; 10% grid with 1% local refinement. No global-best or future-execution guarantee. amountOut retains the original quote; execution.amountOut is the assessed output used for ranking and UI review. Optional provider restricts comparison to that source; it does not disable execution checks.\n\nNothing is signed or submitted. For an already-discovered V4 pool whose PositionManager key is missing or mismatched, one exact-pool-ID Initialize-event lookup can recover its immutable key. The complete key hash and current PoolManager state must still match; hooks and dynamic fees remain excluded.\n\nThis does not index every pool or replace listing discovery. Only when initial verified discovery yields no supported path, Route additionally probes at most 28 common hook-free V4 keys at the quote block, including native ETH alternatives. Existing pools are preserved within the 96-pool cap.\n\nSearches that already have a path perform no such probes; a path whose quotes fail does not trigger a second expanded search. This bounded availability fallback is not a universal best-price or speed guarantee, and final execution checks remain required. Expensive HTTP requests have a 25-second response deadline; timeout returns 503 QUOTE_TIMEOUT.\n\nWorkers waitUntil retains already-started read-only work and its cleanup after client disconnect, subject to the platform lifetime. Admission and in-flight search ownership expire after 60 seconds as an abandoned-request safeguard; late cleanup cannot delete replacement owners. The four-concurrent and 60-admissions-per-minute per-isolate limits remain.\n\nBUSY returns Retry-After: 2 for concurrency, or the remaining minute-window seconds for rate exhaustion. No new endpoint, background signing or relaxed transaction check is introduced. comparison lists every deduplicated candidate entering final assessment, including failed, expired and unverified results, with exactly one selected candidate. It does not enumerate every preliminary pool path or unavailable provider quote.\n\nThese display-only summaries contain no calldata and cannot be submitted as swap plans. The UI highlights the selected candidate; its animation is a visualization of the completed comparison, not live execution or JIT routing. Missing sources and merged duplicate requests are counted separately.\n\nNo extra routing requests are made for the map. Overlapping Kyber variants share only pending network-reference reads (block, gas price and chain ID). A later request reads again; each quote still checks network freshness, and final full-transaction assessment obtains its own execution context.\n\nThe assessed gas price is the maximum of a positive RPC suggestion and the checked block base fee, avoiding an inadmissible price when concurrent reads describe adjacent fee states. All candidates still execute at that same price; there is no hidden zero-price fallback. Wallet final checks apply the same observed base-fee floor, not a guarantee against future fee increases.\n\nUnavailable execution checks include a closed failure stage/reason; no remote error bodies, credentials or calldata are returned. These diagnostics do not retry failures, lower minimums or promote unverified candidates. After the first validated provider quote, cold ERC20 simulation-layout discovery may overlap remaining provider work.\n\nLayout hints are bounded and scoped to one RPC client; native input and warm hints require no discovery. Started probes are joined before final assessment. Every candidate still validates its exact simulated balance and allowance at the final execution block; no completed price or execution result is cached.\n\nAll complete-transaction checks use one explicit positive gas price shared across candidates, eth_call, estimateGas and ranking. execution.gasPrice records that context; it is not a fee or fill guarantee. Before signing, the wallet flow refreshes the fee fields and simulates again. On EIP-1559 chains, the fee cap is twice the latest base fee plus the suggested priority fee.\n\nOther chains use legacy gas pricing. The signature request uses the same fee fields as the final simulation. Wallet edits or later blocks can still affect execution.\n\nDirect sources include Uniswap V2/V3/V4, GIGA CL and Ramses CL; this is not exhaustive chain liquidity coverage. The lean executor uses canonical V2 pair and authenticated canonical V3 pool-callback execution, retaining fixed Ramses routing and all other adapter fallbacks while preserving all signed limits. Search gas costs are receipt-informed heuristics; final ranking uses full-transaction assessment.\n\nIdentical in-flight blockchain reads share work only while pending, keyed by complete parameters including block and state overrides. Public transport may use one backup RPC after 250ms; configured private server transport does not hedge to public RPC. Deterministic execution rejections fail closed.\n\nNo completed price or execution result is cached. Independent exact-remainder split checks run concurrently under the existing sampler limits and retain deterministic selection order. Pre-sign refresh is not execution-time JIT; this executor has no adaptive rerouting.\n\nNo API key or site login is required on the public production service. Request limits and validation still apply.",
        "parameters": [
          {
            "name": "chainId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "const": 4663
            }
          },
          {
            "name": "tokenIn",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(ETH|0x[0-9a-fA-F]{40})$",
              "description": "Native ETH or an ERC-20 address on chain 4663. Zero address also means native ETH. Do not pass other token symbols."
            }
          },
          {
            "name": "tokenOut",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(ETH|0x[0-9a-fA-F]{40})$",
              "description": "Native ETH or an ERC-20 address on chain 4663. Zero address also means native ETH. Do not pass other token symbols."
            }
          },
          {
            "name": "amountIn",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,77}$",
              "description": "Exact input in base units; maximum 170141183460469231731687303715884105727 (2^127 - 1)."
            }
          },
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "route",
                "kyber",
                "zerox"
              ],
              "description": "route = direct engine; kyber and zerox = upstream routes with Route settlement protection. Check enabledProviders; 0x uses a separate executor."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HybridQuote"
                }
              }
            }
          },
          "400": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds before retry. Concurrency BUSY uses 2; minute admission exhaustion uses the remaining window, 1 to 60. Honor this header instead of retrying on every edit.",
                "schema": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                }
              }
            }
          },
          "503": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/swap": {
      "post": {
        "operationId": "prepareHybridSwap",
        "summary": "Prepare a protected swap",
        "description": "Re-quotes selected routes (including the optional Kyber variant), validates the plan, and builds an unsigned exact-input transaction. The user minimum, recipient, input and deadline are bound in Route settlement. No Route fee is deducted; all actual settlement output goes to the recipient.\n\nUnlike quote candidate assessment, this endpoint performs no caller balance/allowance check, approval, whole-swap simulation, signature or submission. Maximum JSON body: 16384 bytes. Integrators must simulate from the signing wallet after any approval and preserve the reviewed minimum if a provider is reselected.\n\nFor zerox, provide txOrigin as the signing EOA. 0x calldata is rebuilt for this origin and the separate Route executor; never approve Settler. Its opaque actions and inner minimum remain unchanged, while the outer contract enforces the exact reviewed user minimum and deadline. An inner 0.5% minimum can make a swap fail even when a looser outer tolerance would permit it.\n\nChanging executors requires a fresh approval review. Active executors have no fee recipient, administrator or fee-rate setter. Direct venue membership and supported fee tiers are server-controlled.\n\nExperimental Sushi/Pancake integrations are not active API coverage; clients cannot enable them by submitting adapter or factory addresses. Resolve the reviewed spender from the output-specific configuration map. If Kyber uses a distinct token-output executor, upstream delivery goes directly to the requested recipient and its actual token balance delta enforces the minimum.\n\nNative ETH output retains the existing forwarding guard. No request field may override the executor, receiver policy or fee. Complete the JSON body within five seconds; stalled bodies return 408 BODY_TIMEOUT.\n\nUnexpected transport failures are logged without raw provider error text. No API key or site login is required on the public production service. Request limits and validation still apply.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HybridSwapRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Unsigned swap, optional exact approval, fresh estimate and simulationRequired=true.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HybridSwapResponse"
                }
              }
            }
          },
          "400": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "408": {
            "description": "BODY_TIMEOUT: complete the JSON body within five seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds before retry. Concurrency BUSY uses 2; minute admission exhaustion uses the remaining window, 1 to 60. Honor this header instead of retrying on every edit.",
                "schema": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                }
              }
            }
          },
          "503": {
            "description": "Structured error; see errors and access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/activity": {
      "get": {
        "operationId": "getActivity",
        "summary": "Read total swap activity",
        "description": "All-time mainnet activity across current and historical Route settlement contracts, including early tests. Counts unique successful swap transactions, excluding approvals and failed transactions. Nested wrapper events are not counted twice.\n\nVolume counts one side of each swap: USDG at $1, otherwise ETH/WETH input or output at the indexed ETH/USDG spot price. This is an estimate at current indexed prices, not historical dollar volume. Swaps with neither pricing asset are excluded from volume and reported in unpricedSwaps.\n\nRefreshes at most once per minute per server instance, with 64 recent blocks excluded. Upstream failures return the last available snapshot with stale=true. No query parameters or wallet data are accepted.\n\nNo API key or site login is required on the public production service. Request limits and validation still apply.",
        "responses": {
          "200": {
            "description": "Aggregate snapshot. A null volume means ETH pricing was unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "chainId": {
                      "type": "integer",
                      "const": 4663
                    },
                    "transactions": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "swaps": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "estimatedVolumeUsd": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "minimum": 0
                    },
                    "usdgVolume": {
                      "type": "string",
                      "description": "USDG base units, six decimals."
                    },
                    "ethVolume": {
                      "type": "string",
                      "description": "ETH base units, eighteen decimals."
                    },
                    "unpricedSwaps": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "throughBlock": {
                      "type": "string"
                    },
                    "asOf": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "chainId",
                    "transactions",
                    "swaps",
                    "estimatedVolumeUsd",
                    "usdgVolume",
                    "ethVolume",
                    "unpricedSwaps",
                    "throughBlock",
                    "asOf",
                    "stale"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Structured error; see the API overview for codes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Structured error; see the API overview for codes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Structured error; see the API overview for codes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message",
              "requestId"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "Token": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string",
            "enum": [
              "ETH",
              "USDG"
            ]
          },
          "address": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "decimals": {
            "type": "integer",
            "minimum": 0,
            "maximum": 18
          }
        },
        "required": [
          "symbol",
          "address",
          "decimals"
        ],
        "additionalProperties": false
      },
      "Adapter": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "address",
          "name"
        ],
        "additionalProperties": false
      },
      "Config": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string"
          },
          "chainId": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "rpcUrl": {
            "type": "string",
            "format": "uri"
          },
          "router": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "wrappedNative": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "deployedAt": {
            "type": "string",
            "format": "date-time"
          },
          "explorer": {
            "type": [
              "string",
              "null"
            ]
          },
          "adapters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Adapter"
            }
          },
          "tokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Token"
            }
          },
          "quoteTtlSeconds": {
            "type": "integer",
            "const": 30
          },
          "protocolFeeBps": {
            "type": "integer",
            "const": 0
          },
          "audited": {
            "type": "boolean",
            "const": false
          }
        },
        "required": [
          "mode",
          "chainId",
          "name",
          "rpcUrl",
          "router",
          "wrappedNative",
          "deployedAt",
          "explorer",
          "adapters",
          "tokens",
          "quoteTtlSeconds",
          "protocolFeeBps",
          "audited"
        ],
        "additionalProperties": false
      },
      "Quote": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "tokenIn": {
            "type": "string",
            "enum": [
              "ETH",
              "USDG"
            ]
          },
          "tokenOut": {
            "type": "string",
            "enum": [
              "ETH",
              "USDG"
            ]
          },
          "amountIn": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "A positive integer in token base units, no larger than uint256."
          },
          "router": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "amountOut": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "A positive integer in token base units, no larger than uint256."
          },
          "blockNumber": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "expiresAt": {
            "type": "integer",
            "description": "Unix seconds; prices can change before expiry."
          },
          "intermediate": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "legs": {
            "type": "array",
            "minItems": 1,
            "maxItems": 2,
            "items": {
              "type": "object",
              "properties": {
                "adapter": {
                  "type": "string",
                  "pattern": "^0x[0-9a-fA-F]{40}$"
                },
                "fee": {
                  "type": "integer",
                  "description": "V3 fee in millionths; V2 sentinel 0 is not a zero trading fee."
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "adapter",
                "fee",
                "name"
              ],
              "additionalProperties": false
            }
          },
          "protocolFeeBps": {
            "type": "integer",
            "const": 0
          }
        },
        "required": [
          "chainId",
          "tokenIn",
          "tokenOut",
          "amountIn",
          "router",
          "amountOut",
          "blockNumber",
          "expiresAt",
          "intermediate",
          "legs",
          "protocolFeeBps"
        ],
        "additionalProperties": false
      },
      "SwapRequest": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "tokenIn": {
            "type": "string",
            "enum": [
              "ETH",
              "USDG"
            ]
          },
          "tokenOut": {
            "type": "string",
            "enum": [
              "ETH",
              "USDG"
            ]
          },
          "amountIn": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "A positive integer in token base units, no larger than uint256."
          },
          "amountOutMinimum": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "A positive integer in token base units, no larger than uint256."
          },
          "recipient": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Nonzero recipient other than Route."
          },
          "deadline": {
            "type": "integer",
            "description": "Unix seconds, after now and at most 1200 seconds ahead."
          }
        },
        "required": [
          "chainId",
          "tokenIn",
          "tokenOut",
          "amountIn",
          "amountOutMinimum",
          "recipient",
          "deadline"
        ],
        "additionalProperties": false
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "data": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]*$"
          },
          "value": {
            "type": "string",
            "pattern": "^[0-9]+$"
          }
        },
        "required": [
          "to",
          "data",
          "value"
        ],
        "additionalProperties": false
      },
      "SwapResponse": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "transaction": {
            "$ref": "#/components/schemas/Transaction"
          },
          "approval": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  },
                  "spender": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[1-9][0-9]{0,77}$",
                    "description": "A positive integer in token base units, no larger than uint256."
                  },
                  "transaction": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                },
                "required": [
                  "token",
                  "spender",
                  "amount",
                  "transaction"
                ],
                "additionalProperties": false
              }
            ]
          },
          "simulationRequired": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "chainId",
          "transaction",
          "approval",
          "simulationRequired"
        ],
        "additionalProperties": false
      },
      "Asset": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "symbol": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "decimals": {
            "type": "integer",
            "minimum": 0,
            "maximum": 36
          },
          "verified": {
            "type": "boolean",
            "description": "Included in the curated starter list, not proof that a token is safe or backed by assets."
          }
        },
        "required": [
          "address",
          "symbol",
          "name",
          "decimals",
          "verified"
        ],
        "additionalProperties": false
      },
      "AssetList": {
        "type": "object",
        "properties": {
          "tokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Asset"
            }
          }
        },
        "required": [
          "tokens"
        ],
        "additionalProperties": false
      },
      "HybridVenue": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "protocol": {
            "type": "string",
            "enum": [
              "v2",
              "v3",
              "v4",
              "ramses-cl"
            ]
          },
          "factory": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "router": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "quoter": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "adapter": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        },
        "required": [
          "id",
          "name",
          "protocol",
          "factory",
          "router",
          "quoter",
          "adapter"
        ],
        "additionalProperties": false
      },
      "HybridConfig": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "const": 2
          },
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "name": {
            "type": "string"
          },
          "rpcUrl": {
            "type": "string"
          },
          "explorer": {
            "type": [
              "string",
              "null"
            ]
          },
          "executors": {
            "type": "object",
            "properties": {
              "route": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              },
              "kyber": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              },
              "zerox": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              }
            },
            "required": [
              "route",
              "kyber",
              "zerox"
            ],
            "additionalProperties": false
          },
          "upstreamRouter": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "settlementEngines": {
            "type": "object",
            "properties": {
              "route": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              },
              "kyber": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              },
              "zerox": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              }
            },
            "required": [
              "route",
              "kyber",
              "zerox"
            ],
            "additionalProperties": false
          },
          "feeRecipient": {
            "const": "0x0000000000000000000000000000000000000000",
            "description": "No fee recipient exists in active settlement."
          },
          "feeAdmin": {
            "const": "0x0000000000000000000000000000000000000000",
            "description": "No administrator exists in active settlement."
          },
          "feeToken": {
            "const": "output"
          },
          "feeRecipientChangeable": {
            "const": false
          },
          "venues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HybridVenue"
            }
          },
          "tokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Asset"
            }
          },
          "limits": {
            "type": "object",
            "properties": {
              "maxPools": {
                "const": 96
              },
              "maxPaths": {
                "const": 32
              },
              "maxHops": {
                "const": 3
              },
              "maxSplits": {
                "const": 3
              },
              "maxQuoteCalls": {
                "const": 360
              },
              "deadlineMs": {
                "const": 18000
              },
              "discoveryTokens": {
                "const": 6
              },
              "slippageBps": {
                "const": 50
              }
            },
            "required": [
              "maxPools",
              "maxPaths",
              "maxHops",
              "maxSplits",
              "maxQuoteCalls",
              "deadlineMs",
              "discoveryTokens",
              "slippageBps"
            ],
            "additionalProperties": false
          },
          "quoteTtlSeconds": {
            "const": 30
          },
          "protocolFeeBps": {
            "const": 0
          },
          "audited": {
            "const": false
          },
          "settlementMode": {
            "type": "string",
            "enum": [
              "fee-free"
            ],
            "description": "fee-free: direct plans use RoutePoolExecutor with canonical V2 pair and V3 callback execution plus existing adapter fallbacks; Kyber and 0x use separate immutable RouteMetaExecutor deployments. None has a fee or administrator. Historical approvals do not transfer to a changed executor; review the current spender before signing."
          },
          "zeroXRouter": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Fixed 0x AllowanceHolder upstream. Wallets approve their Route executor, never the dynamic Settler."
          },
          "enabledProviders": {
            "type": "object",
            "properties": {
              "route": {
                "type": "boolean"
              },
              "kyber": {
                "type": "boolean"
              },
              "zerox": {
                "type": "boolean"
              }
            },
            "required": [
              "route",
              "kyber",
              "zerox"
            ],
            "additionalProperties": false
          },
          "feeSettings": {
            "type": "object",
            "properties": {
              "route": {
                "type": "object",
                "properties": {
                  "feeRecipient": {
                    "const": "0x0000000000000000000000000000000000000000"
                  },
                  "feeAdmin": {
                    "const": "0x0000000000000000000000000000000000000000"
                  }
                },
                "required": [
                  "feeRecipient",
                  "feeAdmin"
                ],
                "additionalProperties": false
              },
              "kyber": {
                "type": "object",
                "properties": {
                  "feeRecipient": {
                    "const": "0x0000000000000000000000000000000000000000"
                  },
                  "feeAdmin": {
                    "const": "0x0000000000000000000000000000000000000000"
                  }
                },
                "required": [
                  "feeRecipient",
                  "feeAdmin"
                ],
                "additionalProperties": false
              },
              "zerox": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "feeRecipient": {
                        "const": "0x0000000000000000000000000000000000000000"
                      },
                      "feeAdmin": {
                        "const": "0x0000000000000000000000000000000000000000"
                      }
                    },
                    "required": [
                      "feeRecipient",
                      "feeAdmin"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "route",
              "kyber",
              "zerox"
            ],
            "additionalProperties": false
          },
          "tokenOutputExecutors": {
            "type": "object",
            "properties": {
              "route": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              },
              "kyber": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              },
              "zerox": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]{40}$"
              }
            },
            "required": [
              "route",
              "kyber",
              "zerox"
            ],
            "additionalProperties": false,
            "description": "Provider executor map for ERC20 outputs, including WETH. Use executors for native ETH output. Maps may be identical before a separate token-output guard is activated. Always verify the returned quote.router and transaction.to against the correct map; changed spenders require a fresh review."
          }
        },
        "required": [
          "version",
          "chainId",
          "name",
          "rpcUrl",
          "explorer",
          "executors",
          "upstreamRouter",
          "settlementEngines",
          "feeRecipient",
          "feeAdmin",
          "feeToken",
          "feeRecipientChangeable",
          "venues",
          "tokens",
          "limits",
          "quoteTtlSeconds",
          "protocolFeeBps",
          "audited",
          "settlementMode",
          "zeroXRouter",
          "enabledProviders",
          "feeSettings",
          "tokenOutputExecutors"
        ],
        "additionalProperties": false
      },
      "PlanLeg": {
        "type": "object",
        "properties": {
          "adapter": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Must be an enabled adapter in v2 configuration."
          },
          "tokenOut": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Uses WETH rather than native ETH; no cycles allowed."
          },
          "fee": {
            "type": "integer",
            "minimum": 0,
            "maximum": 999999,
            "description": "Pool fee in millionths for V3/V4. V2 and Ramses CL require sentinel 0, not a zero trading fee; Ramses uses tick spacing for identity and reads the pool fee separately."
          },
          "tickSpacing": {
            "type": "integer",
            "minimum": 0,
            "maximum": 32767,
            "description": "Positive for V4 and Ramses CL, zero otherwise. Ramses accepts 1 through 32767 and verifies canonical factory identity."
          },
          "hooks": {
            "const": "0x0000000000000000000000000000000000000000"
          },
          "nativePool": {
            "type": "boolean",
            "description": "V4 native-currency pool; false for other protocols."
          }
        },
        "required": [
          "adapter",
          "tokenOut",
          "fee",
          "tickSpacing",
          "hooks",
          "nativePool"
        ],
        "additionalProperties": false
      },
      "PlanBranch": {
        "type": "object",
        "properties": {
          "amountIn": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "Exact input in base units; maximum 170141183460469231731687303715884105727 (2^127 - 1)."
          },
          "legs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlanLeg"
            },
            "minItems": 1,
            "maxItems": 3
          }
        },
        "required": [
          "amountIn",
          "legs"
        ],
        "additionalProperties": false
      },
      "HybridQuote": {
        "type": "object",
        "properties": {
          "version": {
            "const": 2
          },
          "provider": {
            "type": "string",
            "enum": [
              "route",
              "kyber",
              "zerox"
            ],
            "description": "route = direct engine; kyber and zerox = upstream routes with Route settlement protection. Check enabledProviders; 0x uses a separate executor."
          },
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "router": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "tokenIn": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "tokenOut": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "amountIn": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "Exact input in base units; maximum 170141183460469231731687303715884105727 (2^127 - 1)."
          },
          "grossAmountOut": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$"
          },
          "feeAmount": {
            "const": "0"
          },
          "protocolFeeBps": {
            "const": 0
          },
          "amountOut": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "Estimated user output before gas. Route adds no fee; equals grossAmountOut."
          },
          "minimumSuggested": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "User minimum using the source 0.5% tolerance, rounded down. A 0x inner minimum can be stricter than a user-selected outer tolerance."
          },
          "blockNumber": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "blockHash": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{64}$"
          },
          "blockPinned": {
            "type": "boolean",
            "description": "true only for direct Route quotes. For upstream quotes, blockNumber is a reference, not the pricing block."
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix seconds. Quotes reserve no liquidity."
          },
          "branches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlanBranch"
            },
            "maxItems": 3,
            "description": "Submit for provider=route; empty for kyber/zerox. Server rebuilds upstream calldata."
          },
          "routes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "amountIn": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                },
                "amountOut": {
                  "type": "string",
                  "pattern": "^[0-9]+$",
                  "description": "Branch output; no Route fee is deducted."
                },
                "venues": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "pools": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "tokens": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  }
                }
              },
              "required": [
                "amountIn",
                "amountOut",
                "venues",
                "pools",
                "tokens"
              ],
              "additionalProperties": false
            },
            "description": "Direct/Kyber branch details. 0x supplies one aggregate route with source names and endpoint tokens; pools is empty because pool identities and per-branch amounts are not supplied."
          },
          "gasEstimate": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "gasCostWei": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "gasCostInOutput": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$"
          },
          "netAmountOut": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^-?[0-9]+$",
            "description": "Simulated user output, when available, otherwise quoted user output, minus estimated gas converted to output-token units. Conversion is a model, not an oracle. May be negative; excludes a separate approval."
          },
          "priceImpactBps": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Approximate comparison with a smaller route quote, not an oracle. Null when unavailable."
          },
          "candidatePaths": {
            "type": "integer",
            "minimum": 0
          },
          "poolsConsidered": {
            "type": "integer",
            "minimum": 0
          },
          "quoteCalls": {
            "type": "integer",
            "minimum": 0,
            "description": "Direct engine: unique pool/direction/exact-input reads at the pinned block, up to 360. Shared path legs reuse those reads within this request only. Discovery and execution-assessment RPCs are separate. Upstream reports its quote request count."
          },
          "coverage": {
            "type": "string",
            "enum": [
              "bounded-verified-pools",
              "upstream-aggregated"
            ]
          },
          "gasAdjusted": {
            "type": "boolean"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Coverage and execution caveats. Listing hints may be retained for up to two minutes only after transient failures, with fresh onchain verification and an explicit warning; access denial and malformed data revoke retained hints. Failed initial/neighbor listing fetches and factory reads reduce coverage; listing categories are sanitized, never raw upstream errors. Final gas warnings use returned assessed output and modeled gas conversion, not just preliminary estimates. Successful simulation does not imply positive net value. Warnings are advisory and do not change transaction limits."
          },
          "latencyMs": {
            "type": "integer",
            "minimum": 0
          },
          "variant": {
            "$ref": "#/components/schemas/QuoteVariant"
          },
          "execution": {
            "$ref": "#/components/schemas/ExecutionAssessment"
          },
          "comparison": {
            "type": "object",
            "properties": {
              "candidates": {
                "type": "array",
                "minItems": 1,
                "maxItems": 6,
                "items": {
                  "$ref": "#/components/schemas/RouteAssessment"
                }
              },
              "blockNumber": {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              "basis": {
                "type": "string",
                "enum": [
                  "gas-adjusted-output",
                  "output-only"
                ]
              },
              "unavailableRequests": {
                "type": "integer",
                "minimum": 0,
                "description": "Quote/build requests that failed before assessment; not a unique venue count."
              },
              "duplicateQuotes": {
                "type": "integer",
                "minimum": 0,
                "description": "Identical successful provider quotes combined before assessment."
              }
            },
            "required": [
              "candidates",
              "blockNumber",
              "basis",
              "unavailableRequests",
              "duplicateQuotes"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "version",
          "provider",
          "chainId",
          "router",
          "tokenIn",
          "tokenOut",
          "amountIn",
          "grossAmountOut",
          "feeAmount",
          "protocolFeeBps",
          "amountOut",
          "minimumSuggested",
          "blockNumber",
          "blockHash",
          "blockPinned",
          "expiresAt",
          "branches",
          "routes",
          "gasEstimate",
          "gasCostWei",
          "gasCostInOutput",
          "netAmountOut",
          "priceImpactBps",
          "candidatePaths",
          "poolsConsidered",
          "quoteCalls",
          "coverage",
          "gasAdjusted",
          "warnings",
          "latencyMs",
          "execution",
          "comparison"
        ],
        "additionalProperties": false
      },
      "HybridSwapRequest": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "tokenIn": {
            "type": "string",
            "pattern": "^(ETH|0x[0-9a-fA-F]{40})$",
            "description": "Native ETH or an ERC-20 address on chain 4663. Zero address also means native ETH. Do not pass other token symbols."
          },
          "tokenOut": {
            "type": "string",
            "pattern": "^(ETH|0x[0-9a-fA-F]{40})$",
            "description": "Native ETH or an ERC-20 address on chain 4663. Zero address also means native ETH. Do not pass other token symbols."
          },
          "amountIn": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "Exact input in base units; maximum 170141183460469231731687303715884105727 (2^127 - 1)."
          },
          "provider": {
            "type": "string",
            "enum": [
              "route",
              "kyber",
              "zerox"
            ],
            "description": "route = direct engine; kyber and zerox = upstream routes with Route settlement protection. Check enabledProviders; 0x uses a separate executor.",
            "default": "route"
          },
          "amountOutMinimum": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "User-selected signed minimum received by the user; must be at least 95% of the fresh user server estimate."
          },
          "recipient": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Nonzero recipient other than either settlement executor."
          },
          "deadline": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix seconds, after now and at most 1200 seconds ahead."
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Fresh quote expiry, after now and at most 30 seconds ahead. This freshness hint is not a quote signature; the server re-quotes."
          },
          "branches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlanBranch"
            },
            "maxItems": 3,
            "description": "1 to 3 branches summing to exact input for route; empty for kyber/zerox."
          },
          "variant": {
            "$ref": "#/components/schemas/QuoteVariant"
          },
          "txOrigin": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Required only for zerox: the signing EOA/actual transaction origin, not the output recipient or Route executor. Relayed smart-account/bundler origins are not supported by the current wallet flow."
          }
        },
        "required": [
          "chainId",
          "tokenIn",
          "tokenOut",
          "amountIn",
          "amountOutMinimum",
          "recipient",
          "deadline",
          "expiresAt",
          "branches"
        ],
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "provider": {
                  "const": "zerox"
                }
              },
              "required": [
                "provider"
              ]
            },
            "then": {
              "required": [
                "txOrigin"
              ],
              "properties": {
                "branches": {
                  "maxItems": 0
                }
              }
            },
            "else": {
              "not": {
                "required": [
                  "txOrigin"
                ]
              }
            }
          }
        ]
      },
      "HybridSwapResponse": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer",
            "const": 4663
          },
          "transaction": {
            "$ref": "#/components/schemas/Transaction"
          },
          "approval": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  },
                  "spender": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[1-9][0-9]{0,77}$",
                    "description": "A positive integer in token base units, no larger than uint256."
                  },
                  "transaction": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                },
                "required": [
                  "token",
                  "spender",
                  "amount",
                  "transaction"
                ],
                "additionalProperties": false
              }
            ]
          },
          "simulationRequired": {
            "type": "boolean",
            "const": true
          },
          "grossAmountOut": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$"
          },
          "feeAmount": {
            "const": "0"
          },
          "protocolFeeBps": {
            "const": 0
          },
          "amountOut": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "Estimated user output before gas. Route adds no fee; equals grossAmountOut."
          },
          "blockNumber": {
            "type": "string",
            "pattern": "^[0-9]+$"
          }
        },
        "required": [
          "chainId",
          "transaction",
          "approval",
          "simulationRequired",
          "grossAmountOut",
          "feeAmount",
          "protocolFeeBps",
          "amountOut"
        ],
        "additionalProperties": false
      },
      "QuoteVariant": {
        "type": "string",
        "enum": [
          "balanced",
          "max-output",
          "single-path",
          "no-fee-hooks"
        ],
        "description": "Kyber only: gas-aware default, output-focused, single-path, or exclude the specific uniswap-v4-fee source. The last variant does not exclude all hooked pools. Pass the selected quote variant when rebuilding."
      },
      "ExecutionAssessment": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "simulated",
              "unavailable"
            ]
          },
          "amountOut": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Actual user output returned by read-only full-transaction simulation; null when unavailable. May differ from original amountOut. Not a future fill guarantee."
          },
          "blockNumber": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "blockHash": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{64}$"
          },
          "gasSource": {
            "type": "string",
            "enum": [
              "rpc-estimate",
              "heuristic"
            ]
          },
          "gasPrice": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Explicit positive gas price in wei attempted for full-transaction eth_call and estimateGas, floored at the checked block base fee. Successful checks also use this price for gas-cost ranking. Null when fixture checks prevented full execution. An unavailable result with a price is still unverified; its gas-cost fields remain heuristic. Gas-price-sensitive hooks may produce different output when fees change."
          },
          "failure": {
            "type": "object",
            "properties": {
              "stage": {
                "type": "string",
                "enum": [
                  "call",
                  "estimateGas",
                  "fixture",
                  "unknown"
                ]
              },
              "reason": {
                "type": "string",
                "enum": [
                  "rate-limited",
                  "access-denied",
                  "timeout",
                  "resource-limit",
                  "gas-price-rejected",
                  "state-unavailable",
                  "method-unsupported",
                  "request-rejected",
                  "network",
                  "unknown",
                  "layout-unverified"
                ]
              }
            },
            "required": [
              "stage",
              "reason"
            ],
            "additionalProperties": false,
            "description": "Present for unavailable execution checks. Sanitized diagnostic category only, not raw RPC text or proof of root cause. Never makes an unverified quote executable. layout-unverified can include missing or failed storage probes."
          }
        },
        "required": [
          "status",
          "amountOut",
          "blockNumber",
          "blockHash",
          "gasSource",
          "gasPrice"
        ],
        "additionalProperties": false
      },
      "RouteAssessment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^candidate-[0-9]+$",
            "description": "Unique only within this comparison, not a permanent route ID."
          },
          "provider": {
            "type": "string",
            "enum": [
              "route",
              "kyber",
              "zerox"
            ],
            "description": "route = direct engine; kyber and zerox = upstream routes with Route settlement protection. Check enabledProviders; 0x uses a separate executor."
          },
          "status": {
            "type": "string",
            "enum": [
              "build-rejected",
              "simulated",
              "layout-unavailable",
              "rpc-unavailable",
              "reverted",
              "expired"
            ]
          },
          "selected": {
            "type": "boolean"
          },
          "eligible": {
            "type": "boolean",
            "description": "Was included in the final ranking. Candidates that pass simulation rank ahead of unverified alternatives."
          },
          "rank": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Final ranking, starting at 1; null for excluded candidates. The swap graph shows up to five assessments, with ranked candidates first and remaining assessments in their original order. All assessments remain in this API response."
          },
          "quotedAmountOut": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,77}$",
            "description": "Estimated user output before gas. Route adds no fee; equals grossAmountOut."
          },
          "simulatedAmountOut": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$"
          },
          "gasCostWei": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]+$",
            "description": "Only present as a value for a successful, fresh simulation; otherwise null."
          },
          "netAmountOut": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^-?[0-9]+$",
            "description": "Simulated output less estimated gas under the same conversion model used for ranking. Null for unverified/failed/expired candidates or missing conversion; excludes approval gas."
          },
          "routes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "amountIn": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                },
                "amountOut": {
                  "type": "string",
                  "pattern": "^[0-9]+$",
                  "description": "Branch output; no Route fee is deducted."
                },
                "venues": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "pools": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "tokens": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$"
                  }
                }
              },
              "required": [
                "amountIn",
                "amountOut",
                "venues",
                "pools",
                "tokens"
              ],
              "additionalProperties": false
            },
            "description": "Direct/Kyber branch details. 0x supplies one aggregate route with source names and endpoint tokens; pools is empty because pool identities and per-branch amounts are not supplied."
          },
          "variant": {
            "$ref": "#/components/schemas/QuoteVariant"
          }
        },
        "required": [
          "id",
          "provider",
          "status",
          "selected",
          "eligible",
          "rank",
          "quotedAmountOut",
          "simulatedAmountOut",
          "gasCostWei",
          "netAmountOut",
          "routes"
        ],
        "additionalProperties": false
      }
    }
  },
  "security": []
}
