Simulate Swap
Simulates an arbitrary swap transaction via eth_call and returns the received output amount, gas usage and raw return data — without holding funds or sending anything on-chain.
Simulates any approval-based swap transaction — yours or another aggregator's — against live chain state and reports what it would actually return. Use it to re-validate quotes before execution, to compare aggregators on equal terms, or to debug reverting calldata.
No funds are needed: the simulation runs entirely inside an eth_call with state overrides. A
minimal proxy contract is placed at the from address, the input-token balance of from and its
allowance towards to are overridden to amountIn, and the proxy then calls to with the given
calldata — measuring the received output tokens, the gas the call consumed and its raw return data.
The block environment is realistic by default: tx.gasprice is the current network gas price,
block.coinbase is the latest block's validator and the gas limit is derived from the block gas
limit — so gas- and validator-dependent code paths behave as they would on-chain.
GET is also supported with the same fields as query parameters.
Parameters
chain_idreqintegerEVM-compatible chain ID (path parameter).
fromreqstringWallet address the transaction would be sent from. Output tokens are measured at this address. It does not need to hold any funds or approvals — both are provided via state overrides.
toreqstringContract address the transaction calls (typically an aggregator router). Must differ from
from.
datareqstringTransaction calldata as a 0x-prefixed hex string. Submit exactly what you would send on-chain.
tokenInreqstringContract address of the input token. Must be an ERC-20: the endpoint models the approval-based flow (wallet approves the router, router pulls the tokens), so native-token inputs are not supported.
amountInreqstringInput amount in the token's base units. The sender's balance and allowance are overridden to exactly this value. Decimal or 0x-hex.
tokenOutreqstringContract address of the output token to measure. Use
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for the chain's native token.
gasPricestringGas price in wei, reflected by tx.gasprice during the simulation; the sender is
automatically funded to cover it. Default: the current network gas price. Pass 0 to simulate
without a gas price.
gasstringGas limit for the simulation. Default: 50% of the current block gas limit.
blockstringBlock to simulate at: a block number (decimal or 0x-hex) or a tag such as latest or
pending. Default: latest.
spenderstringAddress the allowance override is granted to, when the router pulls tokens through a separate
contract (e.g. Permit2-style flows). Default: to.
coinbasestringAddress to use as block.coinbase during the simulation. Default: the validator of the most
recent block, so validator-dependent logic behaves as it would on-chain.
balanceSlotstringERC-20 base storage slot of the token's balance mapping. Resolved automatically for tokens known to the aggregator; required only for exotic tokens.
allowanceSlotstringERC-20 base storage slot of the token's allowance mapping. Resolved automatically for tokens known to the aggregator; required only for exotic tokens.
Request
curl 'https://api.nordstern.finance/simulate/8453' \
-H "Content-Type: application/json" \
-H "Referer: https://yourdomain.com" \
-d '{
"from": "0xYourWalletAddress",
"to": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d",
"data": "0x3f0bde25...",
"tokenIn": "0x4200000000000000000000000000000000000006",
"amountIn": "1000000000000000000",
"tokenOut": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
}'// Re-validate a quote: pass the quote's tx fields straight through.
const response = await fetch("https://api.nordstern.finance/simulate/8453", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Referer": "https://yourdomain.com",
},
body: JSON.stringify({
from: "0xYourWalletAddress",
to: quote.tx.to,
data: quote.tx.data,
tokenIn: "0x4200000000000000000000000000000000000006",
amountIn: "1000000000000000000",
tokenOut: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
}),
});
const result = await response.json();
console.log(result);import requests
url = "https://api.nordstern.finance/simulate/8453"
body = {
"from": "0xYourWalletAddress",
"to": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d",
"data": "0x3f0bde25...",
"tokenIn": "0x4200000000000000000000000000000000000006",
"amountIn": "1000000000000000000",
"tokenOut": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
}
headers = {"Referer": "https://yourdomain.com"}
response = requests.post(url, json=body, headers=headers)
print(response.json())Response
successbooleanWhether the simulated call succeeded. false means the transaction would revert on-chain; the
simulation itself still ran and returns 200.
amountOutstringAmount of tokenOut received by from, in base units. "0" when success is false.
gasUsedintegerGas consumed by the call to to. Excludes the 21,000 intrinsic transaction gas and calldata
gas, so it is directly comparable across quotes but slightly below the full on-chain total.
returnDatastringRaw return data of the call as 0x-prefixed hex. Carries the revert payload when success is
false.
revertReasonstringHuman-readable decoded revert reason. Only present when success is false.
blockstringThe block parameter the simulation ran at (echoes the request, default latest).
{
"success": true,
"amountOut": "2120362157",
"gasUsed": 431202,
"returnData": "0x000000000000000000000000000000000000000000000000000000007e63c92d",
"block": "latest"
}A reverting transaction still returns 200, with the decoded reason:
{
"success": false,
"amountOut": "0",
"gasUsed": 54210,
"returnData": "0x08c379a0...",
"revertReason": "Insufficient output",
"block": "latest"
}amountOut is measured as a real balance delta at from, so transfer taxes, rebases
and router fees are all reflected — it is the amount the wallet would actually receive.
Errors
| Code | Meaning |
|---|---|
400 | Missing or invalid parameter, native tokenIn, unknown storage slots for an untracked tokenIn (provide balanceSlot/allowanceSlot), or a simulation setup revert (e.g. tokenOut is not an ERC-20). The plain-text response body describes the issue. |
404 | Chain ID not supported. |
502 | The RPC node backing the simulation failed. Safe to retry. |
See Errors for the full error format.