> ## 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.

# Quote (JSON body)

> The same quote as `GET /quote`, with the parameters as a JSON object. Numeric fields accept
a number or a decimal string; `dexes` / `excludeDexes` accept a comma-separated string or
an array; booleans must be JSON booleans.


Guide: [Quote and swap](/router/quote-and-swap).


## OpenAPI

````yaml router.openapi.yaml POST /quote
openapi: 3.1.0
info:
  title: Raze Swap Router API
  version: 1.0.0
  description: >
    Quotes and **unsigned** transactions for swaps on Solana, routed over ~20
    venues through a

    deploy of the `swap` program. 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 no
    key and builds for

    Raze's deploy of the `swap` program,
    `DADMMjfNnY6z8H9h9RfHZ9tfarBySsj4Yb65qLyKJDAD`.


    **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`.


    **No authentication.** A router you run yourself has no keys, no accounts
    and no rate limit. It

    listens on loopback by default (`ROUTER_LISTEN=127.0.0.1:4700`); keep it
    behind your firewall or

    your own gateway.


    **Conventions:**

    - Amounts are integers in the token's base units (lamports, atoms). In
    quotes and builds the
      u64 amounts are decimal **strings** (`inAmount`, `outAmount`, `otherAmountThreshold`,
      `platformFee.amount`, every `costs.*`). `minReturn`, `maxAmountIn`, `computeUnits` and
      `contextSlot` 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.


    **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** 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, `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`.


    The 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
  - url: http://127.0.0.1:4700
    description: Your own router (default ROUTER_LISTEN)
security: []
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
paths:
  /quote:
    post:
      tags:
        - swap
      summary: Quote a swap (JSON body)
      description: >
        The same quote as `GET /quote`, with the parameters as a JSON object.
        Numeric fields accept

        a number or a decimal string; `dexes` / `excludeDexes` accept a
        comma-separated string or

        an array; booleans must be JSON booleans.
      operationId: postQuote
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteRequest'
            example:
              inputMint: So11111111111111111111111111111111111111112
              outputMint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
              amount: '10000000'
              swapMode: ExactOut
              slippageBps: 100
      responses:
        '200':
          description: The quote
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteResponse'
              examples:
                exactOut:
                  summary: ExactOut, 10 USDC out of SOL, 1% slippage
                  value:
                    inputMint: So11111111111111111111111111111111111111112
                    inAmount: '84951440'
                    outputMint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
                    outAmount: '10000000'
                    otherAmountThreshold: '85800954'
                    swapMode: ExactOut
                    slippageBps: 100
                    priceImpactPct: '0'
                    routePlan:
                      - swapInfo:
                          ammKey: HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR
                          label: Meteora DLMM
                          inputMint: So11111111111111111111111111111111111111112
                          outputMint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
                          inAmount: '84951440'
                          outAmount: '10000000'
                          walkSteps: 1
                        percent: 100
                        bps: 10000
                    contextSlot: 452409379
                    timeTaken: 0.153888399
                    quoteId: 23e14e01000044bb
        '400':
          $ref: '#/components/responses/QuoteBadRequest'
        '404':
          $ref: '#/components/responses/NoRoute'
        '413':
          $ref: '#/components/responses/TooLarge'
        '422':
          $ref: '#/components/responses/QuoteDeclined'
        '500':
          $ref: '#/components/responses/Internal'
        '503':
          $ref: '#/components/responses/NotReady'
components:
  schemas:
    QuoteRequest:
      type: object
      required:
        - inputMint
        - outputMint
        - amount
      properties:
        inputMint:
          type: string
          description: Mint you spend
        outputMint:
          type: string
          description: Mint you receive; equal to `inputMint` asks for a cycle
        amount:
          type:
            - string
            - integer
          description: 'u64 in base units: the input for ExactIn, the output for ExactOut'
        swapMode:
          type: string
          enum:
            - ExactIn
            - ExactOut
            - exactIn
            - exactOut
          default: ExactIn
        slippageBps:
          type:
            - integer
            - string
          default: 50
          description: 0–10000
        maxHops:
          type:
            - integer
            - string
          description: 1–4; can only tighten the operator's limit
        onlyDirectRoutes:
          type: boolean
          default: false
        dexes:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
          description: Only these venues. Alias `includeDex`
        excludeDexes:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
          description: Never these venues. Alias `excludeDex`
        allowSplit:
          type: boolean
          default: false
        platformFeeBps:
          type:
            - integer
            - string
          default: 0
          description: 0–1000 (higher is capped)
        feeOnInput:
          type: boolean
        forJitoBundle:
          type: boolean
          default: false
        reserveKeys:
          type:
            - integer
            - string
          default: 0
          description: 0–255
        asLegacyTransaction:
          type: boolean
          const: false
    QuoteResponse:
      type: object
      required:
        - inputMint
        - inAmount
        - outputMint
        - outAmount
        - otherAmountThreshold
        - swapMode
        - slippageBps
        - priceImpactPct
        - routePlan
      properties:
        inputMint:
          type: string
        inAmount:
          type: string
          description: >-
            What leaves the wallet, platform fee included. ExactIn: the `amount`
            asked
        outputMint:
          type: string
        outAmount:
          type: string
          description: >-
            What arrives, net of venue and platform fees. ExactOut: the `amount`
            asked
        otherAmountThreshold:
          type: string
          description: >-
            ExactIn: the least that arrives, `outAmount × (10000 − slippageBps)
            / 10000`. ExactOut: the most that is spent, `inAmount × (10000 +
            slippageBps) / 10000`
        swapMode:
          type: string
          enum:
            - ExactIn
            - ExactOut
        slippageBps:
          type: integer
        priceImpactPct:
          type: string
          description: >-
            Price impact as a decimal fraction (`0.01` is 1%). `0` when it is
            not known
        routePlan:
          type: array
          items:
            $ref: '#/components/schemas/RoutePlanStep'
          description: >-
            The hops in order. A split is two routes one after the other: a
            route ends at the first step whose `outputMint` is the quote's
        contextSlot:
          type: integer
          description: Slot of the pool state the quote was priced on
        timeTaken:
          type: number
          description: Seconds spent inside the router
        platformFee:
          $ref: '#/components/schemas/PlatformFee'
        quoteId:
          type: string
          description: 16 hex digits; the build of this quote carries the same `quoteId`
        routeTicket:
          type: string
          description: >-
            The route signed with HMAC-SHA256
            (`base64url(JSON).base64url(MAC)`), valid for `ROUTER_TICKET_TTL_S`
            (default 60 s). Only when your router sets `ROUTER_TICKET_SECRET`
          example: eyJ2IjoyLCJxdW90ZUlkIjoiMjNlMTRlMDEwMDAwNDRjNiIsImlucHV0TWlu…
    RoutePlanStep:
      type: object
      required:
        - swapInfo
      properties:
        swapInfo:
          $ref: '#/components/schemas/SwapInfo'
        percent:
          type: integer
          minimum: 1
          maximum: 100
          description: >-
            On the first step of a route, that route's share of the input,
            rounded; 100 elsewhere
        bps:
          type: integer
          minimum: 1
          maximum: 10000
          description: The exact share in basis points
    PlatformFee:
      type: object
      description: Present when `platformFeeBps` > 0
      properties:
        amount:
          type: string
          description: The fee, in base units of `feeMint`
        feeBps:
          type: integer
        feeMint:
          type: string
          description: >-
            Router extension: the mint the fee is taken in (`inputMint` or
            `outputMint`)
    Error:
      type: object
      required:
        - error
        - reason
      properties:
        error:
          type: string
          description: >-
            Closed error code: `bad_request`, `declined`, `not_found`,
            `internal`, `quote_mismatch`, `invalid_route_ticket`,
            `route_ticket_mismatch`, `route_expired`, `bad_recipient`,
            `venue_red`, `rpc`, or on `/tx/v1` `bad_address`, `no_instructions`,
            `bad_data`, `missing_budget`, `invalid_message`, `wire_limit`
        reason:
          type: string
          description: >-
            With `declined`, a stable label (`no_route`, `cold_unresolved`,
            `platform_fee`, …); otherwise a sentence for humans
        quoteId:
          type: string
          description: >-
            16 hex digits, also in the router's logs. Absent when the request
            could not be parsed, and on `/tx/v1`
    LowLiquidityError:
      type: object
      required:
        - error
        - reason
        - liquidity
      properties:
        error:
          type: string
          const: declined
        reason:
          type: string
          const: low_liquidity
        liquidity:
          type: object
          description: The deepest direct pool of the pair, all too shallow to price
          properties:
            venue:
              type: string
              description: '`dex` label of the pool'
            hubMint:
              type: string
              description: The pool's SOL, USDC or USDT side
            hubAmount:
              type: string
              description: Its balance in base units of `hubMint` (u64 as string)
        quoteId:
          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
    SwapInfo:
      type: object
      required:
        - ammKey
        - label
        - inputMint
        - outputMint
        - inAmount
        - outAmount
      properties:
        ammKey:
          type: string
          description: Pool address
        label:
          type: string
          description: Venue `dex` label
        inputMint:
          type: string
        outputMint:
          type: string
        inAmount:
          type: string
          description: Input of this hop (after the platform fee when it is on the input)
        outAmount:
          type: string
          description: Output of this hop
        walkSteps:
          type: integer
          description: >-
            Router extension: ticks or bins this hop walked. Keep it when you
            send the quote back: without it the build declares the maximum
            compute budget for the hop (and pays priority fee on it)
  responses:
    QuoteBadRequest:
      description: >
        The request is wrong and retrying will not help. `error` is
        `bad_request` with the reason

        as a sentence (no `quoteId` when the parameters could not be parsed at
        all), or `declined`

        with `reason: zero_amount`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            badMint:
              summary: Not a base58 address
              value:
                error: bad_request
                reason: inputMint is not a base58 address
                quoteId: 23e14e01000044bf
            slippage:
              summary: slippageBps over 10000
              value:
                error: bad_request
                reason: slippageBps above 10000
                quoteId: 23e14e01000044c1
            unknownDex:
              summary: dexes names no known venue
              value:
                error: bad_request
                reason: 'includeDex names no venue this router serves: Jupiter'
                quoteId: 23e14e01000044c2
            legacy:
              summary: asLegacyTransaction=true
              value:
                error: bad_request
                reason: 'asLegacyTransaction is not served: this router emits v1'
                quoteId: 23e14e01000044c4
            missing:
              summary: Missing parameter
              value:
                error: bad_request
                reason: missing field `amount`
            zero:
              summary: amount=0
              value:
                error: declined
                reason: zero_amount
                quoteId: 23e14e01000044c3
    NoRoute:
      description: >
        `declined` with `no_route` (no route exists under these filters and hop
        limit) or `no_cycle`

        (input equals output and no cycle returns more than it costs). Widen the
        filters or the

        amount; retrying the same request will not change it unless the market
        does.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: declined
            reason: no_route
            quoteId: 23e14e01000045c5
    TooLarge:
      description: The request body is over 256 KiB (plain-text body)
      content:
        text/plain:
          schema:
            type: string
    QuoteDeclined:
      description: >
        A named decline: a route exists in principle but cannot be served now.
        `error` is

        `declined` and `reason` one of `cold_unresolved` (the router found no
        pool for a mint it

        had never seen; it remembers this for a while), `low_liquidity` (the
        pair's pools are dust;

        the body adds `liquidity`), `transfer_guard` (a Token-2022 mint is
        paused or has a transfer

        hook), `stale` (pool state is being re-read after a restart or stream
        gap; retry in seconds),

        `unbuildable` (the only routes cannot be built: account budget, venue
        not in your config,

        wire), `unservable`, `approx`, `inactive`, `no_depth`,
        `missing_account`, `degenerate`,

        `unsupported`, `incoherent`.
      content:
        application/json:
          schema:
            anyOf:
              - $ref: '#/components/schemas/Error'
              - $ref: '#/components/schemas/LowLiquidityError'
          examples:
            cold:
              summary: Unknown mint
              value:
                error: declined
                reason: cold_unresolved
                quoteId: 23e14e01000044c0
            dust:
              summary: Only dust pools (shape from the code)
              value:
                error: declined
                reason: low_liquidity
                liquidity:
                  venue: Meteora DAMM V2
                  hubMint: So11111111111111111111111111111111111111112
                  hubAmount: '5084204'
                quoteId: '0000000000000007'
    Internal:
      description: >-
        A router bug: `error` is `internal` (`quote task failed`, `build task
        failed`, …). Report it with the `quoteId`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            build:
              summary: The build task panicked (shape from the code)
              value:
                error: internal
                reason: build task failed
                quoteId: 23e14e0100000009
    NotReady:
      description: >
        Not ready: retry with backoff. `reasons` lists every readiness reason
        (the same as

        `GET /ready`), or a transient one of this request (`miss gate busy`,
        `miss budget`,

        `clickhouse busy`: a cold mint is still being fetched).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotReadyError'
          examples:
            cold:
              summary: A router that has just started (reasons from the router's tests)
              value:
                error: not_ready
                reasons:
                  - 'store cold: no account frame from the stream yet'
                  - index not built
                quoteId: 23e14e0100000001
            coldMint:
              summary: A cold mint still being fetched (shape from the code)
              value:
                error: not_ready
                reasons:
                  - miss budget
                quoteId: 23e14e010000000a

````

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