Quote v2 API
Quote API computes the best path to swap tokens at the best rate using our Navigator.
With a straightforward API call, you can get the transaction data that will execute the swap without hassle.
Changes since v1
- We don't do gas estimation from now on. This will have similar effect as setting
skipGasEstimation=trueonv1. slippageNumeratorandslippageDenominatornow combined into a singleslippagefield. This is going to be same as fixingslippageDenominatorto10000.- Referrer fee has been implemented. You can now set
referrerFeeToken,referrerFee, andreferrerFeeTofields to receive referrer fee. payWithSCNRfield has been added. With this, you can choose whether to make thefromto pay the Swapscanner fee with SCNR instead of the output token. 20% discount will be applied to the Swapscanner fee ifpayWithSCNRis set totrue.- Preconditions that were previously blocking the
swapTxfrom being returned are now returned aserrorsfield.swapTxwill always be returned. - Response body schema has been drastically changed. Please refer to the Response Body section for more details.
Endpoint
https://api.swapscanner.io/v2/quote
Request Message Schema
{
"domain": {
"name": "Swapscanner Navigator",
"version": "v2",
"chainId": "8217",
"verifyingContract": "0x8888888888888888888888888888888888888888",
"salt": "0xYourSaltHere"
},
"primaryType": "QuoteRequestV2",
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" },
{ "name": "salt", "type": "bytes32" }
],
"QuoteRequestV2": [
{ "name": "issuedAt", "type": "uint256" },
{ "name": "slippage", "type": "uint16" },
{ "name": "from", "type": "address" },
{ "name": "to", "type": "address" },
{ "name": "tokenInAddress", "type": "address" },
{ "name": "tokenOutAddress", "type": "address" },
{ "name": "amount", "type": "uint256" },
{ "name": "referrerFeeToken", "type": "uint8" },
{ "name": "referrerFee", "type": "uint16" },
{ "name": "referrerFeeTo", "type": "address" },
{ "name": "payWithSCNR", "type": "bool" }
]
}
}Security Related Fields
-
issuedAt- UNIX timestamp (in seconds) when you issued the request.issuedAtandsaltwill together work as a countermeasure for replay attacks.Your computer and the Swapscanner API server could be a clock difference, resulting in the message expiring earlier than expected. In such case, try subtracting 1~2 seconds from your current timestamp. However, do not subtract too much since we have TTL.
Trading Related Fields
-
slippage- slippage that thefromwallet would like to allow in BPS (basis points). (e.g. for slippage allowance of 1%, setslippageto 100) -
from- The address of the wallet (or contract) that would like to perform a swap. TokentokenInAddresswill be transferred from this address. -
to- The address of the wallet (or contract) that would like to receive the swapped token. TokentokenOutAddresswill be transferred to this address. In most cases, this should be the same asfromaddress. -
tokenInAddress- Address of the token that thefromwallet would like to provide. -
tokenOutAddress- Address of the token that thefromwallet would like to receive. -
amount- amount oftokenInAddressthat thefromwallet would like to provide. Must be numerated with the decimals of thetokenInAddress. (e.g. 1 KAIA =1000000000000000000)
Referrer Fee Related Fields
-
referrerFeeToken- the token that the referrer would like to receive as a fee (0: same as Swapscanner fee (preferrably stablecoin but can be tokenOut), 1: tokenIn, 2: tokenOut). Set to 0 if you don't want to receive referrer fee. -
referrerFee- the fee that the referrer would like to receive in BPS (basis points) (e.g. for 0.1% fee, setreferrerFeeto 10). Set to 0 if you don't want to receive referrer fee. -
referrerFeeTo- the address that the referrer would like to receive the fee. Set to zero address if you don't want to receive referrer fee.
Swapscanner Fee Related Fields
payWithSCNR- whether to makefromaccount to pay the Swapscanner fee with SCNR or not.
Example Message
{
issuedAt: Math.floor(Date.now() / 1000),
slippage: '10', // 0.1%
from: '0x[ADDRESS_TO_ACCOUNT_WHO_WILL_SEND_SWAP_TX_AND_PAY_INPUT_TOKEN]'.toLowerCase(),
to: '0x[ADDRESS_TO_ACCOUNT_WHO_WILL_RECEIVE_OUTPUT_TOKEN]'.toLowerCase(),
tokenInAddress: '0x[INPUT_TOKEN_ADDRESS]'.toLowerCase(),
tokenOutAddress: '0x[OUTPUT_TOKEN_ADDRESS]'.toLowerCase(),
amount: '1000000',
referrerFeeToken: '1', // collect from input token
referrerFee: '10', // 0.10%
referrerFeeTo: '0x[REFERRER_FEE_TO_ADDRESS]'.toLowerCase()
}Response Codes
200: OK400: Bad Requestused_salt: the salt given is already used once and not fresh anymore.bad_signature: signature is invalid and Swapscanner API was unable to recover signer address.bttf: acronym of “Back to the Future”. Happens when the issuedAt is greater than the current server timestamp.signature_expired: the request was generated too long ago.
403: Forbiddenbad_referrer: the referrer address is not authorized.invalid_signature: the referrer address does not match with the recovered one.
429: Too Many Requestsrate_limited: the request is rejected due to rate limiting.
503: Service Unavailablequote_under_maintenance: system is under the maintenance mode and will be back online shortly.
Response Body
{
// input contains the information about the input token
"input": {
// address of the input token
"address": "0x[INPUT_TOKEN_ADDRESS]",
// balance of the input token in the `from` account
"balance": "146362196",
// amount of the input token that the `from` account would like to provide
"amount": "10000000000"
},
// output contains the information about the output token
"output": {
// address of the output token
"address": "0x[OUTPUT_TOKEN_ADDRESS]",
// balance of the output token in the `to` account
"balance": "2592272957307052821882"
},
// quote contains the information about the swap
"quote": {
// priceImpact is the price impact of the swap
"priceImpact": 0.005615815216666306,
// output contains the information about the output token
"output": {
// recipient is the address that will receive the output token
"recipient": "0x[SWAP_RECIPIENT_ADDRESS]",
// estimatedAmountDeductingFee is the estimated amount of the output token that the `to` account will receive after deducting the fee
"estimatedAmountDeductingFee": "50020321161059352407537",
// minimumAmount is the guaranteed minimum amount of the output token that the `to` account will receive.
// This is approximately equal to deducting the slippage allowance from the `estimatedAmountDeductingFee`.
"minimumAmount": "49520117949448758883461"
},
// fees contains the information about the fees that the `from` account will be paying, or
// being deducted before and/or after the swap.
"fees": [
// Note that referrer desired to receive 0.10% of the input token as a fee, but the actual
// fee being taken here is 0.0999996% of the input token. This can happen due to precision loss.
{
"type": "referrer",
"fee": { "address": "0x[INPUT_TOKEN_ADDRESS]", "amount": "9999960" },
"recipient": "0x[REFERRER_FEE_TO_ADDRESS]"
},
// Swapscanner fee depends on our fee schedule.
{
"type": "swapscanner",
"fee": {
// address can be either SCNR or the output token
"address": "0x[SWAPSCANNER_FEE_TOKEN_ADDRESS]",
"amount": "9038554652517578627"
}
}
],
"routing": [
{
"path": [
{
"token": "0x22e3ac1e6595b64266e0b062e01fae31d9cdd578",
"subPaths": [{ "exchange": "KokonutSwap", "fraction": 0.0526315788 }]
},
{
"token": "0x4fa62f1f404188ce860c8f0041d6ac3765a72e67",
"subPaths": [{ "exchange": "KokonutSwap", "fraction": 0.0526315788 }]
},
{
"token": "0x[OUTPUT_TOKEN_ADDRESS]",
"subPaths": [{ "exchange": "KokonutSwap", "fraction": 0.0526315788 }]
}
]
},
{
"path": [
{
"token": "0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.8421052636 }]
},
{
"token": "0x[OUTPUT_TOKEN_ADDRESS]",
"subPaths": [
{ "exchange": "ClaimSwap", "fraction": 0.0526315788 },
{ "exchange": "KLAYswap", "fraction": 0.5263157892 },
{ "exchange": "KLAYswap", "fraction": 0.2631578956 }
]
}
]
},
{
"path": [
{
"token": "0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
},
{
"token": "0xba9725eaccf07044625f1d232ef682216f5371c2",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
},
{
"token": "0x[OUTPUT_TOKEN_ADDRESS]",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
}
]
},
{
"path": [
{
"token": "0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
},
{
"token": "0xba9725eaccf07044625f1d232ef682216f5371c2",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
},
{
"token": "0x34d21b1e550d73cee41151c77f3c73359527a396",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
},
{
"token": "0x[OUTPUT_TOKEN_ADDRESS]",
"subPaths": [{ "exchange": "KLAYswap", "fraction": 0.0526315788 }]
}
]
}
],
// errors contains the information about the errors that the Swapscanner encountered while
// computing the quote. Following errors must be addressed before the swap can be performed.
// Although you can still perform the swap without addressing the errors, the swap may revert.
"errors": [
// Some of the errors require manual intervention.
{ "message": "insufficient_input_token_balance" },
// Some of the errors can be resolved by performing a transaction. In this case, we add
// `tx` field to the error object.
{
"message": "insufficient_input_token_allowance",
"tx": {
"type": "approve",
"txs": {
"eth": {
"from": "0x[SWAP_INITIATOR_ADDRESS]",
"to": "0x[INPUT_TOKEN_ADDRESS]",
"data": "0x[DATA_TO_ALLOW_SWAPSCANNER_NAEP_TO_SPEND_UINT256_MAX_OF_INPUT_TOKEN]",
"value": "0x0",
"type": "0x2",
"maxPriorityFeePerGas": "0xba43b7400",
"maxFeePerGas": "0xba43b7400"
},
"klay": {
"from": "0x[SWAP_INITIATOR_ADDRESS]",
"to": "0x[INPUT_TOKEN_ADDRESS]",
"data": "0x[DATA_TO_ALLOW_SWAPSCANNER_NAEP_TO_SPEND_UINT256_MAX_OF_INPUT_TOKEN]",
"value": "0x0",
"type": "SMART_CONTRACT_EXECUTION",
"gasPrice": "0xba43b7400"
},
"klip": {
"bappName": "Swapscanner",
"from": "0x[SWAP_INITIATOR_ADDRESS]",
"to": "0x[INPUT_TOKEN_ADDRESS]",
"value": "0",
"abi": "{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}",
"params": "[\"0x[SWAPSCANNER_NAEP_ROUTER_ADDRESS]\",\"[UINT256_MAX]\"]"
}
}
}
}
],
// swapTx contains the information about the transaction that will perform the swap
"swapTx": {
"type": "swap",
"txs": {
// eth is the transaction data can be used with Metamask-like Ethereum standard wallets
"eth": {
"from": "0x[SWAP_INITIATOR_ADDRESS]",
"to": "0x[SWAPSCANNER_NAEP_ROUTER_ADDRESS]",
"data": "0x[DATA_TO_PERFORM_SWAP]",
"value": "0x[INPUT_AMOUNT_IF_INPUT_TOKEN_IS_NATIVE_TOKEN]",
"type": "0x2",
"maxPriorityFeePerGas": "0xba43b7400",
"maxFeePerGas": "0xba43b7400"
},
// klay is the transaction data can be used with Kaikas-like Kaia standard wallets
"klay": {
"from": "0x[SWAP_INITIATOR_ADDRESS]",
"to": "0x[SWAPSCANNER_NAEP_ROUTER_ADDRESS]",
"data": "0x[DATA_TO_PERFORM_SWAP]",
"value": "0x[INPUT_AMOUNT_IF_INPUT_TOKEN_IS_NATIVE_TOKEN]",
"type": "SMART_CONTRACT_EXECUTION",
"gasPrice": "0xba43b7400"
},
// klip is the transaction data can be used with Klip API
"klip": {
"bappName": "Swapscanner",
"from": "0x[SWAP_INITIATOR_ADDRESS]",
"to": "0x[SWAPSCANNER_NAEP_ROUTER_ADDRESS]",
"value": "[INPUT_AMOUNT_IF_INPUT_TOKEN_IS_NATIVE_TOKEN]",
"abi": "{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swap_3e3c58e6\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}",
"params": "[\"0x[DATA_TO_PERFORM_SWAP]\",\"0x[DATA_TO_PERFORM_SWAP]\"]"
}
}
}
}
}Errors
-
insufficient_input_token_allowance: thefromaccount has not approved the Swapscanner NAEP to spend the input token. Thetxfield will be present in the error object, which contains the transaction data that will approve the Swapscanner NAEP to spend the input token. -
insufficient_scnr_fee_allowance: thefromaccount has not approved the Swapscanner NAEP to spend the SCNR. Thetxfield will be present in the error object, which contains the transaction data that will approve the Swapscanner NAEP to spend the SCNR. This can only be present whenpayWithSCNRis set totrue. -
insufficient_input_token_balance: thefromaccount does not have sufficient balance of the input token. -
insufficient_scnr_balance: thefromaccount does not have sufficient balance of the SCNR. This can only be present whenpayWithSCNRis set totrue.
Swap Tx
Return Data
The swapTx will return following data to the caller:
returns (address outputToken, uint256 outputAmount)Which means outputAmount amount of outputToken has been transferred to the to address.
Event
Following event will be emitted when the swap is performed:
event Swap(
address indexed sender,
address recipient,
address indexed inputToken,
address indexed outputToken,
uint256 inputAmount,
uint256 outputAmount
);Which means sender has paid inputAmount amount of inputToken, and recipient received outputAmount amount of outputToken.
Fee
There could be two distinct fees that the from account will be paying. One is the Swapscanner fee
and the other is the referrer fee. Referrer is a caller of the quote API.
Swapscanner Fee
Swapscanner fee is the fee that the Swapscanner will be charging for providing the best quote. The fee is calculated based on our fee schedule.
There are two ways to pay the Swapscanner fee:
Pay with SCNR
If payWithSCNR is set to true, corresponding amount of SCNR (calculated based on realtime pricing data)
will be deducted from from account's balance.
Sufficient amount of SCNR must be present in the from account's balance, and the from account
must have approved the Swapscanner NAEP to spend the SCNR.
Discounts of 20% will be applied to the Swapscanner fee if payWithSCNR is set to true.
Pay with Token
If payWithSCNR is set to false, the Swapscanner fee will be automatically deducted from the output token amount.
Referrer Fee
Referrer fee is the fee that the referrer (caller of the quote API) can charge to the from account.
Referrer fee will be disabled if any of the following conditions are met:
referrerFeeTokenis set to0.referrerFeeis set to0.referrerFeeTois set to zero address.
Referrer Fee Token
Referrer can choose which token to receive as a fee. There are three options:
0: referrer fee is disabled.1: the input token amount (tokenIn) will be deducted before the swap and sent to the referrer as a fee.2: the output token amount (tokenOut) will be deducted after the swap and sent to the referrer as a fee.