Skip to main content
POST
/
quote
Price a swap and return a routePlan
curl --request POST \
  --url https://quiet-bloodhound-531.convex.site/quote \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '
{
  "chainId": 2,
  "tokenIn": "<string>",
  "tokenOut": "<string>",
  "amountIn": "<string>",
  "slippageBps": 5000,
  "maxHops": 2,
  "splitEnabled": true,
  "enforcePoolDisjoint": true,
  "allowedDexes": [
    "UNIV2"
  ],
  "feeBps": 5000,
  "taker": "<string>",
  "timeBudgetMs": 5025
}
'
{
  "quoteId": "<string>",
  "routePlan": {
    "chainId": 123,
    "tokenIn": "<string>",
    "tokenOut": "<string>",
    "amountIn": "<string>",
    "expectedAmountOut": "<string>",
    "minAmountOut": "<string>",
    "slippageBps": 5000,
    "routes": [
      {
        "amountIn": "<string>",
        "legs": [
          {
            "dex": "UNIV2",
            "tokenIn": "<string>",
            "tokenOut": "<string>",
            "amountIn": "<string>",
            "minOut": "<string>",
            "data": {
              "kind": "<string>",
              "pool": "<string>",
              "feeBps": 5000
            },
            "poolId": "<string>"
          }
        ]
      }
    ],
    "blockNumber": 1,
    "feeBps": 5000,
    "gasEstimate": {
      "gasUnits": 1,
      "gasCostWei": "<string>"
    },
    "feeBreakdown": {
      "protocolFeeAmount": "<string>",
      "integratorFeeAmount": "<string>"
    },
    "metadata": {
      "connectorsConsidered": [
        "<string>"
      ],
      "candidatePaths": 1,
      "selectedPaths": 1,
      "candidates": [
        {
          "path": [
            "<string>"
          ],
          "dexes": [
            "UNIV2"
          ],
          "projectedOut": "<string>",
          "allocatedIn": "<string>",
          "score": 123
        }
      ]
    },
    "nativeIn": true,
    "nativeOut": true
  },
  "expiresAt": 123
}

Documentation Index

Fetch the complete documentation index at: https://docs.o1.exchange/llms.txt

Use this file to discover all available pages before exploring further.

Use POST /quote to fetch a price. The response includes a stable quoteId you echo on /submit when the user is ready to swap.
  • Authentication: x-api-key header required.
  • Rate limit: 120 req/min per key (default). See Rate limits.

Request

POST {API_URL}/quote
Content-Type: application/json
x-api-key: <YOUR_API_KEY>

Body parameters

FieldTypeRequiredDescription
chainIdintegeryesEVM chain ID. Currently only 8453 (Base) is supported.
tokenInaddressyesToken to sell. Use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE or the zero address for native ETH.
tokenOutaddressyesToken to buy. Same native sentinel rules apply.
amountInstringyesAmount in base units (wei) as a decimal string. Must be > 0.
slippageBpsintegeryesSlippage tolerance in basis points (100 = 1%). Range 0..10000.
feeBpsintegernoIntegrator fee in basis points, taken out of expectedAmountOut. Range 0..10000.
maxHopsintegernoMaximum hops per route. Default 3.
splitEnabledbooleannoAllow the optimizer to split the trade across multiple routes when it improves output. Default true.
enforcePoolDisjointbooleannoWhen splitting, require routes to use disjoint pool sets. Off by default.
allowedDexesarray of DexIdnoRestrict routing to a subset of venues. See Supported DEXes.
takeraddressnoOptional taker hint. Doesn’t affect pricing for most callers.
timeBudgetMsintegernoPer-request override of the optimizer wall-clock budget. Range 50..10000.

Response

{
  "quoteId": "a1b2c3d4e5f6...",
  "expiresAt": 1712180000000,
  "routePlan": {
    "chainId": 8453,
    "tokenIn": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "tokenOut": "0x4200000000000000000000000000000000000006",
    "amountIn": "1000000000",
    "expectedAmountOut": "484446072048780734",
    "minAmountOut": "479601611328292926",
    "slippageBps": 100,
    "feeBps": 30,
    "blockNumber": 44266656,
    "gasEstimate": { "gasUnits": 300000 },
    "feeBreakdown": {
      "protocolFeeAmount": "1457804507741243911",
      "integratorFeeAmount": "0"
    },
    "routes": [
      {
        "amountIn": "1000000000",
        "legs": [
          {
            "dex": "UNIV3",
            "tokenIn": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
            "tokenOut": "0x4200000000000000000000000000000000000006",
            "amountIn": "1000000000",
            "minOut": "0",
            "poolId": "0xd0b5...f224",
            "data": { "kind": "v3_direct", "pool": "0xd0b5...f224" }
          }
        ]
      }
    ],
    "metadata": {
      "candidatePaths": 16,
      "selectedPaths": 1,
      "connectorsConsidered": [
        "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
        "0x9401e5e6564db35c0f86573a9828df69fc778631"
      ]
    }
  }
}

Response fields

FieldTypeDescription
quoteIdstringStable identifier for this quote. Hand to /submit.
expiresAtintegerUnix milliseconds at which the cached quote drops.
routePlanobjectFull plan including pricing, gas estimate, and per-leg detail. See the RoutePlan reference for every field.
The fields you’ll most commonly surface to users:
  • routePlan.expectedAmountOut — the price you display
  • routePlan.minAmountOut — the worst case after slippage
  • routePlan.routes[].legs[].dex — list of venues used (e.g. UNIV3 → AERODROME_CL)
  • routePlan.feeBps — protocol + integrator fee in bps
  • routePlan.gasEstimate.gasUnits — estimated gas for the swap

Caching and freshness

Quotes are cached server-side under their quoteId for roughly 10 seconds. After expiresAt, calling /submit returns 404 quote not found or expired. For UIs that show a live price, the recommended pattern is to re-fetch the quote every 5 to 8 seconds while the swap modal is open. See Quote freshness.

Examples

const quote = await fetch(`${API_URL}/quote`, {
  method: "POST",
  headers: {
    "x-api-key": process.env.O1_API_KEY!,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    chainId: 8453,
    tokenIn: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    tokenOut: "0x4200000000000000000000000000000000000006",
    amountIn: "1000000000",
    slippageBps: 100,
  }),
}).then((r) => r.json());
Pair this with POST /submit for the standard two-step flow, or use POST /execute when you don’t need a price preview step.

Authorizations

x-api-key
string
header
required

Body

application/json
chainId
integer
required

EVM chain id. 8453 for Base (current Phase-1 target).

Required range: x >= 1
tokenIn
string
required

20-byte hex address. The sentinel 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE (or the zero address) signals the chain's native asset (ETH on Base) and is recognized in tokenIn/tokenOut.

Pattern: ^0x[a-fA-F0-9]{40}$
tokenOut
string
required

20-byte hex address. The sentinel 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE (or the zero address) signals the chain's native asset (ETH on Base) and is recognized in tokenIn/tokenOut.

Pattern: ^0x[a-fA-F0-9]{40}$
amountIn
string
required

Non-negative integer encoded as a decimal string (wei).

Pattern: ^[0-9]+$
slippageBps
integer
required
Required range: 0 <= x <= 10000
maxHops
integer
Required range: x >= 1
splitEnabled
boolean
enforcePoolDisjoint
boolean
allowedDexes
enum<string>[]
Minimum array length: 1
Available options:
UNIV2,
UNIV3,
UNIV4,
AERODROME_V2LIKE,
AERODROME_CL,
PANCAKE_V2,
PANCAKE_V3,
PANCAKE_INFINITY_CL,
HYDREX,
QUICKSWAP_V4,
ALIEN_BASE_V3,
CURVE,
PROPSWAP,
TESSERA,
ELFOMOFI,
LUNARBASE,
FELTIR,
DODO_V2,
WOOFI,
GYROSCOPE_ECLP,
MAVERICK_V2
feeBps
integer

Integrator fee in bps, charged out of the output amount.

Required range: 0 <= x <= 10000
taker
string

20-byte hex address. The sentinel 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE (or the zero address) signals the chain's native asset (ETH on Base) and is recognized in tokenIn/tokenOut.

Pattern: ^0x[a-fA-F0-9]{40}$
timeBudgetMs
integer

Per-request override of the optimizer's wall-clock budget. Omit to inherit the engine default.

Required range: 50 <= x <= 10000

Response

Quote produced

quoteId
string
required

SHA-256 (or HMAC-SHA256 if the server has O1_QUOTE_SIGNING_KEY set) of the quote payload. Echo this on /submit.

routePlan
object
required
expiresAt
integer<int64>
required

Unix epoch milliseconds at which the cached quote drops.