Chord Quote and swap API

Best-route quotes across every venue on the chain, and the unsigned transaction to execute them.

GitHub OpenAPI

Operations 4

GET /quote Best route for a swap #
POST /swap Build an unsigned swap transaction #
GET /swap/calldata Quote and build in one call #
POST /swap/simulate Simulate a built transaction before signing #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/getchord-xyz:getchord-xyz-quote-and-swap-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

getchord-xyz-quote-and-swap-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Chord Quote and swap API
  version: '2026-10-05'
  summary: Trade, data and agent endpoints for eight EVM chains (Ethereum 1, Arbitrum One 42161, Base 8453, BNB Chain 56, Avalanche 43114, Monad 143, Arc 5042, Robinhood Chain 4663) and Solana (data and swaps).
  description: 'Chord is a non-custodial trading app and on-chain data index. The API has three kinds of endpoint:


    - **Trade**: `/quote` finds the best route across every venue on the chain; `/swap` turns it into a transaction you sign yourself. Chord never holds funds or keys.

    - **Read**: every swap on the chain, rolled up by token, venue and hour, from Chord''s own index — tokens, launches, holders, top wallets, portfolio PnL, liquidity positions and pools. No key needed. Avalanche, Base, BNB Chain, Arbitrum One and Ethereum have the same rollups under `/chains/{chain}/*`; Solana has its own data family under `/chains/solana/*` (base58 addresses, case-sensitive) and its swaps under `/sol/trade/*`.

    - **Agent**: the analyst (`/ask`) and the streams.


    Amounts are decimal strings in the token''s smallest unit. Timestamps are Unix seconds unless the field is `updatedAt` (milliseconds). `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` differ on both: amounts there are in whole tokens and every time is in milliseconds. Reads answer anonymous callers at 60 requests a minute per IP; an `X-API-Key` header raises that to your plan. Every non-2xx body is `{ error, message }`.'
  contact:
    name: Chord
    url: https://getchord.xyz/developer
  x-logo:
    url: https://getchord.xyz/chord/pwa-192x192.png?v=20261019
servers:
- url: https://api.getchord.xyz/v1
  description: Production
tags:
- name: Quote and swap
  description: Best-route quotes across every venue on the chain, and the unsigned transaction to execute them.
paths:
  /quote:
    get:
      tags:
      - Quote and swap
      operationId: getQuote
      summary: Best route for a swap
      description: 'Quotes every venue on the chain in parallel, splits the order across venues when that improves the output, composes a two-hop route through the chain''s anchors when no direct pool wins, and returns the best.


        **Use it for**: a price before a trade, a route card, an agent deciding whether to buy, a bot comparing venues.


        **Notes**

        - Amounts are strings in the token''s smallest unit. On Arc the USDC predeploy has 6 decimals, native USDC 18 — send the predeploy address `0x3600…0000` (the zero address is an alias for it on 5042).

        - A quote is a live read of the venues and is good for about 30 seconds. Re-quote before you build if you waited longer.

        - `fast=1` returns a single-hop answer in about 400 ms marked `preliminary`; run the full quote alongside and replace it.

        - `only=` pins one venue and bypasses the routing safety gates — it needs an API key.

        - An empty `routePlan` is a real answer (no route at this size); read `noRouteReason`.'
      parameters:
      - name: chain
        in: query
        required: false
        schema:
          type: integer
          enum:
          - 5042
          - 4663
          - 143
          - 43114
          - 8453
          - 56
          - 42161
          - 1
          default: 143
        description: 'Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum. Omitted = 143. Always pass it.'
      - name: inputMint
        in: query
        required: true
        schema:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        description: Token you sell. The zero address means the native unit (an alias for the USDC predeploy on Arc; ETH on Robinhood Chain).
      - name: outputMint
        in: query
        required: true
        schema:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        description: Token you buy.
      - name: amount
        in: query
        required: true
        schema:
          type: string
          pattern: ^\d+$
          description: Amount in the token's smallest unit, as a decimal string. Never a float.
        description: Input amount, smallest unit.
      - name: slippageBps
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 5000
          default: 50
        description: Slippage tolerance in basis points; sets `otherAmountThreshold`.
      - name: fast
        in: query
        required: false
        schema:
          type: integer
          enum:
          - 0
          - 1
        description: '1 = progressive first frame (single-hop, ~400 ms, `preliminary: true`).'
      - name: only
        in: query
        required: false
        schema:
          type: string
          pattern: ^[a-z0-9_]+$
        description: 'Debug: restrict routing to one venue id. Requires `X-API-Key`.'
      responses:
        '200':
          description: The best route. `routePlan` empty + `outputAmount` "0" = no route.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteResponse'
              example:
                inputMint: '0x3600000000000000000000000000000000000000'
                outputMint: '0x171a4217b86a807a64eb94757db6849fb4bdbaa0'
                inputAmount: '5000000'
                outputAmount: '465'
                otherAmountThreshold: '460'
                slippageBps: 100
                priceImpactPct: '92.51'
                routePlan:
                - percent: 100
                  swapInfo:
                    dex: uniswap_v4
                    pool: '0xdd9da42901118c475e6efb78117100e611c675e2c53bc801c4d2bfdd504b2e8d'
                    inputMint: '0x3600000000000000000000000000000000000000'
                    outputMint: '0x171a4217b86a807a64eb94757db6849fb4bdbaa0'
                    inputAmount: '5000000'
                    outputAmount: '465'
                    adapter: '0xd1d86d370f40471B79D9938B27F6ea040EbD6888'
                    extraData: '0x000000000000000000000000171a4217b86a807a64eb94757db6849fb4bdbaa00000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000'
                gasEstimate: '318189'
                gasCostUSD: '0'
                blockNumber: 21808240
                timeTaken: 0.643
                feeBps: 25
                feeAmount: '1'
                feeMint: '0x171a4217b86a807a64eb94757db6849fb4bdbaa0'
                feeTier: meme
        '400':
          description: Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /swap:
    post:
      tags:
      - Quote and swap
      operationId: buildSwap
      summary: Build an unsigned swap transaction
      description: 'Turns a quote into a transaction against the Chord router. You sign it and broadcast it; Chord never sees a key and never holds funds.


        **Notes**

        - Send the `/quote` body back unmodified. `chain` must match the quote.

        - For an ERC-20 input, approve the router (`transaction.to`) for at least `inputAmount` first — or run `/swap/simulate` and let it tell you.

        - `slippageBps` is a consistency check only: the signed minimum output is the quote''s `otherAmountThreshold`. A different value is refused with `SLIPPAGE_MISMATCH` — re-quote at the slippage you want.

        - On Arc the native sentinel aliases to the USDC predeploy: a "native" input is pulled by `transferFrom`, a "native" output is delivered as the predeploy, and `value` is always 0.

        - `batch: "7702"` is Monad-only (EIP-7702 one-signature approve+swap); it is ignored on every other chain.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                quoteResponse:
                  $ref: '#/components/schemas/QuoteResponse'
                userPublicKey:
                  type: string
                  pattern: ^0x[a-fA-F0-9]{40}$
                  description: Wallet that signs and receives the output.
                chain:
                  type: integer
                  enum:
                  - 5042
                  - 4663
                  - 143
                  - 43114
                  - 8453
                  - 56
                  - 42161
                  - 1
                  default: 143
                  description: Must match the quote.
                slippageBps:
                  type: integer
                  minimum: 1
                  maximum: 5000
                  description: Optional consistency check — same value the quote was requested with.
                feeAccount:
                  type: string
                  pattern: ^0x[a-fA-F0-9]{40}$
                  description: Referrer credited with the referral share of the protocol fee.
                wrapUnwrapMON:
                  type: boolean
                  default: true
                  description: Wrap / unwrap the native unit around the swap where the chain has a wrapped native (not Arc).
                usePermit2:
                  type: boolean
                  default: false
                batch:
                  type: string
                  enum:
                  - '7702'
              required:
              - quoteResponse
              - userPublicKey
            example:
              quoteResponse:
                …: the /v1/quote body
              userPublicKey: '0xb145400da27a2497d9fc2cd5621f2bfd37617af4'
              chain: 5042
      responses:
        '200':
          description: Sign `transaction` with any wallet library and submit it to the chain in `chainId`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  transaction:
                    $ref: '#/components/schemas/SwapTx'
                  lastValidBlockHeight:
                    type: integer
                    description: Block after which the quote should be considered stale.
                  batch7702:
                    type: object
                    additionalProperties: true
                    description: Monad only — the one-signature approve+swap plan.
              example:
                transaction:
                  to: '0x1b1fee89a381e595fe6536b99ba91f3e16e9601a'
                  data: 0xdc72a437…
                  value: '0'
                  gasLimit: '1500000'
                  chainId: 5042
                lastValidBlockHeight: 21808340
        '400':
          description: Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /swap/calldata:
    get:
      tags:
      - Quote and swap
      operationId: swapCalldata
      summary: Quote and build in one call
      description: 'For contracts and bots that call the router directly: routes and encodes in a single request. The output goes to `msg.sender`; the caller approves the router for `tokenIn` and sends the calldata.'
      parameters:
      - name: chain
        in: query
        required: false
        schema:
          type: integer
          enum:
          - 5042
          - 4663
          - 143
          - 43114
          - 8453
          - 56
          - 42161
          - 1
          default: 143
        description: 'Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum. Omitted = 143.'
      - name: tokenIn
        in: query
        required: true
        schema:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        description: Token the caller approves and sends.
      - name: tokenOut
        in: query
        required: true
        schema:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        description: Token returned to msg.sender.
      - name: amountIn
        in: query
        required: true
        schema:
          type: string
          pattern: ^\d+$
          description: Amount in the token's smallest unit, as a decimal string. Never a float.
        description: ''
      - name: slippageBps
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 5000
          default: 100
        description: Sets `minOut` on the returned calldata.
      responses:
        '200':
          description: Router call.
          content:
            application/json:
              schema:
                type: object
                properties:
                  to:
                    type: string
                    pattern: ^0x[a-fA-F0-9]{40}$
                    description: EVM address, hex, case-insensitive.
                  data:
                    type: string
                    description: ''
                  value:
                    type: string
                    pattern: ^\d+$
                    description: Amount in the token's smallest unit, as a decimal string. Never a float.
                  minOut:
                    type: string
                    description: Minimum output, human units.
                  expectedOut:
                    type: string
                    description: Quoted output, human units.
                  gasLimit:
                    type: string
                    description: ''
              example:
                to: '0x1b1fee89a381e595fe6536b99ba91f3e16e9601a'
                data: 0x…
                value: '0'
                minOut: '0.0942'
                expectedOut: '0.0951'
                gasLimit: '1000000'
        '400':
          description: Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /swap/simulate:
    post:
      tags:
      - Quote and swap
      operationId: simulateSwap
      summary: Simulate a built transaction before signing
      description: '`eth_call`s the built calldata from the user''s address and estimates gas, so a revert is caught before the wallet opens. Known selectors are decoded (`NotRouter`, a paused Kuru market, allowance and balance errors). An allowance revert is advisory: approve first, then swap.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                chain:
                  type: integer
                  enum:
                  - 5042
                  - 4663
                  - 143
                  - 43114
                  - 8453
                  - 56
                  - 42161
                  - 1
                from:
                  type: string
                  pattern: ^0x[a-fA-F0-9]{40}$
                  description: EVM address, hex, case-insensitive.
                to:
                  type: string
                  pattern: ^0x[a-fA-F0-9]{40}$
                  description: EVM address, hex, case-insensitive.
                data:
                  type: string
                  description: Calldata from `/swap`.
                value:
                  type: string
                  pattern: ^\d+$
                  description: Amount in the token's smallest unit, as a decimal string. Never a float.
              required:
              - from
              - to
              - data
              - value
            example:
              chain: 5042
              from: '0xb145400da27a2497d9fc2cd5621f2bfd37617af4'
              to: '0x1b1fee89a381e595fe6536b99ba91f3e16e9601a'
              data: 0xdc72a437…
              value: '0'
      responses:
        '200':
          description: '`ok: true` with the simulated output and gas, or `ok: false` with the decoded revert.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: ''
                  amountOut:
                    type:
                    - string
                    - 'null'
                    description: Simulated output, smallest unit.
                  gas:
                    type:
                    - integer
                    - 'null'
                    description: Estimated gas units.
                  revert:
                    type: string
                    description: Decoded reason (when `ok` is false).
                  selector:
                    type:
                    - string
                    - 'null'
                    description: 4-byte error selector.
              example:
                ok: true
                amountOut: '465'
                gas: 318189
        '400':
          description: Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    SwapTx:
      type: object
      properties:
        to:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        data:
          type: string
          description: Calldata.
        value:
          type: string
          pattern: ^\d+$
          description: Amount in the token's smallest unit, as a decimal string. Never a float.
        gasLimit:
          type: string
          description: ''
        chainId:
          type: integer
          description: ''
      description: Unsigned transaction against the router.
    Error:
      type: object
      properties:
        error:
          type: string
          description: Stable machine code, e.g. `INVALID_PARAMS`, `NOT_READY`, `RATE_LIMIT_EXCEEDED`.
        message:
          type: string
          description: For humans.
        statusCode:
          type: integer
          description: HTTP status, when included.
      description: Every non-2xx body.
      required:
      - error
      example:
        error: INVALID_PARAMS
        message: amount must be an integer string in the token's smallest unit
    QuoteResponse:
      type: object
      properties:
        inputMint:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        outputMint:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        inputAmount:
          type: string
          pattern: ^\d+$
          description: Amount in the token's smallest unit, as a decimal string. Never a float.
        outputAmount:
          type: string
          pattern: ^\d+$
          description: Amount in the token's smallest unit, as a decimal string. Never a float.
        otherAmountThreshold:
          type: string
          pattern: ^\d+$
          description: Minimum output after fee and slippage — the number the transaction enforces.
        slippageBps:
          type: integer
          description: ''
        priceImpactPct:
          type: string
          description: Percent, as a string, against the spot rate of the same route.
        routePlan:
          type: array
          items:
            $ref: '#/components/schemas/RouteLeg'
          description: Empty with `outputAmount` "0" = no route (an honest answer, never a fabricated price).
        noRouteReason:
          type: string
          description: 'Only when `routePlan` is empty: `INSUFFICIENT_LIQUIDITY` (try a smaller amount) or `NO_POOLS`.'
        gasEstimate:
          type: string
          description: Gas units, from the venue quoter or the RPC.
        gasCostUSD:
          type: string
          description: ''
        blockNumber:
          type: integer
          description: ''
        timeTaken:
          type: number
          description: Engine seconds.
        feeBps:
          type: integer
          description: 'Protocol fee on the output token, per token on-chain (`FeeCollector.feeBpsFor`): 5 bps by default on every chain, 0 on the stablecoins and majors a chain exempts (USDC / EURC on Arc, WETH / USDG and stocks on Robinhood Chain), capped at 100.'
        feeAmount:
          type: string
          pattern: ^\d+$
          description: Amount in the token's smallest unit, as a decimal string. Never a float.
        feeMint:
          type: string
          pattern: ^0x[a-fA-F0-9]{40}$
          description: EVM address, hex, case-insensitive.
        feeTier:
          type: string
          description: '`major` · `stable` · `standard` · `meme` · `new`.'
        preliminary:
          type: boolean
          description: 'Present only on `fast=1` answers: single-hop, ~400 ms, replace it with the full quote.'
    RouteLeg:
      type: object
      properties:
        percent:
          type: integer
          description: Share of the input this leg carries.
        swapInfo:
          type: object
          properties:
            dex:
              type: string
              description: Venue id (see Resources → Venue ids).
            pool:
              type: string
              description: Pool address, or the 32-byte pool id on Uniswap V4.
            inputMint:
              type: string
              pattern: ^0x[a-fA-F0-9]{40}$
              description: EVM address, hex, case-insensitive.
            outputMint:
              type: string
              pattern: ^0x[a-fA-F0-9]{40}$
              description: EVM address, hex, case-insensitive.
            inputAmount:
              type: string
              pattern: ^\d+$
              description: Amount in the token's smallest unit, as a decimal string. Never a float.
            outputAmount:
              type: string
              pattern: ^\d+$
              description: Amount in the token's smallest unit, as a decimal string. Never a float.
            adapter:
              type: string
              description: The router adapter that executes this leg — from the engine, never hardcode.
            extraData:
              type: string
              description: Adapter-specific calldata for the leg.
            feeAmount:
              type: string
              pattern: ^\d+$
              description: Amount in the token's smallest unit, as a decimal string. Never a float.
            feeMint:
              type: string
              pattern: ^0x[a-fA-F0-9]{40}$
              description: EVM address, hex, case-insensitive.
      description: One leg of the route.
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Optional on every read. A key from getchord.xyz/developer raises the rate limit to your plan and meters usage per key. Required for `?only=` on quotes and for the Ask agent API.
    Session:
      type: http
      scheme: bearer
      description: A Google sign-in session minted by the app (`nts_…`). Only the browser surfaces use it; agents use `ApiKey`.