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=true
onv1
. slippageNumerator
andslippageDenominator
now combined into a singleslippage
field. This is going to be same as fixingslippageDenominator
to10000
.- Referrer fee has been implemented. You can now set
referrerFeeToken
,referrerFee
, andreferrerFeeTo
fields to receive referrer fee. payWithSCNR
field has been added. With this, you can choose whether to make thefrom
to pay the Swapscanner fee with SCNR instead of the output token. 20% discount will be applied to the Swapscanner fee ifpayWithSCNR
is set totrue
.- Preconditions that were previously blocking the
swapTx
from being returned are now returned aserrors
field.swapTx
will 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.issuedAt
andsalt
will 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 thefrom
wallet would like to allow in BPS (basis points). (e.g. for slippage allowance of 1%, setslippage
to 100) -
from
- The address of the wallet (or contract) that would like to perform a swap. TokentokenInAddress
will be transferred from this address. -
to
- The address of the wallet (or contract) that would like to receive the swapped token. TokentokenOutAddress
will be transferred to this address. In most cases, this should be the same asfrom
address. -
tokenInAddress
- Address of the token that thefrom
wallet would like to provide. -
tokenOutAddress
- Address of the token that thefrom
wallet would like to receive. -
amount
- amount oftokenInAddress
that thefrom
wallet would like to provide. Must be numerated with the decimals of thetokenInAddress
. (e.g. 1 KLAY =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, setreferrerFee
to 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 makefrom
account 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 Klaytn 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
: thefrom
account has not approved the Swapscanner NAEP to spend the input token. Thetx
field 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
: thefrom
account has not approved the Swapscanner NAEP to spend the SCNR. Thetx
field 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 whenpayWithSCNR
is set totrue
. -
insufficient_input_token_balance
: thefrom
account does not have sufficient balance of the input token. -
insufficient_scnr_balance
: thefrom
account does not have sufficient balance of the SCNR. This can only be present whenpayWithSCNR
is 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:
referrerFeeToken
is set to0
.referrerFee
is set to0
.referrerFeeTo
is 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.