---
title: "Get a cross-chain swap quote"
method: POST
path: "/api/v1/quote"
tags: ["Swap"]
---

# Get a cross-chain swap quote

`POST /api/v1/quote`

## Request

- Base URL: `https://app.ravn.exchange`
- URL: `https://app.ravn.exchange/api/v1/quote`
- Auth: one of:
  - API key in header `x-api-key`
  - none

## Request body

- object
  - `quoteSessionId` string
  - `inputChainId` 1 | 10 | 56 | 130 | 137 | 324 | 480 | 999 | 143 | 8453 | 42161 | 59144 | 43114 | 4663 | 4217 | -1 | -2, required
  - `outputChainId` 1 | 10 | 56 | 130 | 137 | 324 | 480 | 999 | 143 | 8453 | 42161 | 59144 | 43114 | 4663 | 4217 | -1 | -2, required
  - `inputToken` string, required: Token contract address, or the native-token sentinel 0xEeee...EEeE
  - `outputToken` string, required
  - `inputAmount` string, required: Positive integer string, in the input token's smallest unit
  - `userAddress` string, required
  - `destinationAddress` string: Where output should land. Required at quote time for a real (executable) quote from Relay (Bitcoin as source or dest), THORChain (Bitcoin either direction), Across (Solana-touching), Eco (cross-ecosystem), or compose (RAVN two-hop routes). Omit it there and you get a preview (QuoteDTO.executable=false). Validated here, not only at execute: a malformed address, an address from the wrong ecosystem for the output chain, or a known non-wallet address (any RAVN-listed token's mint/contract, this swap's own tokens, the native-coin sentinel, burn addresses, Solana core programs — funds sent there are unrecoverable) is rejected with INVALID_REQUEST. A Solana address is also looked up on chain: a token account (the message names the wallet that owns it) or a program is rejected; this lookup fails open, so an RPC outage never blocks a quote. An empty string means not supplied.
  - `refundAddress` string: Where to refund the input asset if the swap fails. Selling native Bitcoin with userAddress set to a Bitcoin address and no refundAddress refunds to userAddress (the address the BTC is sent from); with any other userAddress, supply it. Well-known sample addresses (e.g. bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh) count as no address: supply the real refund. For a Bitcoin-source Relay or THORChain quote, the refund must be known here, at quote time — neither has an execute-time re-bind, so without one it returns a priced-but-unexecutable preview and supplying it later on execute is refused. Other BTC-source venues (Garden, Chainflip, Rift, NEAR Intents) support binding this at execute time instead. Validated against the INPUT chain (refunds are paid back on the origin), including the token's-own-address check described on destinationAddress.
  - `slippageBps` integer: Max slippage in basis points. Omitted means Auto: 50, wider where a route needs it (slippage.bps reports the figure used). Setting it drops venues that enforce no minimum (slippage.noMinimum: true, today Rift) from the race, since your figure is a protection they can't give — unless allowNoMinimum is true.
  - `allowNoMinimum` boolean: Let venues that enforce no minimum (today Rift) race even though slippageBps is set. Such a quote fills at the venue's own rate once the deposit lands: it carries slippage.noMinimum: true, slippage.guaranteedMin null, and your slippageBps does not protect it. Without slippageBps they already race. Defaults to false.
  - `rankingMode` 'best_output' | 'fastest': Defaults to best_output.
  - `excludeVenues` string[]: Drop specific venues — e.g. a risk objection to one of them. An excluded venue is used nowhere in the route, including the steps of RAVN's own multi-step routes (venue.id "compose", and "relay" quotes that carry hops); a multi-step route that needs it isn't offered. Venues that swap for you may route through other venues of their own choosing, which this can't reach: Layerswap (a Solana token often goes through Jupiter first), Relay, Rift, Across (when it swaps before or after bridging) and Mayan (Jupiter on Solana, other DEXs such as Nordstern on EVM). Naming a venue that was never eligible for this pair is a no-op, not an error.
  - `onlyVenues` string[]: Race only these venues — e.g. ["bebop"] for an RFQ-only race. Every other venue is left out, including any RAVN adds later, and excludeVenues still applies on top. It covers every venue RAVN routes your funds through: a multi-step route is offered only when its own venue.id and every venue in its hops are listed — e.g. ["compose", "jupiter", "relay"] for RAVN's routes through Jupiter and Relay, or ["relay", "kyberswap"] for a Relay quote that buys through KyberSwap on arrival. RAVN's stablecoin route also needs "0x_swap" beside its hops: it sweeps the leftover. Venues that swap for you may route through other venues of their own choosing, which this can't reach: Layerswap (a Solana token often goes through Jupiter first), Relay, Rift, Across (when it swaps before or after bridging) and Mayan (Jupiter on Solana, other DEXs such as Nordstern on EVM). Same-chain venues (Bebop, 0x, Kyber, OKX…) only quote same-chain pairs; when none of the named venues can quote, you get NO_LIQUIDITY with every left-out venue in excludedVenues. An empty list is rejected rather than read as no restriction.
  - `confidential` boolean: Settle privately: the on-chain deposit and payout cannot be linked to each other. The race narrows to the private venues — NEAR Intents' Confidential Intents and Houdini Swap's two-hop exchange route — and the best output wins; you get NO_LIQUIDITY rather than a public fill if neither can quote. Measured cost: NEAR ~0.3 bps more on EVM-to-EVM and ~5-8 bps more when Bitcoin or Solana is a leg; Houdini ~3% below spot on its fixed-rate quote, which is not a guaranteed minimum (so it wins only where NEAR can't quote). Both can settle slower than a public swap (NEAR Bitcoin-source 43 min; Houdini a few minutes to about an hour), so read estimatedTimeSeconds before executing. A Houdini quote is valid until expiresAt (Houdini holds each price for 60 seconds from when RAVN fetched it). Neither venue takes your integrator fee itself: from an EVM chain or Solana (and NEAR from Bitcoin) RAVN collects it beside the deposit (the execution's fee) — from Solana as a transfer to RAVN inside the same transaction that pays the deposit. Houdini is sent your request's IP and user-agent (plus clientTimezone) for its compliance screening, and its terms bar US persons and sanctioned jurisdictions: Houdini is left out of the race when this request arrives from such a country, and you are responsible for your end users' eligibility — pass excludeVenues: ["houdini"] where that cannot be met. Confidentiality is the venue's, not RAVN's, and remains subject to its screening.
  - `clientTimezone` string: Your end user's IANA timezone (e.g. Europe/Berlin), forwarded only to venues whose API requires the user's details on every call (Houdini). Defaults to UTC.
  - `sandbox` boolean: Test the full quote -> execute -> status flow with no real funds and no live venue settlement. The quote itself is still priced live. On /v1/execute nothing is opened at a venue: where building would open an order, a deposit address or channel, or spend real money (NEAR Intents, Rift, Garden, Layerswap, Houdini Swap, Chainflip, RAVN two-hop routes, THORChain from Bitcoin) you get a stand-in DEPOSIT of the input to your user's own wallet (the refund address, else userAddress; selling Bitcoin needs one of them to be a Bitcoin address), even where the live route is a transaction; every other venue returns its real payload, built live: a transaction or typed data that swaps for real if you send it or submit it to the venue yourself, and Relay from Bitcoin the live deposit address it opened when it quoted. Every sandbox execution carries `sandbox: true`: never send it. /v1/submit-signature and /v1/submit-transaction skip the real submission. /v1/status always reports an immediate synthetic success. Sandbox swaps are never metered or billed.
  - `timeoutMs` integer: The race's time limit in milliseconds, counted from when it starts. Once it has passed and some venue has priced the swap, venues still silent are left out (they aren't in alternatives) and the best of the rest is returned. If none has priced by then, the race waits for the first price (up to each venue's own limit, 10 s for most) and then leaves out the rest. A quote with slippage.noMinimum counts as a price only 2000 ms past the limit, so venues that hold a minimum get that long to answer. Defaults to 6000, the limit RAVN's app uses; a positive integer, clamped to 1000–15000. RAVN's own route gets 2000 more on pairs where its cross-chain WBTC plan races. Lower it to answer sooner, raise it to wait for slower venues.
  - `broadcastViaRavn` boolean: Set if you can post a signed Solana transaction back to RAVN instead of broadcasting it yourself. It adds routes that only work when RAVN checks or lands the signed transaction: Layerswap's memo payments, which sell a Solana wallet's USDC (or any Solana token via Jupiter) into native BTC or a Robinhood Chain stock with no account rent — often the best price under ~$200; and Jupiter's market-maker (JupiterZ) and gas-sponsored orders, which a market maker or Jupiter signs too, inside Jupiter's own landing (a long-tail Solana token can price 7–33 bp better). Without it, Jupiter quotes only orders your user signs alone, and one that needs Jupiter's gas sponsor (a wallet short of SOL) is a preview (executable false). When /v1/execute returns a TRANSACTION with `submit` (every Jupiter one, a two-hop route's first step included — except an order carrying your fee under Jupiter's 50 bps minimum: RAVN's fee transfer is added to it, which Jupiter's landing doesn't take, so it comes without `submit` for your user alone to sign), sign `transaction.serialized` and POST { quoteToken, signedTransaction } to `submit.url` (/v1/submit-transaction) instead of broadcasting it, within seconds (for Jupiter RAVN answers once it has landed: allow the call up to 2 minutes; posting the same signed transaction again is safe); transactions without `submit` you still broadcast yourself.

## Response `200`

Quote produced

- object
  - `data` QuoteDTO
    - `quoteToken` string, required: Opaque handle — pass back to POST /v1/execute verbatim. Do not parse.
    - `venue` object, required
      - `id` string, required
      - `name` string, required
    - `routeType` string, required
    - `input` object, required
      - `token` TokenDTO, required
        - `symbol` string, required
        - `name` string, required
        - `address` string, required
        - `decimals` number, required
        - `chainId` number, required
        - `isNative` boolean, required
        - `logoUrl` string
      - `amount` string, required
    - `output` object, required
      - `token` TokenDTO, required
        - `symbol` string, required
        - `name` string, required
        - `address` string, required
        - `decimals` number, required
        - `chainId` number, required
        - `isNative` boolean, required
        - `logoUrl` string
      - `amount` string, required
    - `fee` object, required: The integrator fee actually baked into this quote, in bps, with the amount actually deducted in `token`'s base units — the output token everywhere except Fly Trade and Mayan, which take their fee from the input token, 0x Solana, which takes it from whichever side RAVN can receive it on, and OKX, which takes it from the input when the output is a native coin (EVM) or a token RAVN can't hold (Solana). Mayan from Solana pays it in neither: `token` is then the asset its order locks on Solana (USDC, USDT, Wormhole WETH) or USDC on the destination chain, and `amount` the least that arrives — except on a route paying no referrer, which carries RAVN's own fee in the input token. Relay charges it in the currency its own quote names: the input when its solver holds it (ETH, USDC, SOL, BTC), else a solver coin on the origin chain (ETH, or a stablecoin such as USDC or OUSD) — `token` and `amount` are Relay's. A RAVN two-hop route (compose) carries it on hop 1 when hop 1 is 0x, 0x Gasless, Bebop, KyberSwap, Fly Trade or Nordstern, in that venue's token, booked at hop 1's minimum; it is owed once POST /v1/status is given the hop-1 tx (`txHash`) that paid it (a gasless 0x or Bebop hop 1: once the venue's record of the signed trade shows it paid). Always the honest, effective figure; on NEAR Intents that includes 1Click's own fee, which it takes from the input on every swap, with or without yours (the output already reflects it): 20 bps with no fee set (1 bp when both tokens are USDC, USDT or DAI, or the same asset), with yours half of it plus the larger of that half and 20 (1) bps, and its 20 (1) bps on top of RAVN's own fee beside a private swap — so NEAR never shows `bps: 0`; Rift, private swaps (`confidential`: NEAR Intents, Houdini Swap), Eco and Layerswap have no fee of their own: RAVN collects it beside the swap (the execution's `fee`), in the input token, and the venue is quoted on the rest; it is owed once paid (EVM: the fee tx's hash on POST /v1/status `txHash`, or the swap's own tx when batched with it; Bitcoin and Solana: found in the deposit's own transaction, or from Solana where RAVN builds the transaction, in the swap's own). Private swaps from Solana carry it too; so do Layerswap's route from Solana and Mayan's from Solana that pay no referrer, inside the transaction RAVN builds, and Jupiter under its 50 bps minimum, inside its order's transaction (nothing more to send). Eco from Solana and Eco or Layerswap from Bitcoin stay fee-free for now. `supported: false` means the venue has no fee mechanism at all on this route (Eco from Solana or Bitcoin, Layerswap or Houdini from Bitcoin) and any feeBps on this API key was silently unable to apply, regardless of `bps` (which will be 0). `supported: true` with `bps: 0` means the venue can carry a fee but none was requested — a real, intentional 0 — or that it couldn't on this pair: 0x Solana when RAVN has no account for either token, Jupiter when its order is co-signed (a JupiterZ market maker, with broadcastViaRavn) or has no room for the fee — then priced on the input less the fee — or when it takes its fee in a token RAVN has no referral account for, a two-hop route whose hop 1 runs through another venue, or Rift from Bitcoin when the fee would be under Bitcoin's 546-sat dust limit (a private NEAR swap from Bitcoin then shows 1Click's fee alone).
      - `bps` number, required
      - `amount` string, required
      - `token` TokenDTO, required
        - `symbol` string, required
        - `name` string, required
        - `address` string, required
        - `decimals` number, required
        - `chainId` number, required
        - `isNative` boolean, required
        - `logoUrl` string
      - `supported` boolean, required
    - `executable` boolean, required: False means this is a preview-only price — usually because the venue needs a real destinationAddress and/or refundAddress that wasn't supplied, and priced against a placeholder instead. POST /v1/execute on `quoteToken` will fail with QUOTE_NOT_EXECUTABLE; request a fresh quote with those fields supplied instead.
    - `slippage` SlippageDTO, required: `noMinimum`: the venue enforces no minimum (Rift) — `bps` is then not a protection.
      - `bps` number, required
      - `isFirm` boolean, required
      - `guaranteedMin` string, nullable, required
      - `noMinimum` boolean, required
    - `gas` object, nullable, required
      - `native` string, required
      - `nativeSymbol` string, required
      - `usd` string, nullable, required
      - `estimated` boolean, required
    - `inputUsd` string, nullable, required: USD value of the input amount. Same price source as `gas.usd` (DefiLlama). Null when the token can't be priced.
    - `outputUsd` string, nullable, required: USD value of the output amount. Same price source as `inputUsd`/`gas.usd`.
    - `estimatedTimeSeconds` number, required
    - `estimatedTimeIsGuess` boolean, required: True when the time is RAVN's estimate, not the venue's own figure — see Quote.estimatedTimeIsGuess.
    - `expiresAt` number, required: Epoch ms, always a real time: POST /v1/execute on `quoteToken` before this, and re-quote after. RAVN never refuses the quote for age before it; past it most routes return 410 QUOTE_EXPIRED. Already 5 s ahead of the venue's own deadline (room for the wallet to sign), so compare it to the clock as is. Routes execute holds to no clock get 60 s from the response: two-hop RAVN routes (`venue.id === "compose"`: execute re-prices both hops and refuses only if the minimum shown can no longer be met) and venues that state no deadline.
    - `hops` object[]: Present on RAVN routes (`venue.name === "RAVN"`): two-hop (`venue.id === "compose"`) and Relay dest-call (`venue.id === "relay"`) quotes, the venues it runs through in order. Sign hop 1; hop 2 is a unique deposit, not a second wallet tx. The stablecoin route also sweeps its leftover through 0x (`0x_swap`), which isn't listed here.
      - `id` string, required
      - `name` string, required
    - `alternatives` AlternativeQuoteDTO[], required: Every other venue that raced and produced a usable quote, best expected net output first (a quote with `slippage.noMinimum` counts 0.3% under its outputAmount, the shortfall such a venue has typically delivered, so it can sit below a quote with a smaller outputAmount; one more than 1% above the best quote that holds a minimum is listed here but never picked as the quote above, since nothing holds that figure, so it can sit above the winner) — the same field already visible via /v1/health, now attached where a caller can actually act on it (pick one, or filter one out with the next request's `excludeVenues`). Input token/amount are identical to the primary quote above; only what's here differs per venue.
      - `venue` object, required
        - `id` string, required
        - `name` string, required
      - `routeType` string, required
      - `quoteToken` string, required: Pass to POST /v1/execute to run THIS route instead of the primary quote.
      - `outputAmount` string, required
      - `fee` object, required: `amount` is in `token`'s base units — the output token everywhere except Fly Trade and Mayan, which deduct their fee from the input token, and 0x Solana, which may. Mayan from Solana, Relay and the rest: see QuoteDTO.fee.
        - `bps` number, required
        - `amount` string, required
        - `token` TokenDTO, required
          - `symbol` string, required
          - `name` string, required
          - `address` string, required
          - `decimals` number, required
          - `chainId` number, required
          - `isNative` boolean, required
          - `logoUrl` string
        - `supported` boolean, required
      - `executable` boolean, required
      - `estimatedTimeSeconds` number, required
      - `estimatedTimeIsGuess` boolean, required
      - `expiresAt` number, required: This route's own execute deadline, same meaning as QuoteDTO.expiresAt. Each venue sets its own (0x Solana and OKX allow less time than most), so check it before executing.
      - `hops` object[]
        - `id` string, required
        - `name` string, required
      - `slippage` SlippageDTO, required: `noMinimum`: the venue enforces no minimum (Rift) — `bps` is then not a protection.
        - `bps` number, required
        - `isFirm` boolean, required
        - `guaranteedMin` string, nullable, required
        - `noMinimum` boolean, required
  - `meta` Meta
    - `requestId` string, required
    - `version` string, required

## Other responses

- `400`: Invalid request / unsupported token or chain
- `401`: x-api-key present but invalid
- `404`: No liquidity for this pair/amount. `error.details` carries { routeType, eligibleVenues, excludedVenues } — eligibleVenues is pre-exclusion, and excludedVenues echoes back the request's excludeVenues (plus every venue its onlyVenues left out) so a caller who excluded every eligible venue can tell that apart from genuine no-liquidity. The lists also cover the steps of multi-step routes, whose venues eligibleVenues doesn't name: leaving out a step's venue drops that route.
- `429`: Rate limited

---

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