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

# Quote a swap and build its transaction

> Quotes a swap against the current registered maker books and, when `signer` is given, builds the unsigned transaction that executes it.

- **Without `signer`:** a quote only. `quoteResponse` is filled, `transaction` is `null`, and nothing touches RPC — cheap enough to call on every input change. The caller's own maker books (if any) cannot be excluded from such a quote.
- **With `signer`:** the same quote plus `transaction`, base64-encoded and unsigned, for the taker to sign and send. The quote and the transaction come from one run of the matching engine over one book list, so they cannot disagree.

The `swapMode` parameter controls how `size` is interpreted:
- **Omitted (default):** `size` is always in base tokens.
- **`MaxAmountIn`:** `size` is the maximum input amount (buy → quote tokens, sell → base tokens).
- **`MinAmountOut`:** `size` is the minimum output amount (buy → base tokens, sell → quote tokens).

A size the book cannot cover is refused with `INSUFFICIENT_LIQUIDITY`; the error carries the size that could be filled. The engine mirrors the on-chain matching engine to the atom.



## OpenAPI

````yaml /openapi.json post /v1/order/swap
openapi: 3.0.3
info:
  description: >-
    REST API for the Archer Exchange — a high-performance Solana-based order
    book exchange.


    All monetary values (prices, sizes, fees) are returned as decimal strings
    for precision.


    ### Rate Limiting

    All endpoints are rate-limited via a token-bucket algorithm. When the limit
    is exceeded, the API returns `429 Too Many Requests`.


    ### Error Format

    All errors follow a consistent JSON format:

    ```json

    {
      "error": "ERROR_CODE",
      "message": "Human-readable description"
    }

    ```


    ### Handling errors

    Every error falls into one of five actions. REST errors come back as
    `{"error": CODE, "message"}`. A transaction that fails on-chain reports
    `{"InstructionError": [index, {"Custom": code}]}`; codes are the `errors`
    list of the program IDL (`archer-sdk/idl/archer_v1.json`). When a build
    endpoint's preflight catches an on-chain error first, it returns `400
    INVALID_PARAMS` with the reason in `message`.


    | Action | REST | On-chain (code) |

    |---|---|---|

    | **Retry as is**, with backoff | `RATE_LIMITED` (429),
    `SERVICE_UNAVAILABLE` (503), `INTERNAL_ERROR` (500); relay `OVERLOADED`,
    `PREFLIGHT_UNAVAILABLE`. Keep backing off on 429: 50 of them within a minute
    from one IP returns `BANNED` (403) for 10 minutes | none |

    | **Refetch, rebuild, retry**: the book or registry changed under you | |
    `LevelSizeMismatch` (527), `StaleSequenceNumber` (509),
    `SequenceNumberTooFarAhead` (522), `RegistryBooksMismatch` (525),
    `IncompleteMakerBooks` (513), `NoMatchingLiquidity` (507); relay status
    `expired` (re-sign with a fresh blockhash) |

    | **Reprice** | `CROSSES_SPREAD`, `SLIPPAGE_EXCEEDED` | `PostOnlyWouldCross`
    (524), `CrossingOrderLevels` (505), `InvalidPrice` (503),
    `SlippageToleranceExceeded` (703) |

    | **Resize** | `INSUFFICIENT_LIQUIDITY` (the body's `availableSize` is what
    fits) | `MakerBookSideFull` (528: cancel a level first),
    `InvalidSizeAtLevel` (506), `InsufficientBalance` (402) and SPL Token `1`
    (fund the account or shrink), `ZeroSwapAmount` (702) |

    | **Stop**: fix the request or the setup; retrying cannot help |
    `INVALID_PARAMS`, `MISSING_API_KEY` / `INVALID_API_KEY` (401), `FORBIDDEN`,
    `NOT_FOUND`, `MARKET_NOT_FOUND`, `METHOD_NOT_ALLOWED`; `MARKET_PAUSED` /
    `MARKET_FROZEN` until the market resumes |
    `UnauthorizedArcherAccountDelegate` (1001), `BuilderFeeExceedsAccountCap`
    (1003), `UnauthorizedMaker` (502), `MakerNotRegistered` (512),
    `PostOnlyRequiresLimitOrderBook` (526), `MarketNotActive` (107),
    `MarketFrozen` (114); any 200–399 code (wrong account wiring, a bug to
    report) |
  title: Archer Exchange API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.archer.exchange
  - description: Staging
    url: https://api-staging.archer.exchange
  - description: Local
    url: http://localhost:8080
security:
  - apiKey: []
tags:
  - description: Discover and inspect available trading markets
    name: Markets
  - description: Token metadata for every mint Archer lists
    name: Tokens
  - description: Get price quotes before placing an order
    name: Quote
  - description: Build unsigned Solana transactions for swaps
    name: Orders
  - description: Build unsigned Solana transactions for limit orders
    name: Limit Orders
  - description: >-
      ArcherAccount — a wallet's delegated trading identity. Collateral sits in
      token accounts owned by the account PDA; an authorized delegate can trade
      and quote as the account but never withdraw.
    name: Account
  - description: Read a maker book — balances and resting levels — by PDA or by owner
    name: Maker Books
  - description: Deposit / withdraw / close — fund movement for a maker book
    name: Maker Funds
  - description: Public protocol-wide aggregate statistics
    name: Stats
  - description: >-
      Submit signed Solana transactions and let Archer land them. Hosted at
      `https://send.archer.exchange`, separate from the REST API, using the same
      API key.
    name: Transaction Relay
paths:
  /v1/order/swap:
    post:
      tags:
        - Orders
      summary: Quote a swap and build its transaction
      description: >-
        Quotes a swap against the current registered maker books and, when
        `signer` is given, builds the unsigned transaction that executes it.


        - **Without `signer`:** a quote only. `quoteResponse` is filled,
        `transaction` is `null`, and nothing touches RPC — cheap enough to call
        on every input change. The caller's own maker books (if any) cannot be
        excluded from such a quote.

        - **With `signer`:** the same quote plus `transaction`, base64-encoded
        and unsigned, for the taker to sign and send. The quote and the
        transaction come from one run of the matching engine over one book list,
        so they cannot disagree.


        The `swapMode` parameter controls how `size` is interpreted:

        - **Omitted (default):** `size` is always in base tokens.

        - **`MaxAmountIn`:** `size` is the maximum input amount (buy → quote
        tokens, sell → base tokens).

        - **`MinAmountOut`:** `size` is the minimum output amount (buy → base
        tokens, sell → quote tokens).


        A size the book cannot cover is refused with `INSUFFICIENT_LIQUIDITY`;
        the error carries the size that could be filled. The engine mirrors the
        on-chain matching engine to the atom.
      operationId: swapOrder
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BuildOrderRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BuildOrderResponse'
          description: The quote, and the transaction when a taker was named.
        '400':
          $ref: '#/components/responses/InsufficientLiquidity'
        '404':
          $ref: '#/components/responses/MarketNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  schemas:
    BuildOrderRequest:
      properties:
        accountOwner:
          description: >-
            The wallet that owns the ArcherAccount this request acts through.
            With `platform` it derives the account PDA server-side — you never
            handle a PDA. Omit for a plain wallet-owned book. Replaces the
            earlier `archerAccount` field, which is no longer read.
          nullable: true
          type: string
        market:
          description: Base58-encoded market address.
          example: u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4
          type: string
        maxSlippageBps:
          description: Maximum allowed slippage in basis points.
          minimum: 0
          type: integer
        platform:
          default: self
          description: >-
            Platform namespace for `accountOwner`. Ignored unless `accountOwner`
            is set.
          enum:
            - self
            - treadfi
          nullable: true
          type: string
        preflight:
          default: false
          description: >-
            Simulate the built transaction before returning it, and reject with
            the program's reason if it would fail (insufficient balance,
            slippage, liquidity gone, unauthorised signer). Off by default: a
            transaction is otherwise returned whether or not the signer could
            land it right now, which callers that build at quote time rely on.
            Ignored without `signer`.
          nullable: true
          type: boolean
        priorityFeeMicroLamports:
          description: >-
            Priority fee for the transaction's compute-budget instruction, in
            micro-lamports per compute unit. Omitted → the server default.
          example: 50000
          format: int64
          type: integer
        side:
          description: Trade side.
          enum:
            - buy
            - sell
          type: string
        signer:
          description: >-
            The wallet that signs the swap: the taker, or with `accountOwner`
            the account's owner or delegate. Omit for a quote only: the response
            then carries `quoteResponse` and no `transaction`, and the caller's
            own maker books (if any) cannot be excluded from the quote. Existing
            clients may keep sending it as `takerAddress`; send one name only.
          type: string
        size:
          description: >-
            Amount to trade (decimal string). Interpretation depends on
            `swapMode`.
          type: string
        swapMode:
          description: >-
            Controls how `size` is interpreted. When omitted, size is in base
            tokens.
          enum:
            - MaxAmountIn
            - MinAmountOut
          type: string
        withInstructions:
          default: false
          description: >-
            Also return the unsigned instructions under `instructions`, for
            composing your own transaction instead of signing ours. Omitted or
            `false` leaves the response exactly as it was.
          nullable: true
          type: boolean
      required:
        - market
        - side
        - size
        - maxSlippageBps
      type: object
    BuildOrderResponse:
      description: >-
        A swap quote and, when a taker was named, the unsigned transaction built
        from it. `quoteResponse` comes from the same engine run as the
        transaction.
      properties:
        addressLookupTables:
          description: >-
            Address lookup tables the transaction references. None are
            configured; always empty today.
          items:
            type: string
          type: array
        instructions:
          allOf:
            - $ref: '#/components/schemas/TransactionInstructions'
          description: >-
            Unsigned instructions, present only when the request set
            `withInstructions`.
          nullable: true
        quoteResponse:
          $ref: '#/components/schemas/QuoteResponse'
        swapMode:
          description: >-
            The effective mode, including the default applied when `swapMode`
            was omitted.
          enum:
            - MaxAmountIn
            - MinAmountOut
          type: string
        transaction:
          description: >-
            Base64-encoded unsigned Solana transaction for the taker to sign and
            submit. `null` when the request carried no `signer`.
          nullable: true
          type: string
      required:
        - transaction
        - swapMode
        - quoteResponse
        - addressLookupTables
      type: object
    TransactionInstructions:
      description: >-
        The instruction form of a built transaction, for callers that assemble
        and sign their own — their own fee strategy, their own lookup tables, or
        bundling Archer's instructions with their own.


        Returned only when the request sets `withInstructions`. The accompanying
        `transaction` is still built and still valid; these are the same
        instructions it contains, so signing one or composing the other are
        equivalent (the backend asserts this: rebuilding these instructions
        compiles to a byte-identical message). They also reflect the same
        maker-book selection the quote was computed from, so a caller that
        re-composes them gets the quoted price.
      properties:
        addressLookupTables:
          description: >-
            Lookup tables the instructions assume. None are configured; always
            empty today.
          items:
            type: string
          type: array
        computeBudgetInstructions:
          description: >-
            Compute-unit limit and price, kept separate so you can drop them and
            substitute your own fee strategy without touching the rest.
          items:
            $ref: '#/components/schemas/SerializedInstruction'
          type: array
        instructions:
          description: >-
            Archer's instructions, in the order they must execute. Any ATA
            creation and WSOL wrap/unwrap are included.
          items:
            $ref: '#/components/schemas/SerializedInstruction'
          type: array
        signer:
          description: The account that must sign and pay the fee.
          type: string
      required:
        - computeBudgetInstructions
        - instructions
        - signer
        - addressLookupTables
      type: object
    QuoteResponse:
      description: >-
        A swap quote. Amounts are what actually leaves and enters the taker's
        wallet — protocol and builder fees and any Token-2022 transfer fees
        included — computed by the same engine, over the same maker books in the
        same order, that `POST /v1/orders/build` executes.
      properties:
        inAmount:
          description: >-
            Input debited from the taker (decimal string in the input token).
            For `MaxAmountIn` this is at most the requested size; fees are
            carved out of it.
          example: '150.600000'
          type: string
        inputMint:
          description: Mint the taker pays with.
          example: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
          type: string
        outAmount:
          description: >-
            Output credited to the taker (decimal string in the output token).
            For `MinAmountOut` this is at least the requested size.
          example: '1.000000000'
          type: string
        outputMint:
          description: Mint the taker receives.
          example: So11111111111111111111111111111111111111112
          type: string
        priceImpactPct:
          description: >-
            Distance of the average fill price from the best price on the
            consumed side, in percent, before fees. `0` when the fill sits
            entirely at the top of book; positive means worse.
          example: '0.0332'
          type: string
        slippageBps:
          description: The requested tolerance, echoed.
          example: 50
          type: integer
        swapMode:
          description: >-
            The effective mode, including the default applied when `swapMode`
            was omitted.
          enum:
            - MaxAmountIn
            - MinAmountOut
          type: string
        totalFee:
          $ref: '#/components/schemas/QuoteFees'
      required:
        - inputMint
        - outputMint
        - inAmount
        - outAmount
        - swapMode
        - slippageBps
        - priceImpactPct
        - totalFee
      type: object
    ErrorResponse:
      properties:
        error:
          description: Machine-readable error code.
          enum:
            - INVALID_PARAMS
            - MARKET_NOT_FOUND
            - MARKET_PAUSED
            - INSUFFICIENT_LIQUIDITY
            - SLIPPAGE_EXCEEDED
            - NOT_FOUND
            - FORBIDDEN
            - RATE_LIMITED
            - INTERNAL_ERROR
            - SERVICE_UNAVAILABLE
            - MARKET_FROZEN
            - CROSSES_SPREAD
            - MISSING_API_KEY
            - INVALID_API_KEY
            - BANNED
            - METHOD_NOT_ALLOWED
          type: string
        message:
          description: Human-readable error description.
          type: string
      required:
        - error
        - message
      type: object
    InsufficientLiquidityError:
      description: >-
        Returned when the order book cannot fill the requested size. Includes
        the maximum available fill.
      properties:
        availableAvgPrice:
          description: Average price for the available fill.
          type: string
        availableSize:
          description: Maximum size that can be filled at current liquidity.
          type: string
        error:
          example: INSUFFICIENT_LIQUIDITY
          type: string
        message:
          type: string
      required:
        - error
        - message
        - availableSize
        - availableAvgPrice
      type: object
    SerializedInstruction:
      description: One instruction.
      properties:
        accounts:
          items:
            $ref: '#/components/schemas/InstructionAccount'
          type: array
        data:
          description: Base64-encoded instruction data.
          type: string
        programId:
          type: string
      required:
        - programId
        - accounts
        - data
      type: object
    QuoteFees:
      description: >-
        What the taker pays on top of the matched notional, in quote tokens
        (decimal strings).
      properties:
        builderFee:
          description: The builder fee the swap carries; `0` when it carries none.
          example: '0.000000'
          type: string
        protocolFee:
          description: The market's taker fee. Negative on a market that rebates takers.
          example: '0.060000'
          type: string
      required:
        - protocolFee
        - builderFee
      type: object
    InstructionAccount:
      description: >-
        One account an instruction touches, in the shape `@solana/web3.js` and
        `@solana/kit` already accept.
      properties:
        isSigner:
          type: boolean
        isWritable:
          type: boolean
        pubkey:
          type: string
      required:
        - pubkey
        - isSigner
        - isWritable
      type: object
  responses:
    InsufficientLiquidity:
      content:
        application/json:
          examples:
            insufficientLiquidity:
              value:
                availableAvgPrice: '150.104000'
                availableSize: '12.500000000'
                error: INSUFFICIENT_LIQUIDITY
                message: Insufficient liquidity
            invalidParams:
              value:
                error: INVALID_PARAMS
                message: 'Invalid size: not a decimal number: abc'
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/InsufficientLiquidityError'
      description: >-
        Invalid parameters, or the registered maker books cannot cover the
        requested size. An `INSUFFICIENT_LIQUIDITY` body carries `availableSize`
        — the base size the book could fill — and `availableAvgPrice`, its
        average price, so a client can retry at that size.
    MarketNotFound:
      content:
        application/json:
          example:
            error: MARKET_NOT_FOUND
            message: 'Market not found: 5Ggx...abc'
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Market not found.
    RateLimited:
      content:
        application/json:
          example:
            error: RATE_LIMITED
            message: Too many requests. Please slow down.
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Too many requests.
    InternalError:
      content:
        application/json:
          example:
            error: INTERNAL_ERROR
            message: 'Internal error: ...'
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Internal server error.
    ServiceUnavailable:
      content:
        application/json:
          example:
            error: SERVICE_UNAVAILABLE
            message: 'Service unavailable: ...'
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        Service temporarily unavailable (e.g., transaction builder not
        initialized).
  securitySchemes:
    apiKey:
      in: header
      name: X-API-Key
      type: apiKey

````

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