---
title: "Quote on any chain: Chord first, a fallback only when it fails"
method: GET
path: "/meta/quote"
tags: ["Meta aggregator"]
---

# Quote on any chain: Chord first, a fallback only when it fails

`GET /meta/quote`

## Request

- Base URL: `https://api.getchord.xyz/v1`
- URL: `https://api.getchord.xyz/v1/meta/quote`
- Auth: none declared

One call that ends in a route you can sign or an honest "no route anywhere". Without `taker` it is a price; with `taker` it also returns the unsigned transaction, the approval it needs and a simulation.

**Policy**
1. Chord's own router is always asked first, with its normal budget.
2. A fallback is asked only when Chord fails: the engine timed out, errored or is down; there is no route; Chord refuses the route itself (value guard, taxed token, stale bonding-curve route); the chain's router is not live; or the built transaction fails simulation. A better price elsewhere is not a reason. A user error (unknown token, bad amount) never falls back.
3. Fallbacks are tried in the chain's order (`GET /meta/providers`); the first answer that passes every check wins. Per provider 4 s, whole request 9 s, a circuit breaker per provider and chain.

**Safety, on every fallback answer**
- The transaction target and the approval spender must be on Chord's allowlist for that provider and chain, and deployed there.
- `minAmountOut` comes from your slippage; a provider minimum below it is refused.
- The value guard of `/quote` applies: an output worth 30 % less than the input at Chord's prices is refused. An unpriced token gets a security scan (`safety`); a honeypot is refused.
- With `taker`, the transaction is simulated as that wallet and must deliver at least `minAmountOut`. A fallback transaction that cannot be simulated is never returned.
- Without `taker`, a fallback price is shown only after the provider BUILT the route and it was simulated for a placeholder wallet (`PRICE_CHECKED`); a provider that prices a size but will not build it is skipped. The placeholder's transaction is never returned.
- An input the simulation cannot supply (a balance that is not a plain storage mapping, e.g. rebasing shares) while the taker does not hold it: HTTP 422 `INPUT_NOT_SIMULATABLE` — hold the input and ask again.

**Notes**
- `provider: null` with HTTP 200 means every provider looked and none has a route. HTTP 503 `UNAVAILABLE` means nobody could answer right now: retry, do not conclude the pair is untradeable.
- The answer is good until `expiresAt` (30 s). Quote again before signing if you waited.

## Query parameters

- `chain` string, required
- `tokenIn` string, required: EVM address, hex, case-insensitive.
- `tokenOut` string, required: EVM address, hex, case-insensitive.
- `amount` string, required: Amount in the token's smallest unit, as a decimal string. Never a float.
- `slippageBps` integer
- `taker` string: EVM address, hex, case-insensitive.

## Response `200`

The quote. Read `provider` and `fallbackReason` before anything else.

- MetaQuote: The same shape whichever provider answered.
  - `chain` integer: Chain id.
  - `tokenIn` string: EVM address, hex, case-insensitive.
  - `tokenOut` string: EVM address, hex, case-insensitive.
  - `amountIn` string: Amount in the token's smallest unit, as a decimal string. Never a float.
  - `taker` string, nullable: The wallet the transaction was built and simulated for; null on a price-only quote.
  - `slippageBps` integer: The slippage `minAmountOut` reflects.
  - `provider` string, nullable: Who answered: `chord` (Chord's own router), `kyberswap`, `monorail`, `lifi`, `relay`. `null` = no provider has a route.
  - `fallbackReason` string, nullable: `null` when Chord answered. Otherwise why it did not: `no_route`, `insufficient_liquidity`, `engine_error`, `engine_timeout`, `engine_down`, `value_guard`, `taxed_token`, `route_stale`, `chain_not_live`, `build_failed`, `simulation_failed`.
  - `attempts` MetaAttempt[]: Every provider asked, in order.
    - `provider` string: `chord`, `kyberswap`, `monorail`, `lifi` or `relay`.
    - `status` string: `ok`, or why this provider did not produce the answer: `no_route`, `timeout`, `http_error`, `rate_limited`, `invalid_response`, `not_allowlisted`, `calldata_mismatch`, `min_out_too_low`, `value_gap`, `unsafe_token`, `simulation_failed`, `unverified`, `breaker_open`, `skipped`; for Chord also `engine_error`, `engine_timeout`, `engine_down`, `route_refused`, `build_failed`, `chain_not_live`.
    - `ms` integer: Time spent on this provider.
    - `error` string, nullable: Short reason from a fixed vocabulary, never provider text.
  - `amountOut` string: What the taker receives after every fee, smallest unit of `tokenOut`. (`/quote`'s `outputAmount` is before Chord's fee; this is after.)
  - `minAmountOut` string: The minimum the transaction enforces, from the slippage you asked for.
  - `priceImpactPct` string, nullable: Percent, when the provider states one.
  - `valueLossPct` number, nullable: Output value against input value at Chord's own prices, percent (negative = worth more). `null` when Chord has no reliable price for a side: see `safety` and `warnings`.
  - `feeBps` integer: Chord path: Chord's protocol fee on the output. Fallback: the integrator fee Chord added (0 today); the provider's own fees are already inside `amountOut`.
  - `feeRecipient` string, nullable: EVM address, hex, case-insensitive.
  - `route` object
    - `venues` string[]: Venue names.
  - `tx` object, nullable: The UNSIGNED transaction. `null` without `taker`. `to` is the Chord router when `provider` is `chord`, the provider's own router otherwise.
    - `to` string: EVM address, hex, case-insensitive.
    - `data` string: Calldata.
    - `value` string: Amount in the token's smallest unit, as a decimal string. Never a float.
    - `gas` string, nullable: Gas limit to sign with.
    - `chainId` integer
  - `approval` object, nullable: The approval to send first. `null` for a native input or when the taker's allowance already covers the amount.
    - `token` string: EVM address, hex, case-insensitive.
    - `spender` string: EVM address, hex, case-insensitive.
    - `amount` string: Amount in the token's smallest unit, as a decimal string. Never a float.
    - `resetFirst` boolean: Present only for a token that reverts `approve(x > 0)` while its allowance is non-zero (USDT on Ethereum). `true` = the taker has a left-over allowance: send `approve(spender, 0)` first, then this approval.
  - `simulation` object, nullable: The transaction run as the taker (with the input supplied when the taker does not hold it), measuring the taker's own balance change. `null` without `taker`.
    - `ok` boolean, nullable: `true` = ran and delivered at least `minAmountOut`; `null` = no verdict (only ever returned on the Chord path).
    - `amountOut` string: Amount in the token's smallest unit, as a decimal string. Never a float.
    - `gasUsed` integer
    - `revert` string
    - `reason` string
  - `safety` object, nullable: A security scan of the unknown token, present when the value check could not run on a fallback answer.
    - `source` string: `goplus`
    - `token` string: EVM address, hex, case-insensitive.
    - `worstFlag` string: `none`, `low`, `medium`, `high`.
    - `honeypot` boolean, nullable
    - `buyTaxPct` number, nullable
    - `sellTaxPct` number, nullable
    - `risks` string[]
  - `warnings` string[]: `INSUFFICIENT_BALANCE`, `UNPRICED`, `OUTPUT_WRAPPED`, `NO_ROUTE`, and on a price-only fallback `PRICE_CHECKED` (built and simulated for a placeholder wallet) or `UNVERIFIED_PRICE` (built, not simulatable) — each followed by a sentence.
  - `quoteId` string: Pass to `POST /meta/swap` within 2 minutes.
  - `expiresAt` integer: Unix time, seconds, UTC.

## Other responses

- `400`: Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).
- `422`: The request is valid but cannot be served as asked (`INPUT_NOT_SIMULATABLE` on `/meta/*`: a route exists, but the input token cannot be supplied in a simulation and the taker does not hold it — hold the input and ask again).
- `429`: Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.
- `503`: 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.

---

[API](https://skmtc.dev/getchord/apis/chord-api.md) · [All operations](https://skmtc.dev/getchord/apis/chord-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getchord/apis/chord-api/revisions/d3bc4640fea0?raw)
