curl --request GET \
--url https://api.akka.finance/partner/v1/{chainId}/quote \
--header 'apikey: <api-key>'const options = {method: 'GET', headers: {apikey: '<api-key>'}};
fetch('https://api.akka.finance/partner/v1/{chainId}/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.akka.finance/partner/v1/{chainId}/quote"
headers = {"apikey": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"dstAmount": "12723902882990271",
"tx": {
"to": "<string>",
"data": "<string>",
"value": "<string>",
"gasPrice": "<string>",
"gas": "<string>",
"from": "<string>",
"type": "legacy",
"maxFeePerGas": "<string>",
"maxPriorityFeePerGas": "<string>"
},
"encodedTx": "<string>",
"chainId": 123,
"sellToken": "<string>",
"buyToken": "<string>",
"sellAmount": "<string>",
"buyAmount": "<string>",
"payer": "<string>",
"recipient": "<string>",
"issues": [
{
"code": "INSUFFICIENT_BALANCE",
"message": "<string>",
"actual": "<string>",
"expected": "<string>",
"token": "<string>",
"spender": "<string>"
}
],
"validation": {
"balance": {
"status": "VALID",
"actual": "<string>",
"expected": "<string>",
"reason": "<string>"
},
"allowance": {
"status": "VALID",
"actual": "<string>",
"expected": "<string>",
"reason": "<string>"
},
"gas": {
"status": "VALID",
"actual": "<string>",
"expected": "<string>",
"reason": "<string>"
}
},
"simulation": {
"status": "SUCCESS",
"method": "estimateGas",
"gas": "420000",
"gasLimit": "420000",
"gasUsedMethod": "limit",
"blockNumber": "<string>",
"estimatedGasUsed": "350000",
"stateOverrides": [
"balance"
]
},
"validForSeconds": 123,
"validitySource": "ADVISORY",
"partnerId": "<string>",
"srcToken": {
"address": "<string>",
"symbol": "<string>",
"name": "<string>",
"decimals": 123,
"logoUri": {}
},
"dstToken": {
"address": "<string>",
"symbol": "<string>",
"name": "<string>",
"decimals": 123,
"logoUri": {}
},
"quoteId": "<string>",
"blockNumber": "<string>",
"generatedAt": "<string>",
"expiresAt": "<string>",
"minAmountOut": "<string>",
"allowanceTarget": {},
"simulationIncomplete": true,
"simulationStatus": "SUCCESS",
"simulationStateOverrides": [
"balance"
],
"gas": "420000",
"estimatedGasUsed": "350000",
"quotedAtBlock": "<string>",
"routes": [
{
"percent": 123,
"pools": [
{
"address": "<string>",
"fee": 123,
"exchange": "<string>",
"poolType": "<string>"
}
],
"path": [
{
"address": "<string>",
"decimals": 123,
"symbol": "<string>"
}
]
}
],
"graph": [
{
"from": "<string>",
"to": "<string>",
"pool": "<string>",
"exchange": "<string>",
"poolType": "<string>",
"percentage": 700000
}
],
"compare": {}
}Partner Executable Quote
Returns calldata, approval target, minimum output, lifecycle metadata, and structured payer issues in one response.
curl --request GET \
--url https://api.akka.finance/partner/v1/{chainId}/quote \
--header 'apikey: <api-key>'const options = {method: 'GET', headers: {apikey: '<api-key>'}};
fetch('https://api.akka.finance/partner/v1/{chainId}/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.akka.finance/partner/v1/{chainId}/quote"
headers = {"apikey": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"dstAmount": "12723902882990271",
"tx": {
"to": "<string>",
"data": "<string>",
"value": "<string>",
"gasPrice": "<string>",
"gas": "<string>",
"from": "<string>",
"type": "legacy",
"maxFeePerGas": "<string>",
"maxPriorityFeePerGas": "<string>"
},
"encodedTx": "<string>",
"chainId": 123,
"sellToken": "<string>",
"buyToken": "<string>",
"sellAmount": "<string>",
"buyAmount": "<string>",
"payer": "<string>",
"recipient": "<string>",
"issues": [
{
"code": "INSUFFICIENT_BALANCE",
"message": "<string>",
"actual": "<string>",
"expected": "<string>",
"token": "<string>",
"spender": "<string>"
}
],
"validation": {
"balance": {
"status": "VALID",
"actual": "<string>",
"expected": "<string>",
"reason": "<string>"
},
"allowance": {
"status": "VALID",
"actual": "<string>",
"expected": "<string>",
"reason": "<string>"
},
"gas": {
"status": "VALID",
"actual": "<string>",
"expected": "<string>",
"reason": "<string>"
}
},
"simulation": {
"status": "SUCCESS",
"method": "estimateGas",
"gas": "420000",
"gasLimit": "420000",
"gasUsedMethod": "limit",
"blockNumber": "<string>",
"estimatedGasUsed": "350000",
"stateOverrides": [
"balance"
]
},
"validForSeconds": 123,
"validitySource": "ADVISORY",
"partnerId": "<string>",
"srcToken": {
"address": "<string>",
"symbol": "<string>",
"name": "<string>",
"decimals": 123,
"logoUri": {}
},
"dstToken": {
"address": "<string>",
"symbol": "<string>",
"name": "<string>",
"decimals": 123,
"logoUri": {}
},
"quoteId": "<string>",
"blockNumber": "<string>",
"generatedAt": "<string>",
"expiresAt": "<string>",
"minAmountOut": "<string>",
"allowanceTarget": {},
"simulationIncomplete": true,
"simulationStatus": "SUCCESS",
"simulationStateOverrides": [
"balance"
],
"gas": "420000",
"estimatedGasUsed": "350000",
"quotedAtBlock": "<string>",
"routes": [
{
"percent": 123,
"pools": [
{
"address": "<string>",
"fee": 123,
"exchange": "<string>",
"poolType": "<string>"
}
],
"path": [
{
"address": "<string>",
"decimals": 123,
"symbol": "<string>"
}
]
}
],
"graph": [
{
"from": "<string>",
"to": "<string>",
"pool": "<string>",
"exchange": "<string>",
"poolType": "<string>",
"percentage": 700000
}
],
"compare": {}
}payer supplies the input and sends the returned transaction. recipient receives the output and defaults to payer.
A successful response can contain balance, allowance, or native gas entries in issues. Resolve them before broadcasting. A validation status of UNKNOWN means AKKA could not complete that RPC check; validate it independently.
Use simulation.status, not HTTP status alone, to decide whether your own simulation is required. A payer that does not yet hold the sell amount or the router approval is still simulated: the estimate grants exactly what is missing through eth_estimateGas state overrides and lists it in simulation.stateOverrides (balance, allowance), while issues keeps reporting the shortfall. For native-ETH output to a contract recipient whose direct estimate reverts at the ETH transfer, the estimate runs with the recipient treated as a plain account and simulation.stateOverrides lists recipientCode: that gas leaves out the recipient’s receive(), and the transaction succeeds only if the recipient accepts the ETH when it executes. simulation.gasLimit is the transaction gas limit to send: on SUCCESS it is the estimate +20%; on INCOMPLETE and SKIPPED_METRIC_STATE it is a static route plan, so never send less and simulate independently on INCOMPLETE. By default simulation.gas, tx.gas and the root gas are that same limit (simulation.gasUsedMethod is limit). simulation.estimatedGasUsed is the expected consumption to use for cost display. The payer gas checks (validation.gas, INSUFFICIENT_GAS_BALANCE, and the native-input balance) budget simulation.gasLimit, and encodedTx carries it. Refresh after expiresAt, any approval transaction, user delay, failed simulation, or nonce replacement. Executable calldata is single-use and must not be cached or retried after broadcast.
Inspect tx.type: send only gasPrice for legacy, or only maxFeePerGas and maxPriorityFeePerGas for eip1559. Preserve tx.to, tx.data, and tx.value exactly.
Set includeRoutes=true for the parallel route list, includeGraph=true for the flat on-chain hop list, or includeCompare=true for same-moment single-pool comparison quotes. All three views come from the same pathfinder invocation that produced dstAmount and tx.data — one call, one number, one route. includeTokensInfo and includeGas default to true on this endpoint. gasPrice and gasLimit override the RPC lookups. A gasLimit becomes the limit (on a route with a wallet-unsafe leg, such as a Metric leg whose price feed is not proven live, the limit is never below the route floor) and skips the RPC estimate, so simulation.status is INCOMPLETE (SKIPPED_METRIC_STATE with a wallet-unsafe leg). There is no exactQuote parameter: an executable quote is always exact.
Set excludeWalletUnsafe=true when the transaction must pass a wallet pre-signature simulation on a public RPC as it is. The route then leaves out every leg that fails such a simulation: the Metric pools whose price feed is not proven live, titan_propamm (the maker writes its price in the block of the trade) and uni_v4_angstrom (it is never served without the wrapper). A Metric pool with a live feed stays in the route. The quote never uses the atomic fallback wrapper, so tx.data is the plain route. excludeWalletUnsafe=false gives the default route. Without the parameter, the setting of your key applies (off unless AKKA set it on).
gas, tx.gas, simulation.gas and
estimatedGasUsed carry the expected receipt gas: what receipt.gasUsed
shows, after the gas refund and with no buffer, for cost display and route
ranking. It is not a gas limit: a transaction sent with it runs out of gas.
Only simulation.gasLimit is the limit to send. simulation.gasUsedMethod
says how the expected value was made:simulateV1: aneth_simulateV1of the exact transaction (the payer state overrides of the estimate), accepted when the call succeeds and uses more than 21,000 gas and at most the raw estimate. It is the receipt gas at the state of the quote block. Replays of real swaps at their parent block matched the receipt within 0.01% on 34 of 40 Ethereum swaps and exactly on 14 of 18 HyperEVM swaps, and came out +0.004% to +1.8% on Arbitrum and up to +532 gas on Robinhood (the L1 part included). Pool state that changes before your transaction lands moves the receipt either way: the Ethereum replays moved by -3.8% to +10.7% where earlier transactions of the same block touched the pools.refundRatio: the raweth_estimateGastimes the chain’s receipt/estimate ratio (0.87 on Ethereum; 0.84 on Arbitrum and HyperEVM; 0.855 on Robinhood; 0.80 on XDC), when no simulation is available. Each ratio is set above the highest one observed on the chain, so this value errs high (typically 5–10% over the receipt). The estimate is the gas before the refund, 1.15–1.30x the receipt.estimate: the raweth_estimateGasresult, on a chain without a measured ratio.routeModel: the gas model of the primary route, when no estimate ran.limit: no expected value exists; the limit stands in.
gas was
made and never changes what gas means for your key. Sending
simulation.gasLimit as the gas limit is correct in both modes.Authorizations
Query Parameters
Gas limit for the transaction. Any value skips the RPC estimate, so simulation.status is INCOMPLETE (SKIPPED_METRIC_STATE on a route with a Metric leg) and simulation.method is routeGasFloor. It becomes simulation.gasLimit (and by default gas, tx.gas and simulation.gas), except on a route with a Metric leg, where the limit is never below the route floor. With expected-gas reporting gas, tx.gas and simulation.gas stay the expected consumption: the gas model of the primary route, not an RPC estimate.
Leave out of the route every leg that fails a wallet pre-signature simulation on a public RPC, with no fallback wrapper: the Metric pools whose price feed is not proven live (a Metric pool with a live feed stays), titan_propamm and uni_v4_angstrom. false keeps the default route. Absent: the setting of the partner key (off unless AKKA set it on).
Response
Payer state a SUCCESS estimate assumed through eth_estimateGas state overrides (missing sell-token balance and/or router allowance; also held state whose quote-time read did not answer in time). recipientCode (/partner/v1 only): native output to a contract recipient; the estimate ran with the recipient's code removed. Omitted when the estimate ran on the real state.
balance, allowance, recipientCode Expected gas consumption (decimal-string uint256), the same value as simulation.estimatedGasUsed. Not a limit, and independent of a caller-supplied gasLimit. By default it is the /swap/v1 value. With expected-gas reporting it also equals simulation.gas, tx.gas and the root gas: the expected receipt gas (after the refund), so it can be below the /swap/v1 estimatedGasUsed of the same route (the raw estimate, or the route plan without an estimate).
"350000"
