> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raze.bot/llms.txt
> Use this file to discover all available pages before exploring further.

# Build an EVM swap (/swap-instructions)

> The same handler as `POST /evm/swap`: same body, same response, under the path name a
Solana or Jupiter client calls. On EVM there are no instructions to assemble: the answer is
the unsigned transactions, `setupTransactions` (the approvals) then `swapTransaction`, to
sign and send in that order.


The same handler as [`POST /evm/swap`](/api-reference/router/evm-swap), under the path name Solana and Jupiter clients call.

<Note>
  On EVM there are no instructions to assemble: the answer is the unsigned transactions, `setupTransactions` (the approvals) then `swapTransaction`, to sign and send in that order. See [EVM swaps](/router/evm#the-swap).
</Note>


## OpenAPI

````yaml router.openapi.yaml POST /evm/swap-instructions
openapi: 3.1.0
info:
  title: Raze Swap Router API
  version: 1.0.0
  description: >
    Quotes and **unsigned** transactions for swaps on Solana, routed through a
    deploy of the `swap`

    program over the venues `GET /venues` lists as `buildable` and `servable`,
    and, under `/evm`, on

    Ethereum, BNB Chain, Base and Robinhood Chain (see **EVM routes** below).
    The router **never

    signs and never sends**: you get a quote, then the instructions (or a
    serialized, unsigned

    transaction), and you sign and broadcast from your backend.


    **Public router.** `https://router.raze.bot` is Raze's router. It takes the
    same **API key** as

    the market-data API (`x-api-key`, `Authorization: Bearer` or `?apiKey=`;
    only `/health`,

    `/ready`, `/evm/health` and `/evm/ready` are open), shares the account's
    limit a

    minute with it and spends credits for each request it lets in. Its Solana
    routes have no path

    prefix (`/quote`, `/swap-instructions`, …),

    issues no `routeTicket`, and builds for Raze's deploy of the `swap` program,

    `DADMMjfNnY6z8H9h9RfHZ9tfarBySsj4Yb65qLyKJDAD`. A missing or unknown key
    answers `401` and a

    request over the limit `429`, both with the API's body,

    `{"error": {"code": "unauthorized" | "rate_limited", "message"}}`.


    **EVM routes (`/evm`).** The same host quotes and builds swaps on Ethereum
    (`eth`, chain id 1),

    BNB Chain (`bsc`, 56), Base (`base`, 8453) and Robinhood Chain (`robinhood`,
    4663), over Uniswap

    V2 and V3 (eth, base, robinhood) and PancakeSwap V2 and V3 (bsc): `GET` and
    `POST /evm/quote`,

    `POST /evm/swap` (alias `POST /evm/swap-instructions`), `GET /evm/venues`,
    `GET /evm/chains`,

    and the open `GET /evm/health` and `GET /evm/ready`. Same key, same limit a
    minute, same

    credits. They speak the Solana routes' API, so Jupiter's: the same parameter
    and field names

    (`inputMint`, `outputMint`, `amount`, `slippageBps`, `routePlan`,
    `otherAmountThreshold`,

    `quoteResponse`, `userPublicKey`, …), the conventions and the error shape
    below, `404 not_found`

    for an unknown path (`/evm/build` and `/evm/deployments` are gone) and `405`
    with `Allow` for a

    wrong method. What differs, because EVM does:

    - `chain` is required: `eth`, `bsc`, `base`, `robinhood` or the chain id
    (alias `chainId`).

    - Mints and wallets are `0x` addresses in any case (answers are lower case);
    the native coin is
      `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` (or `native`). Inside a `routePlan` the wrapped
      token stands for it.
    - Amounts are uint256 in base units: decimal strings of any size, or JSON
    integers up to
      2^64 − 1. `contextSlot` is the block number.
    - ExactIn only (`ExactOut` is `400`), `maxHops` at most 3 (default 2), one
    venue per route, no
      split, no platform fee (`platformFeeBps` or `feeBps` above 0 is `400`, not ignored).
    - The build returns unsigned transactions instead of instructions:
    `setupTransactions` (the
      approvals), then `swapTransaction`, simulated together, that you sign and send in order from
      your own RPC. It builds only a quote this router made and still holds (`quoteResponse.quoteId`),
      and a `quoteResponse` that says otherwise about it is `400 quote_mismatch`.
    - Errors carry no `quoteId`. A request is cut at 10 seconds (`503 rpc`,
    `request_timeout`).


    **One router, one `swap` deploy.** A router builds for the program address
    in its

    `ROUTER_SWAP_PROGRAM_ID` (the `programId` of every `swapInstruction` is that
    address) and

    reads that deploy's on-chain config: a venue the config has no live row for
    is never served,

    and while the config is paused every build answers `503`. A client with its
    own deploy runs

    its own router: it has no keys, no accounts and no rate limit and listens on
    loopback by

    default (`ROUTER_LISTEN`), so keep it behind your own gateway.


    **Conventions of the Solana routes:**

    - Amounts are integers in the token's base units (lamports, atoms). In
    quotes and builds the
      u64 amounts are decimal **strings** (`inAmount`, `outAmount`, `otherAmountThreshold`,
      `swapInfo.inAmount` / `outAmount`, `platformFee.amount`, every `costs.*Lamports*` field).
      `slippageBps`, `contextSlot`, `minReturn`, `maxAmountIn`, `computeUnits`,
      `loadedAccountsDataSize`, `lastValidBlockHeight` and every `transactionConfig` field are JSON
      numbers.
    - Mints and wallets are base58 addresses; wrapped SOL is
    `So11111111111111111111111111111111111111112`.

    - Venue labels (`label`, `dexes`, `excludeDexes`) are the `dex` names of
    `GET /venues`; input
      labels match case- and punctuation-insensitively, aliases included.
    - Request bodies are read as JSON whatever the `Content-Type`; at most 256
    KiB (larger is `413`).

    - Unknown fields and query parameters are ignored, not rejected.


    **Solana transactions are v1** (SIMD-0385, prefix `0x81`, up to 4,096 bytes
    and 64 account keys, no

    address lookup tables). The compute-unit limit, loaded-accounts limit and
    priority fee travel in

    the message header (`transactionConfig`), not as ComputeBudget instructions.
    Signing a v1

    transaction needs an SDK that supports it. `txVersion: 0` and
    `asLegacyTransaction: true` are

    refused.


    **Errors** of the Solana routes are `{"error", "reason", "quoteId"}`:
    `error` is a closed code, `reason` a label or a

    sentence, `quoteId` present once the request was parsed. The status says
    whose move it is:

    `400` fix the request, `404` no route exists (or an unknown path:
    `not_found`), `409` re-quote

    or retry later, `413` too large, `422` a named decline that waiting will not
    change, `500` a

    router bug, `503` not ready: retry with backoff. Two bodies differ:
    `not_ready` carries

    `reasons` (a list) instead of `reason`, and a `low_liquidity` decline adds
    `liquidity`. A known

    path with the wrong method (`GET /swap`) is `405` with an empty body and an
    `Allow` header.


    The Solana quote and swap fields mirror Jupiter's Swap API (Metis), so most
    clients change only the

    host; differences are listed on each operation.
servers:
  - url: https://router.raze.bot
    description: Raze's public router (API key)
security:
  - ApiKeyHeader: []
  - Bearer: []
  - ApiKeyQuery: []
tags:
  - name: ops
    description: Liveness and readiness
  - name: venues
    description: The venues this router knows, and the price oracle's verdict on each
  - name: swap
    description: Quote, then build the instructions or the unsigned transaction
  - name: transactions
    description: Serialize your own instructions as an unsigned v1 transaction
  - name: EVM swap
    description: >-
      Quote and build swaps on Ethereum, BNB Chain, Base and Robinhood Chain,
      under /evm
  - name: EVM catalog
    description: The EVM chains, their policy and the venue manifest
  - name: EVM ops
    description: Liveness and readiness of the EVM routes
paths:
  /evm/swap-instructions:
    post:
      tags:
        - EVM swap
      summary: Build an EVM swap (alias of /evm/swap)
      description: >
        The same handler as `POST /evm/swap`: same body, same response, under
        the path name a

        Solana or Jupiter client calls. On EVM there are no instructions to
        assemble: the answer is

        the unsigned transactions, `setupTransactions` (the approvals) then
        `swapTransaction`, to

        sign and send in that order.
      operationId: evmSwapInstructions
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EvmSwapRequest'
            example:
              userPublicKey: '0x000000000000000000000000000000000000dEaD'
              quoteId: b00fb006-1e11-4498-9d81-6d5d0857ef87
      responses:
        '200':
          $ref: '#/components/responses/EvmSwap'
        '400':
          $ref: '#/components/responses/EvmSwapBadRequest'
        '401':
          $ref: '#/components/responses/EvmUnauthorized'
        '404':
          $ref: '#/components/responses/EvmNoRoute'
        '409':
          $ref: '#/components/responses/EvmSwapConflict'
        '413':
          $ref: '#/components/responses/TooLarge'
        '422':
          $ref: '#/components/responses/EvmSwapDeclined'
        '429':
          $ref: '#/components/responses/EvmRateLimited'
        '503':
          $ref: '#/components/responses/EvmNotReady'
components:
  schemas:
    EvmSwapRequest:
      type: object
      required:
        - userPublicKey
      properties:
        userPublicKey:
          $ref: '#/components/schemas/EvmAddress'
          description: >-
            The wallet that signs and sends every transaction and pays the
            input: the `from` of each. Alias `wallet`
        quoteResponse:
          $ref: '#/components/schemas/EvmQuoteResponse'
          description: >-
            A quote of this router, sent back unchanged: its `quoteId` is what
            is built. Its `chain`, `inputMint`, `outputMint`, `inAmount`,
            `outAmount`, `otherAmountThreshold` and `slippageBps`, when present,
            must be the stored quote's (`400 quote_mismatch`): a new slippage
            goes in the top-level `slippageBps`
        quoteId:
          type: string
          format: uuid
          description: 'Instead of `quoteResponse`: the id of the quote to build'
        destinationTokenAccount:
          $ref: '#/components/schemas/EvmAddress'
          description: >-
            The address that receives the output. Default `userPublicKey`; must
            equal it for a wrap or an unwrap (`422 declined
            recipient_unsupported`). Alias `recipient`
        slippageBps:
          type:
            - integer
            - string
          description: >-
            With a quote: a new floor for this build only, `outAmount × (10000 −
            slippageBps) / 10000` from the quote's `outAmount` (above 10000
            counts as 10000; no effect on a wrap or an unwrap). Pair mode: the
            quote's slippage, default 50
        chain:
          type:
            - string
            - integer
          description: >-
            Pair mode: as in `POST /evm/quote`. With a quote, if present, must
            be its chain
        inputMint:
          $ref: '#/components/schemas/EvmMint'
          description: >-
            Pair mode: the token you spend. With a quote, if present, must be
            its input
        outputMint:
          $ref: '#/components/schemas/EvmMint'
          description: >-
            Pair mode: the token you receive. With a quote, if present, must be
            its output
        amount:
          type:
            - string
            - integer
          description: >-
            Pair mode: as in `POST /evm/quote`. With a quote, if present, must
            be its `inAmount`
        swapMode:
          type: string
          enum:
            - ExactIn
            - exactIn
          description: Pair mode only
        maxHops:
          type:
            - integer
            - string
          description: Pair mode only
        onlyDirectRoutes:
          type: boolean
          description: Pair mode only
        dexes:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
          description: Pair mode only. Alias `includeDex`
        excludeDexes:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
          description: Pair mode only. Alias `excludeDex`
        feeBps:
          type:
            - integer
            - string
          const: 0
          description: >-
            Only 0: no platform fee on EVM (above 0 is `400`; so is
            `platformFeeBps`)
    EvmAddress:
      type: string
      pattern: ^0[xX][0-9a-fA-F]{40}$
      description: >-
        0x and 40 hex digits, any case (answers are lower case). The zero
        address is refused
    EvmQuoteResponse:
      type: object
      required:
        - inputMint
        - inAmount
        - outputMint
        - outAmount
        - otherAmountThreshold
        - swapMode
        - slippageBps
        - priceImpactPct
        - routePlan
        - contextSlot
        - timeTaken
        - quoteId
        - chain
        - chainId
        - router
        - gasEstimate
        - blockHash
        - expiresAt
        - candidates
      properties:
        inputMint:
          type: string
          description: >-
            Lower case; the native coin is
            `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`
        inAmount:
          type: string
          description: 'What you spend: the `amount` asked'
        outputMint:
          type: string
        outAmount:
          type: string
          description: >-
            What the route gives at the quote's block, in base units of
            `outputMint`, before any tax the token itself takes
        otherAmountThreshold:
          type: string
          description: >-
            The floor the swap will enforce on chain: `outAmount × (10000 −
            slippageBps) / 10000`, rounded down (`inAmount` for a wrap or an
            unwrap)
        swapMode:
          type: string
          const: ExactIn
        slippageBps:
          type: integer
        priceImpactPct:
          type: string
          const: '0'
          description: 'Not computed on EVM: always `0`'
        routePlan:
          type: array
          items:
            $ref: '#/components/schemas/EvmRoutePlanStep'
          description: One step per hop, in order
        contextSlot:
          type: integer
          description: The block number the quote was priced at
        timeTaken:
          type: number
          description: Seconds spent inside the router
        quoteId:
          type: string
          format: uuid
          description: What `POST /evm/swap` builds, until `expiresAt`
        chain:
          $ref: '#/components/schemas/EvmChainSlug'
        chainId:
          type: integer
        router:
          type: string
          description: >-
            The contract the swap transaction goes to: the venue's router (also
            the approvals' spender), or the wrapped token for a wrap or an
            unwrap
        gasEstimate:
          type: string
          description: >-
            Indicative (QuoterV2 on V3, a fixed estimate per hop on V2). The
            build's simulation gives the real figure
        blockHash:
          type: string
          description: The hash of the block the quote was priced at
        expiresAt:
          type: string
          format: date-time
          description: >-
            Until when the quote can be built: the chain's `quoteTtlSecs` after
            quoting (15 s; 30 s on `eth`)
        candidates:
          type: integer
          description: Routes priced (0 for a wrap or an unwrap)
    EvmMint:
      type: string
      description: >-
        A token: its address (`0x` and 40 hex digits, any case), or the chain's
        native coin, `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` or `native`.
        The zero address is refused. Answers write addresses in lower case, the
        native coin as `0xeeee…eeee`
      example: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
    EvmSwapResponse:
      type: object
      required:
        - setupTransactions
        - swapTransaction
        - quoteId
        - inAmount
        - outAmount
        - otherAmountThreshold
        - swapMode
        - slippageBps
        - routePlan
        - simulation
        - costs
        - spender
        - deadline
        - chain
        - chainId
        - contextSlot
        - blockHash
        - expiresAt
      properties:
        setupTransactions:
          type: array
          items:
            $ref: '#/components/schemas/EvmTransaction'
          description: >-
            The approvals, to send first and in order: none,
            `approve(inAmount)`, or `approve(0)` then `approve(inAmount)`
        swapTransaction:
          $ref: '#/components/schemas/EvmTransaction'
          description: The swap, to send after the approvals and before `deadline`
        quoteId:
          type: string
          format: uuid
          description: The quote built (in pair mode, the quote made for this call)
        inAmount:
          type: string
        outAmount:
          type: string
          description: >-
            The quote's `outAmount`. What arrives at the build's block is
            `simulation.outAmount`
        otherAmountThreshold:
          type: string
          description: >-
            The floor in the swap's calldata: the quote's, or moved by this
            build's `slippageBps`
        swapMode:
          type: string
          const: ExactIn
        slippageBps:
          type: integer
          description: The slippage of this build's floor
        routePlan:
          type: array
          items:
            $ref: '#/components/schemas/EvmRoutePlanStep'
        simulation:
          $ref: '#/components/schemas/EvmSimulation'
        costs:
          $ref: '#/components/schemas/EvmCosts'
        spender:
          type:
            - string
            - 'null'
          description: >-
            The venue's router the approvals are for, when the input is an
            ERC-20 swapped through a pool; `null` for a native input, a wrap or
            an unwrap
        deadline:
          type: integer
          description: >-
            Unix seconds: the swap reverts if mined later. The chain's
            `deadlineSecs` after the build (60 s; 180 s on `eth`)
        chain:
          $ref: '#/components/schemas/EvmChainSlug'
        chainId:
          type: integer
        contextSlot:
          type: integer
          description: The block number the build was read and simulated at
        blockHash:
          type: string
          description: That block's hash
        expiresAt:
          type: string
          format: date-time
          description: 'The quote''s expiry: until then it can be built again'
    EvmError:
      type: object
      description: >-
        An error of the EVM routes: the Solana routes' shape, without `quoteId`.
        `not_ready` carries `reasons` instead (`NotReadyError`)
      required:
        - error
        - reason
      properties:
        error:
          type: string
          enum:
            - bad_request
            - declined
            - quote_mismatch
            - route_expired
            - rpc
            - not_found
          description: Closed error code
        reason:
          type: string
          description: >-
            With `declined`, a stable label: `no_route`, `zero_amount`,
            `amount_too_small`, `quote_stale`, `recipient_unsupported`. With
            `rpc`, the kind of failure in lower case: `rpc_timeout`,
            `rpc_block_unavailable`, `rpc_unavailable`, `rpc_queue_full`,
            `request_timeout`, …. Otherwise a sentence for humans. Never your
            input, a URL, a key or a provider's message
        candidates:
          type: integer
          description: '`no_route`: routes tried'
        outAmount:
          type:
            - string
            - 'null'
          description: >-
            `quote_stale`: what the route gives now, `null` if it no longer
            executes
        otherAmountThreshold:
          type: string
          description: '`quote_stale`: the floor it had to reach'
    GateError:
      type: object
      description: >-
        The API key gate's error, the market-data API's shape: `unauthorized`
        (401) or `rate_limited` (429)
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - rate_limited
            message:
              type: string
    NotReadyError:
      type: object
      required:
        - error
        - reasons
      properties:
        error:
          type: string
          const: not_ready
        reasons:
          type: array
          items:
            type: string
          description: Every reason the router cannot serve this request now
        quoteId:
          type: string
    EvmRoutePlanStep:
      type: object
      required:
        - swapInfo
        - percent
        - bps
      properties:
        swapInfo:
          $ref: '#/components/schemas/EvmSwapInfo'
        percent:
          type: integer
          const: 100
          description: 'Always 100: EVM routes do not split'
        bps:
          type: integer
          const: 10000
    EvmChainSlug:
      type: string
      enum:
        - eth
        - bsc
        - base
        - robinhood
      description: '`eth` (chain id 1), `bsc` (56), `base` (8453), `robinhood` (4663)'
    EvmTransaction:
      type: object
      description: >-
        An unsigned transaction: add the nonce, sign it with the key of `from`
        and send it
      required:
        - chainId
        - from
        - to
        - data
        - value
      properties:
        chainId:
          type: integer
        from:
          type: string
          description: '`userPublicKey`'
        to:
          type: string
          description: >-
            The input token (an approval), the venue's router (a swap) or the
            wrapped token (a wrap or an unwrap)
        data:
          type: string
          description: Calldata, hex
        value:
          type: string
          description: >-
            Wei to send, decimal: `inAmount` when the input is native, otherwise
            `0`
        gas:
          type: string
          description: >-
            Gas limit, decimal: the simulated gas × the chain's `gasHeadroomPct`
            / 100. Present only when the simulation passed
        maxFeePerGas:
          type: string
          description: >-
            Wei per gas, decimal: 2 × the next block's base fee + the tip.
            Present when the router could read the chain's fees
        maxPriorityFeePerGas:
          type: string
          description: >-
            Wei per gas: the median tip of recent blocks, never under the
            chain's `minPriorityFeeWei`. Present when the router could read the
            chain's fees
    EvmSimulation:
      description: >-
        The approvals and the swap, executed in order at the build's block
        before you send anything
      oneOf:
        - type: object
          title: passed
          required:
            - status
            - outAmount
            - gasUsed
          properties:
            status:
              type: string
              const: passed
            outAmount:
              type: string
              description: 'What arrived at the recipient: at least `otherAmountThreshold`'
            gasUsed:
              type: array
              items:
                type: string
              description: Per transaction, the approvals then the swap
        - type: object
          title: failed
          required:
            - status
            - reason
            - transaction
            - revertReason
          properties:
            status:
              type: string
              const: failed
            reason:
              type: string
              enum:
                - insufficient_balance
                - approval_reverted
                - swap_reverted
                - partial_fill
                - output_below_minimum
                - unexpected_output
                - out_of_gas
              description: >-
                `insufficient_balance`: the sender holds less than `inAmount`
                (nothing simulated). `approval_reverted`, `swap_reverted`: that
                transaction reverted. `partial_fill`: the pool took less than
                `inAmount`. `output_below_minimum`: less than the floor arrived
                (a token that taxes transfers). `unexpected_output`,
                `out_of_gas`: only on a node without `eth_simulateV1`
            transaction:
              type:
                - integer
                - 'null'
              description: >-
                Index of the failing transaction in `setupTransactions` + the
                swap (the swap is last); `null` with `insufficient_balance`
            revertReason:
              type:
                - string
                - 'null'
              description: The contract's `Error(string)` message, when it gave one
        - type: object
          title: requires_approval
          required:
            - status
            - reason
          properties:
            status:
              type: string
              const: requires_approval
            reason:
              type: string
              description: >-
                A sentence: the router's node cannot simulate the approvals and
                the swap in sequence
        - type: object
          title: not_simulated
          required:
            - status
            - reason
          properties:
            status:
              type: string
              const: not_simulated
            reason:
              type: string
              description: >-
                An RPC error code in lower case (`rpc_timeout`, …), or
                `balance_unreadable`
    EvmCosts:
      type: object
      description: >-
        What the transactions cost besides the input, in wei as decimal strings;
        `null` where unknown
      required:
        - gas
        - baseFeePerGas
        - maxPriorityFeePerGas
        - maxFeePerGas
        - gasPrice
        - maxNetworkFeeWei
      properties:
        gas:
          type:
            - string
            - 'null'
          description: >-
            The `gas` limits of every transaction added up; `null` unless the
            simulation passed
        baseFeePerGas:
          type:
            - string
            - 'null'
          description: The next block's base fee
        maxPriorityFeePerGas:
          type:
            - string
            - 'null'
          description: The tip each transaction carries
        maxFeePerGas:
          type:
            - string
            - 'null'
          description: 2 × `baseFeePerGas` + the tip
        gasPrice:
          type:
            - string
            - 'null'
          description: >-
            For a legacy (type 0) transaction: the node's gas price, at least
            `baseFeePerGas` + the tip
        maxNetworkFeeWei:
          type:
            - string
            - 'null'
          description: >-
            `gas` × `maxFeePerGas`: the most the transactions can pay in network
            fees
    EvmSwapInfo:
      type: object
      required:
        - ammKey
        - label
        - inputMint
        - outputMint
        - inAmount
        - outAmount
      properties:
        ammKey:
          type: string
          description: The pool; for a wrap or an unwrap, the wrapped-token contract
        label:
          type: string
          description: >-
            The venue's `dex` label (`Uniswap V3`, `PancakeSwap V2`, …), or
            `Wrap` / `Unwrap`
        inputMint:
          type: string
          description: >-
            The hop's input. Inside a route the wrapped token stands for the
            native coin; a `Wrap` step's input is the native coin
        outputMint:
          type: string
          description: The hop's output; an `Unwrap` step's output is the native coin
        inAmount:
          type: string
          description: Input of this hop, in base units
        outAmount:
          type: string
          description: Output of this hop, in base units
        feeTier:
          type: integer
          description: >-
            V3 only: the pool's fee tier in hundredths of a basis point (`100`
            is 0.01%, `3000` is 0.3%)
  responses:
    EvmSwap:
      description: >-
        The unsigned transactions and their simulation (live answers of the
        public router; `0x…dEaD` is a burn address that happens to hold ETH and
        USDC on Base, used so the simulations could pass)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EvmSwapResponse'
          examples:
            sell:
              summary: 2 USDC to ETH on Base, with its approval (simulation passed)
              value:
                setupTransactions:
                  - chainId: 8453
                    from: '0x000000000000000000000000000000000000dead'
                    to: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'
                    data: >-
                      0x095ea7b30000000000000000000000002626664c2603336e57b271c5c0b26f421741e48100000000000000000000000000000000000000000000000000000000001e8480
                    value: '0'
                    gas: '66525'
                    maxFeePerGas: '11000000'
                    maxPriorityFeePerGas: '1000000'
                swapTransaction:
                  chainId: 8453
                  from: '0x000000000000000000000000000000000000dead'
                  to: '0x2626664c2603336e57b271c5c0b26f421741e481'
                  data: >-
                    0x5ae401dc000000000000000000000000000000000000000000000000000000006ac964be00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000104b858183f000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000002626664c2603336e57b271c5c0b26f421741e48100000000000000000000000000000000000000000000000000000000001e84800000000000000000000000000000000000000000000000000002d5f2f9161ee5000000000000000000000000000000000000000000000000000000000000002b833589fcd6edb6e08f4c7c32d4f71b54bda02913000064420000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c0000000000000000000000000000000000000000000000000002d5f2f9161ee5000000000000000000000000000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000
                  value: '0'
                  gas: '166575'
                  maxFeePerGas: '11000000'
                  maxPriorityFeePerGas: '1000000'
                quoteId: 0d40a5e0-21ea-498c-a753-402ddf896cdf
                inAmount: '2000000'
                outAmount: '806252011312846'
                otherAmountThreshold: '798189491199717'
                swapMode: ExactIn
                slippageBps: 100
                routePlan:
                  - swapInfo:
                      ammKey: '0xb4cb800910b228ed3d0834cf79d697127bbb00e5'
                      label: Uniswap V3
                      inputMint: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'
                      outputMint: '0x4200000000000000000000000000000000000006'
                      inAmount: '2000000'
                      outAmount: '806252011312846'
                      feeTier: 100
                    percent: 100
                    bps: 10000
                simulation:
                  status: passed
                  outAmount: '806252011312846'
                  gasUsed:
                    - '55437'
                    - '138812'
                costs:
                  gas: '233100'
                  baseFeePerGas: '5000000'
                  maxPriorityFeePerGas: '1000000'
                  maxFeePerGas: '11000000'
                  gasPrice: '6000000'
                  maxNetworkFeeWei: '2564100000000'
                spender: '0x2626664c2603336e57b271c5c0b26f421741e481'
                deadline: 1791583422
                chain: base
                chainId: 8453
                contextSlot: 52397007
                blockHash: >-
                  0xf5eb59efc9cf90b49a959ea3596ac0d21b468d5face1048ab1a1c2bb7aab5d65
                expiresAt: '2026-10-09T22:02:57.037886707Z'
            buy:
              summary: >-
                0.001 ETH to USDC on Base, no approval (simulation passed;
                calldata trimmed)
              value:
                setupTransactions: []
                swapTransaction:
                  chainId: 8453
                  from: '0x000000000000000000000000000000000000dead'
                  to: '0x2626664c2603336e57b271c5c0b26f421741e481'
                  data: >-
                    0x5ae401dc000000000000000000000000000000000000000000000000000000006ac964ca…
                  value: '1000000000000000'
                  gas: '149152'
                  maxFeePerGas: '11000000'
                  maxPriorityFeePerGas: '1000000'
                quoteId: b00fb006-1e11-4498-9d81-6d5d0857ef87
                inAmount: '1000000000000000'
                outAmount: '2480114'
                otherAmountThreshold: '2455312'
                swapMode: ExactIn
                slippageBps: 100
                routePlan:
                  - swapInfo:
                      ammKey: '0xb4cb800910b228ed3d0834cf79d697127bbb00e5'
                      label: Uniswap V3
                      inputMint: '0x4200000000000000000000000000000000000006'
                      outputMint: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'
                      inAmount: '1000000000000000'
                      outAmount: '2480114'
                      feeTier: 100
                    percent: 100
                    bps: 10000
                simulation:
                  status: passed
                  outAmount: '2480114'
                  gasUsed:
                    - '124293'
                costs:
                  gas: '149152'
                  baseFeePerGas: '5000000'
                  maxPriorityFeePerGas: '1000000'
                  maxFeePerGas: '11000000'
                  gasPrice: '6000000'
                  maxNetworkFeeWei: '1640672000000'
                spender: null
                deadline: 1791583434
                chain: base
                chainId: 8453
                contextSlot: 52397013
                blockHash: >-
                  0x94b181d0afdb8e403980c281785a1d2d3df7a2cd0296551ec976fc907fe84233
                expiresAt: '2026-10-09T22:03:09.343704617Z'
            emptyWallet:
              summary: >-
                The same quote for a wallet without ETH (simulation failed, no
                gas; calldata trimmed)
              value:
                setupTransactions: []
                swapTransaction:
                  chainId: 8453
                  from: '0xe5fee928c6efe569f7416b65550f61215e1eabcb'
                  to: '0x2626664c2603336e57b271c5c0b26f421741e481'
                  data: >-
                    0x5ae401dc000000000000000000000000000000000000000000000000000000006ac964ca…
                  value: '1000000000000000'
                  maxFeePerGas: '11000000'
                  maxPriorityFeePerGas: '1000000'
                quoteId: b00fb006-1e11-4498-9d81-6d5d0857ef87
                inAmount: '1000000000000000'
                outAmount: '2480114'
                otherAmountThreshold: '2455312'
                swapMode: ExactIn
                slippageBps: 100
                routePlan:
                  - swapInfo:
                      ammKey: '0xb4cb800910b228ed3d0834cf79d697127bbb00e5'
                      label: Uniswap V3
                      inputMint: '0x4200000000000000000000000000000000000006'
                      outputMint: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'
                      inAmount: '1000000000000000'
                      outAmount: '2480114'
                      feeTier: 100
                    percent: 100
                    bps: 10000
                simulation:
                  status: failed
                  reason: insufficient_balance
                  transaction: null
                  revertReason: null
                costs:
                  gas: null
                  baseFeePerGas: '5000000'
                  maxPriorityFeePerGas: '1000000'
                  maxFeePerGas: '11000000'
                  gasPrice: '6000000'
                  maxNetworkFeeWei: null
                spender: null
                deadline: 1791583434
                chain: base
                chainId: 8453
                contextSlot: 52397013
                blockHash: >-
                  0x94b181d0afdb8e403980c281785a1d2d3df7a2cd0296551ec976fc907fe84233
                expiresAt: '2026-10-09T22:03:09.343704617Z'
            wrap:
              summary: Wrap 0.001 ETH (deposit)
              value:
                setupTransactions: []
                swapTransaction:
                  chainId: 8453
                  from: '0x000000000000000000000000000000000000dead'
                  to: '0x4200000000000000000000000000000000000006'
                  data: '0xd0e30db0'
                  value: '1000000000000000'
                  gas: '33320'
                  maxFeePerGas: '11000000'
                  maxPriorityFeePerGas: '1000000'
                quoteId: a25b0a96-bf12-4a84-9084-5535632763fc
                inAmount: '1000000000000000'
                outAmount: '1000000000000000'
                otherAmountThreshold: '1000000000000000'
                swapMode: ExactIn
                slippageBps: 50
                routePlan:
                  - swapInfo:
                      ammKey: '0x4200000000000000000000000000000000000006'
                      label: Wrap
                      inputMint: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
                      outputMint: '0x4200000000000000000000000000000000000006'
                      inAmount: '1000000000000000'
                      outAmount: '1000000000000000'
                    percent: 100
                    bps: 10000
                simulation:
                  status: passed
                  outAmount: '1000000000000000'
                  gasUsed:
                    - '27766'
                costs:
                  gas: '33320'
                  baseFeePerGas: '5000000'
                  maxPriorityFeePerGas: '1000000'
                  maxFeePerGas: '11000000'
                  gasPrice: '6000000'
                  maxNetworkFeeWei: '366520000000'
                spender: null
                deadline: 1791583441
                chain: base
                chainId: 8453
                contextSlot: 52397016
                blockHash: >-
                  0xc798c67b9f745116fd8defbc64e4117c737130b3c49928be0c92d2b8a8540b6d
                expiresAt: '2026-10-09T22:03:16.144660271Z'
    EvmSwapBadRequest:
      description: >
        Fix the request; retrying will not help. `error` is one of:

        `bad_request` (`userPublicKey` missing, not an address, or the zero
        address; a

        `quoteResponse` that is not an object or has no `quoteId`; a `quoteId`
        that is not a UUID;

        `feeBps` above 0; in pair mode, any quote parameter as in `POST
        /evm/quote`),

        `quote_mismatch` (a field of `quoteResponse`, or a top-level `chain`,
        `inputMint`,

        `outputMint` or `amount`, differs from the stored quote: `reason` names
        it), or `declined`

        with `zero_amount` (pair mode).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EvmError'
          examples:
            mismatch:
              summary: quoteResponse.outAmount altered
              value:
                error: quote_mismatch
                reason: quoteResponse.outAmount differs from the quote
            noUser:
              summary: userPublicKey missing (shape from the code)
              value:
                error: bad_request
                reason: userPublicKey is required
            noQuoteId:
              summary: A quoteResponse without quoteId (shape from the code)
              value:
                error: bad_request
                reason: >-
                  quoteResponse.quoteId is required: the EVM router builds only
                  the quotes it made
    EvmUnauthorized:
      description: >-
        A missing or unknown API key, or an account out of credits. The body is
        the API's, with its lower-case code.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GateError'
          example:
            error:
              code: unauthorized
              message: missing or unknown API key (send it as x-api-key)
    EvmNoRoute:
      description: >
        `declined` with `no_route`: no executable route on the verified venues
        of the chain under

        these filters and hop limit, with the number of routes tried
        (`candidates`). The pair has

        no pool on these venues, or no route gives a non-zero output for this
        amount. Not an RPC

        failure: those are `503 rpc`. Retrying the same request will not change
        it unless the

        market does.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EvmError'
          example:
            error: declined
            reason: no_route
            candidates: 4
    EvmSwapConflict:
      description: >
        Quote again, then build. `error` is `route_expired` (the router does not
        hold that quote:

        it expired, it was never made here, or the router restarted since) or
        `declined` with

        `quote_stale` (at the build's block the route gives less than
        `otherAmountThreshold`:

        `outAmount` is what it gives now, `null` if it no longer executes). A
        quote past

        `expiresAt` says so for two minutes; after that it is unknown.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EvmError'
          examples:
            unknown:
              summary: A quote this router does not hold
              value:
                error: route_expired
                reason: >-
                  this router does not hold that quote (expired, or made before
                  a restart): quote again
            expired:
              summary: Past expiresAt (from the router's tests)
              value:
                error: route_expired
                reason: 'the quote expired: quote again'
            stale:
              summary: The route no longer executes (shape from the code)
              value:
                error: declined
                reason: quote_stale
                outAmount: null
                otherAmountThreshold: '2455312'
    TooLarge:
      description: The request body is over 256 KiB (plain-text body)
      content:
        text/plain:
          schema:
            type: string
    EvmSwapDeclined:
      description: >
        A named decline that waiting will not change. `error` is `declined`;
        `reason` is

        `amount_too_small` (the floor would be zero: a `slippageBps` of 10000,
        or a pair-mode

        amount too small) or `recipient_unsupported` (a wrap or an unwrap to an
        address other

        than `userPublicKey`: wrapping credits the caller).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EvmError'
          examples:
            slippage:
              summary: slippageBps=10000 at the build
              value:
                error: declined
                reason: amount_too_small
            recipient:
              summary: A wrap to another address
              value:
                error: declined
                reason: recipient_unsupported
    EvmRateLimited:
      description: >-
        Over the account's limit a minute (shared with the API, the Solana
        routes and launch). Wait for the next minute.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GateError'
          example:
            error:
              code: rate_limited
              message: too many requests
    EvmNotReady:
      description: >
        Retry with backoff. `error` is `not_ready` with `reasons` (the chain has
        no RPC, no venue

        verified yet, or none of the venues `dexes` asked for is verified; or
        too many quotes and

        builds are in flight, then with `Retry-After: 1`), or `rpc` with the
        kind of failure as

        `reason`: the router could not read the chain (`rpc_timeout`,
        `rpc_block_unavailable`,

        `rpc_unavailable`, `rpc_queue_full`, …), or the request took more than
        10 seconds

        (`request_timeout`). Not a lack of liquidity, which is `404 no_route`.
      headers:
        Retry-After:
          description: '`1` when too many quotes and builds are in flight'
          schema:
            type: integer
      content:
        application/json:
          schema:
            anyOf:
              - $ref: '#/components/schemas/NotReadyError'
              - $ref: '#/components/schemas/EvmError'
          examples:
            venue:
              summary: No requested venue is verified (shape from the code)
              value:
                error: not_ready
                reasons:
                  - 'base: none of the requested venues is verified yet'
            overloaded:
              summary: Too many requests in flight (shape from the code)
              value:
                error: not_ready
                reasons:
                  - 'overloaded: too many quotes and builds in flight'
            rpc:
              summary: The node did not answer in time (shape from the code)
              value:
                error: rpc
                reason: rpc_timeout
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
    Bearer:
      type: http
      scheme: bearer
    ApiKeyQuery:
      type: apiKey
      in: query
      name: apiKey

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.