For the complete documentation index, see llms.txt. This page is also available as Markdown.

/v3/quote - Request a swap quote

Obtain a quote before performing a swap.

Method: POST URL: https://api.swapkit.dev/v3/quote

The first step towards performing a swap is requesting a quote, which will compare the price offered by the different swap providers.

Quotes are cached for 5 minutes, and can be used to obtain swap transaction details.


Request Schema

Here's a detailed description of the different parameters:

Parameter
Type
Required
Description

sellAsset

string

Yes

The asset being sold (e.g. "ETH.ETH").

buyAsset

string

Yes

The asset being bought (e.g. "BTC.BTC").

sellAmount

string

Yes

Amount in basic units (decimals separated with a dot).

sourceAddress

string

No

Blockchain address to send the asset from. Must be a valid address for the sell asset's chain Note - This is optional. By providing here we can screen the address against our index of bad addresses. Full screen is done in the /v3/swap endpoint Refunds go here — there's no separate refundAddress. Must be an address the user controls and can receive at, not an exchange deposit address.

destinationAddress

string

No

Recipient blockchain address to send the asset to. Must be a valid address for the buy asset's chain Note - This is optional. By providing here we can screen the address against our index of bad addresses. Full screen is done in the /v3/swap endpoint

providers

array

No

Limits the possible liquidity providers. If omitted, all available providers are used.

slippage

number

No

Max slippage in percentage (5 = 5%).

affiliateFee

number

No

Affiliate fee override in basis points (0-1000, max 10%). Must be a positive integer. If it is not provided, the API key configured fee tiers are applied.

cfBoost

boolean

No

Enables Chainflip boost for better rates.

maxExecutionTime

number

No

Maximum execution time in seconds. Routes exceeding this time are filtered out.

quoteType

string

No

"EXACT_INPUT" (default) or "FLEX_INPUT". Controls how the provider treats the input amount. See Flex input quotes below.

usePrivacyMode

boolean

No

Set to true to request a privacy-preserving swap, where the trade details aren't exposed publicly while the swap executes. Acts as a filter. See Privacy mode. Default: false.

enableSweep

boolean

No

Set to true to enable sweeping wallet funds when the transaction would otherwise leave unspendable dust in the address. Default: false

gasCheck

boolean

No

Set to true to check the wallet's native gas balance and warn when it can't cover the network fee. Opt-in, and applies to token sells only. The check runs at /v3/swap, which inherits this value unless it sets its own — no insufficientGas warning appears in the /v3/quote response. Default: false.

txHints

array

No

Only return routes your wallet can sign: simpleTransfer (transfer to a deposit address), transferWithMemo (transfer carrying a memo or OP_RETURN), or contractCall (calldata submitted to a contract). No match returns 404 noRoutesFound.

Note: Asset names for sellAsset and buyAsset should follow the following nomenclature:

  • Chain.Asset (e.g., "BTC.BTC" or "ARB.ETH")

  • Chain.Asset-ContractAddress (e.g., "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")

This is the identifier as provided in the /tokens or /swapTo endpoints.


Flex input quotes

The optional quoteType parameter controls how the amount you send is treated by the swap provider.

Value
Description

EXACT_INPUT (default)

The exact sellAmount is swapped. This is the standard behaviour and applies when quoteType is omitted.

FLEX_INPUT

Swaps whatever is actually deposited instead of requiring the exact sellAmount. Set it when your deposit amount isn't fixed at quote time.

By default a quote assumes you'll deposit the exact input amount you asked for. Flexible input relaxes that: the amount that actually arrives may differ from the quote, and the route settles on whatever it receives.

It applies in three cases:

  • Sending a full balance. When the wallet sweeps its whole balance (when enableSweep is set), the exact amount isn't known until send time, so flexible input is applied automatically.

  • Manual sends. If the user signs and sends the transaction themselves and might deposit a slightly different amount than quoted, pass quoteType: FLEX_INPUT so the first leg tolerates the difference.

  • Multi-provider routes. On any leg after the first, the input is the previous leg's output, which isn't known exactly ahead of time — so flexible input is turned on automatically for those legs.

When you pass FLEX_INPUT, only routes where every provider supports flexible input are returned — any route containing a provider that doesn't is dropped.

Flexible input is decided entirely at quote time. Both the behaviour and the route filtering happen at /v3/quote; it can't be set at /swap, which only executes the route you've already picked.

The providers that support FLEX_INPUT are:

  • THORCHAIN_STREAMING

  • MAYACHAIN_STREAMING

  • CHAINFLIP

  • CHAINFLIP_STREAMING

  • NEAR

  • FLASHNET

Privacy mode

The optional usePrivacyMode parameter requests a privacy-preserving swap, where the trade details aren't exposed publicly while it executes. Off unless you ask for it. Today it's fulfilled through NEAR Intents' Confidential Intents, though the parameter describes the capability rather than any one provider's implementation.

It's a filter, not a preference: only routes where every provider supports a privacy mode are returned. A route whose second hop is public exposes the trade just as thoroughly as a fully public one, so partial privacy is treated as no privacy. NEAR is the only privacy-capable provider today, so requesting privacy narrows you to the pairs NEAR Intents covers.

Privacy mode is decided entirely at quote time. You can't set it at /v3/swap, which inherits the mode from the quote it executes. The flag isn't echoed in the response, so track it against routeId on your side.

Tracking is unaffected: /track resolves these swaps normally, including by depositAddress, because it reads the provider's status API rather than the public explorer.

Example request

A simple request to trade ETH.ETH to BTC.BTC may omit the providers array if you can manage them in the response, but should include the amount and slippage settings.

A quote expires after 5 minutes. Once it does, you can request a new one, or one will be requested automatically if a swap is initiated using this routeId .

Using the header x-api-key in your /quote request automatically applies your affiliate addresses and fee values set up through our partners dashboard in the response parameters.


Quote Response Schema

Field
Type
Description

quoteId

string

UUID for this quote response

createdAt

string

ISO 8601 timestamp of when this quote response was created. Top level — a sibling of quoteId, not a per-route field.

routes

QuoteRoute[]

An array of routes with an individual routeId to request a swap with. QuoteRoute schema is explained below

providerErrors

QuoteError[] or undefined

Optional. Providers that were asked for a quote and declined. Present on a 200 response — it does not mean the request failed. Schema below; the codes are listed in Route availability and providers errors.

error

string or undefined

In case of a bad request, root level error is provided.

Quote Route Schema

Each route identifies a provider or a group of providers for the swap. Each item in the routes array contains the information needed to compare between them:

Field
Type
Description

routeId

string

UUID of this specific swap response.

providers

array

List of providers available for this route (CHAINFLIP, THORHCAIN etc.).

sellAsset

string

The asset being sold (e.g., “ETH.ETH”).

buyAsset

string

The asset being bought (e.g., “BTC.BTC”).

sellAmount

string

Amount of the sell asset in smallest units.

expectedBuyAmount

string

Estimated amount of the buy asset to be received.

expectedBuyAmountMaxSlippage

string

Worst-case buy amount considering max slippage.

fees

array

List of fees applied to the swap (inbound, network, affiliate, service, outbound, liquidity).

estimatedTime

object

Estimated time for different phases of the swap.

totalSlippageBps

number

Expected total slippage.

legs

array

The different steps invovled in the swap.

warnings

array

Potential warnings about this swap provider.

txHint

string (enum, optional)

How the deposit must be sent for this route — one of simpleTransfer (plain value transfer), transferWithMemo (transfer that must include the memo), or contractCall (submit as a smart-contract / EVM transaction). Returned at quote time so you can filter routes against your wallet's signing capabilities before calling /v3/swap, and guaranteed to match what /v3/swap builds for the same routeId. Absent on route patterns SwapKit hasn't classified — treat missing as unknown.

meta

object

Other information about the transaction and the assets involved.

meta.tags

array

"FASTEST", "RECOMMENDED" or "CHEAPEST" tag help sort the available routes.

nextActions

object

Data needed for the next request in the flow. { method: string; url: string; payload: object }


Quote Error Schema

Field
Type
Description

provider

string

Specific ProviderName value

errorCode

string

One of the possible error codes listed below.

message

string

Message relating to thrown error.

minAmount

string or undefined

The provider's minimum sell amount in human units, when the provider reported one. Present on most sellAssetAmountTooSmall entries — retry at or above it.

Quote Error Codes and messages

Error
Message
Status Code
Scenario

noRoutesFound

No routes found for swap from {sellAsset} to {buyAsset}

404

No valid swap path exists between the requested token pair.

blackListAsset

Asset {asset} is blacklisted

400

The sell or buy asset is identified as a scam token in our blacklist.

apiKeyInvalid or unauthorized

"Invalid API key" / "Unauthorized”

401

Missing, expired, or invalid API key in x-api-key header.

invalidRequest

"Request body is required and must be a valid JSON object”.

400

Request body is missing, null, or malformed JSON.

solanaOutputBelowRentExemptMinimum

Guaranteed output of {minimumOutput} lamports is below the {minimum} lamport rent-exempt minimum needed to fund destination {address}. Increase the swap amount or send to an existing account.

400

Same-chain Jupiter swap buying native SOL for a destinationAddress other than the sender, where the post-slippage minimum output is under Solana's 890,880-lamport (0.00089088 SOL) rent-exempt floor. No on-chain existence check, so an already-funded destination is rejected too. Raise the sell amount, or deliver to sourceAddress.

solanaTokenProgramUnavailable

Could not resolve the Solana token program for mint {tokenAddress}. Please retry.

502

Transient. SwapKit could not determine whether an SPL mint is Token or Token-2022 while preparing a same-chain Solana destination. Safe to retry.

The invalidRequest error may include additional details depending on the missing parameters. Make sure to check the JSON formatting in the request.


Fees breakdown

Fees are categorized into different types based on their role in the swap process.

Fee Type
Description

Inbound

Cost of getting the sell asset to the provider: estimated gas for the deposit, plus any provider ingress fee. Two entries when they're in different assets.

Network

Blockchain transaction fee for processing the swap.

Affiliate

Fee paid to the specified affiliate.

Service

SwapKit's service fee.

Outbound

Fee for transferring the buy asset to the destination address.

Liquidity

Fee applied by the liquidity provider to facilitate the swap.

Fees other than inbound are already reflected in expectedBuyAmount, whether taken from the input or the output — don't subtract them again. inbound is the only fee your wallet funds on top of sellAmount, and it isn't reflected in expectedBuyAmount.

Chainflip is the exception. Its inbound combines your gas with Chainflip's ingress fee, and only the gas is paid on top of sellAmount — the ingress is already reflected in expectedBuyAmount. Token deposits return the two separately (ingress in the deposited asset, gas in the chain's gas asset); native deposits sum them into one entry, so budget the full amount as an upper bound.


Estimated time

The estimated time in seconds for the swap is divided into the following phases:

  • Inbound: Time taken to receive the sell asset.

  • Swap: Time taken for the swap process.

  • Outbound: Time taken to transfer the bought asset to the destination. This includes the provider outbound time, not only the transaction time.

  • Total: The sum of all time estimates.

Example estimated time:


Route metadata

The meta section provides additional information about the swap.

assets

Details of the involved assets, including price and image links.

tags

["FASTEST", "RECOMMENDED", "CHEAPEST"]

approvalAddress

Token-approval spender address. Present only for EVM ERC-20 sells that require an approval.

/v3/swap returns a larger meta than this. Fields that only exist once a transaction is built — allowance, and the deposit-channel fields providerDepositChannelId / depositChannelExpiration — are documented on that page. /v3/quote never opens a deposit channel, so they never appear here.

Example meta Object:

The "tags" help identify what SwapKit considers the best routes by filtering through the ["FASTEST", "RECOMMENDED", "CHEAPEST"] labels.

Tag
Description

RECOMMENDED

Best overall route based on output and speed.

CHEAPEST

The route with the maximum output.

FASTEST

The route with the shortest total estimated time.

To determine the RECOMMENDED route when multiple options are available, each route gets two normalized scores:

  • Output score (0-100): Compare the route's output to the maximum output of the available routes, multiplied by 100 for weight. (routeOutput / maxOutput) * 100

  • Time score (0-50): Compare the route's expected confirmation time to the minimum confirmation time of the available routes, subtracting from 50 to give it a dynamic weight. The fastest route will obtain 50 points here. 50 - abs(routeTime - minTime) / (maxTime - minTime)

Output and time are weighted dynamically, depending on the difference between the fastest route and the one being analyzed.

Time spread (Current vs Fastest)
Output weight
Time weight

≤ 60 seconds

100 %

0 %

60s - 5 min

95 %

5 %

5 - 15 min

90 %

10 %

> 15 min

80 %

20 %

The weights are then multiplied to the score, and the route with the highest total is tagged as RECOMMENDED . It is simply outputScore * outputWeight + timeScore * timeWeight .


Next Actions

The nextActions object includes information about the request to make next. Generally it will point to the /swap endpoint which will return a transaction object, but for ERC-20 tokens the /swap endpoint may first return an approvalTx for spending approval, requiring a second /swap call to get the transaction.

For example, it could look like the following, which includes the method, url and payload to use. The "soureAddress" and "destinationAddress" need to be filled in:

Last updated