# Introduction (/introduction) Nordstern queries all available liquidity sources, simulates execution paths, and returns ready-to-use calldata you can submit directly to the Nordstern Guard Contract with no additional processing required. EVM-compatible L1s and L2s across the ecosystem. Response includes tx data for immediate on-chain execution. No API key, no subscription, and no per-swap protocol fee. The Nordstern API is REST-based. No SDK, no API key, no registration, and no fixed rate limits. A GET request returns everything needed to execute a swap: the optimal split-route, gas estimate, and a ready-to-submit transaction object. Nordstern handles the complexity of querying hundreds of liquidity sources, simulating paths, and encoding calldata so you don't have to. It is designed for developers building wallets, trading interfaces, DeFi protocols, arbitrage bots, and any application that needs reliable, low-latency token swap execution across EVM networks. * New to Nordstern? Read [How It Works](/how-it-works) for a conceptual overview, then follow the [Quick Start](/quick-start) to make your first API call. * Ready to integrate? Go straight to the [API Reference](/overview). * Running a DEX, AMM, or PMM and want to be a liquidity source? See [Integrations](/integrations). * Questions? Join us on [Telegram](https://t.me/nordstern_fi). # Quick Start (/quick-start) This example swaps 1 ETH for USDC on Base. Replace the addresses and chain ID for any other token pair on any [supported chain](/supported-chains). ## Step 1 · Request a route [#step-1--request-a-route] ```bash # Swap 1 WETH → USDC on Base (chain 8453) # To swap native ETH directly, use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE as src curl 'https://api.nordstern.finance/aggregator/8453?src=0x4200000000000000000000000000000000000006&dst=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&amount=1000000000000000000&from=0xYourWalletAddress&slippage=0.5' \ -H "Referer: https://yourdomain.com" ``` ```js // Swap 1 WETH → USDC on Base (chain 8453) // To swap native ETH directly, use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE as src const params = new URLSearchParams({ src: "0x4200000000000000000000000000000000000006", // WETH (or 0xEeee... for native ETH) dst: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC amount: "1000000000000000000", // 1 ETH in wei from: "0xYourWalletAddress", slippage: "0.5", }); const response = await fetch( `https://api.nordstern.finance/aggregator/8453?${params}`, { headers: { "Referer": "https://yourdomain.com" } } ); const route = await response.json(); ``` ```python import requests # Swap 1 WETH → USDC on Base (chain 8453) # To swap native ETH directly, use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE as src url = "https://api.nordstern.finance/aggregator/8453" params = { "src": "0x4200000000000000000000000000000000000006", # WETH (or 0xEeee... for native ETH) "dst": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", # USDC "amount": "1000000000000000000", # 1 ETH in wei "from": "0xYourWalletAddress", "slippage": 0.5, } route = requests.get(url, params=params, headers={"Referer": "https://yourdomain.com"}).json() ``` ## Step 2 · Read the response [#step-2--read-the-response] The response contains the optimal route and a fully encoded `tx` object ready to pass to your wallet or provider. Before proceeding, verify that `tx` is present and `toAmount` is non-zero. If either check fails, no valid route is available. ```json { "src": "0x4200000000000000000000000000000000000006", "dst": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "fromAmount": "1000000000000000000", "toAmount": "2120362157", "gasEstimate": "1045694", "tx": { "from": "0xYourWalletAddress", "to": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d", "data": "0x3f0bde25...", "value": "0" } } ``` ## Step 3 · Approve and execute [#step-3--approve-and-execute] Before the first swap of an ERC-20 token, approve the Guard Contract (`tx.to`) to spend your input token. Once granted, you don't need to repeat it for the same token. Native token swaps (`0xEeee...EEeE`) skip this step — the value is passed via `tx.value`. Then submit `tx` directly. ```js import { createPublicClient, createWalletClient, http, parseAbi, maxUint256 } from "viem"; import { base } from "viem/chains"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount("0xYourPrivateKey"); const transport = http("https://your-rpc-url"); const publicClient = createPublicClient({ chain: base, transport }); const walletClient = createWalletClient({ account, chain: base, transport }); // Guard: no valid route if (!route.tx || route.toAmount === "0") { throw new Error("No valid route available"); } const NATIVE = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; const isNative = route.src.toLowerCase() === NATIVE.toLowerCase(); // Native input: value is set on tx, no ERC-20 approval needed if (!isNative) { const ERC20_ABI = parseAbi([ "function allowance(address,address) view returns (uint256)", "function approve(address,uint256) returns (bool)", ]); // 1. Check allowance on the input token const allowance = await publicClient.readContract({ address: route.src, abi: ERC20_ABI, functionName: "allowance", args: [account.address, route.tx.to], }); // 2. Approve the router if needed (max approval to avoid repeating) if (allowance < BigInt(route.fromAmount)) { await walletClient.writeContract({ address: route.src, abi: ERC20_ABI, functionName: "approve", args: [route.tx.to, maxUint256], }); } } // 3. Submit the swap const hash = await walletClient.sendTransaction({ to: route.tx.to, data: route.tx.data, value: BigInt(route.tx.value), }); ``` ```js import { ethers } from "ethers"; const provider = new ethers.JsonRpcProvider("https://your-rpc-url"); const wallet = new ethers.Wallet("0xYourPrivateKey", provider); // Guard: no valid route if (!route.tx || route.toAmount === "0") { throw new Error("No valid route available"); } const NATIVE = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; const isNative = route.src.toLowerCase() === NATIVE.toLowerCase(); // Native input: value is set on tx, no ERC-20 approval needed if (!isNative) { const ERC20_ABI = [ "function allowance(address owner, address spender) view returns (uint256)", "function approve(address spender, uint256 amount) returns (bool)", ]; const token = new ethers.Contract(route.src, ERC20_ABI, wallet); // 1. Check allowance on the input token const allowance = await token.allowance(wallet.address, route.tx.to); // 2. Approve the router if needed (max approval to avoid repeating) if (allowance < BigInt(route.fromAmount)) { await token.approve(route.tx.to, ethers.MaxUint256); } } // 3. Submit the swap const tx = await wallet.sendTransaction({ to: route.tx.to, data: route.tx.data, value: BigInt(route.tx.value), }); ``` ```python from web3 import Web3 w3 = Web3(Web3.HTTPProvider("https://your-rpc-url")) account = w3.eth.account.from_key("0xYourPrivateKey") # Guard: no valid route if "tx" not in route or route["toAmount"] == "0": raise ValueError("No valid route available") NATIVE = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" is_native = route["src"].lower() == NATIVE.lower() # Native input: value is set on tx, no ERC-20 approval needed if not is_native: ERC20_ABI = [ {"name": "allowance", "type": "function", "stateMutability": "view", "inputs": [{"name": "owner", "type": "address"}, {"name": "spender", "type": "address"}], "outputs": [{"name": "", "type": "uint256"}]}, {"name": "approve", "type": "function", "stateMutability": "nonpayable", "inputs": [{"name": "spender", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [{"name": "", "type": "bool"}]}, ] src_token = w3.eth.contract(address=route["src"], abi=ERC20_ABI) router_address = route["tx"]["to"] from_amount = int(route["fromAmount"]) # 1. Check allowance on the input token allowance = src_token.functions.allowance(account.address, router_address).call() # 2. Approve the router if needed (max approval to avoid repeating) if allowance < from_amount: approve_tx = src_token.functions.approve(router_address, 2**256 - 1).build_transaction({ "from": account.address, "nonce": w3.eth.get_transaction_count(account.address), }) signed = account.sign_transaction(approve_tx) w3.eth.send_raw_transaction(signed.raw_transaction) # 3. Submit the swap swap_tx = { "from": account.address, "to": route["tx"]["to"], "data": route["tx"]["data"], "value": int(route["tx"]["value"]), "nonce": w3.eth.get_transaction_count(account.address), "gas": int(int(route["gasEstimate"]) * 1.2), # add 20% buffer } signed_swap = account.sign_transaction(swap_tx) tx_hash = w3.eth.send_raw_transaction(signed_swap.raw_transaction) ``` * [Get Swap Route](/swap-route) — full parameter reference and response schema. * [Get Token Price](/token-price) — fetch USD prices for multiple tokens in one call. * [Get Token Liquidity](/token-liquidity) — check on-chain depth before routing large swaps. * [Errors](/errors) — how the API signals bad requests and missing routes. * [Supported Chains](/chains) — chain IDs and Guard Contract addresses. # How It Works (/how-it-works) ## Integration flow [#integration-flow] ### Request a route [#request-a-route] Call the aggregator endpoint with your input token, output token, amount, and chain ID. Nordstern queries all available liquidity sources across the chain and simulates every viable execution path. ### Receive ready-to-submit calldata [#receive-ready-to-submit-calldata] The response includes a `tx` object (`to`, `data`, `value`, and `from`) that can be submitted directly on-chain. No manual encoding, no additional calls, no SDK required. ### Approve and execute [#approve-and-execute] Before the first swap, approve the Guard Contract to spend your input token. This is a standard ERC-20 approval and only needs to happen once per token. Then submit the transaction. ## How routing works [#how-routing-works] Steps 01–03 describe the integration flow from your application's perspective. Under the hood, step 01 triggers a four-stage pipeline that runs before the response is returned. Understanding it helps explain why Nordstern consistently finds better routes than querying a single DEX directly. Every request queries all integrated DEXs, AMMs, and liquidity pools at once, not sequentially. This gives Nordstern a complete view of available liquidity in a single pass, which is what makes sub-50ms quotes possible. The selected route is simulated against current on-chain state before it is considered. Paths that would fail on-chain (due to liquidity constraints, token quirks, or stale pool state) are filtered out before any route reaches you. When a single pool cannot fill the swap efficiently, Nordstern splits the order across multiple pools and routes simultaneously. Each leg is sized to minimise combined price impact. A route that adds an extra hop to save 0.1% on output but costs more in gas than it saves is not a better route. Nordstern factors gas cost into route scoring, so the returned route maximises net value to the user, not just gross output. # Why Nordstern (/why-nordstern) ## Key features [#key-features] Our system calculates millions of swap paths and returns the best route in under 50ms. Fast enough for MEV bots, solvers, and any UX where latency matters. We support new tokens immediately after launch and integrate new chains on day one. Your users never hit a dead end because a token or chain isn't listed yet. Every route we return is fully simulated before it reaches you. You only receive paths that are actually executable, resulting in fewer failed transactions, fewer refunds, and happier users. Rebasing, taxed, and fee-on-transfer tokens are fully supported. Where other aggregators fail silently or skip these tokens entirely, Nordstern routes them correctly. Nordstern charges no protocol fee per swap. Apply your own custom fee structure via the `convenienceFee` parameter, or pass through zero fees to your users. No API key, no quota, no throttling for normal usage. Build high-frequency applications without worrying about hitting a ceiling. Only automated spam is blocked. ## At a glance [#at-a-glance] Compared to integrating a DEX directly, Nordstern handles routing, simulation, and calldata encoding for you, with no API key, no subscription, and no rate limits standing between you and production traffic. | Feature | Direct DEX | Nordstern | | ----------------------- | ---------- | -------------- | | DEX / liquidity sources | One | 100+ per chain | | Route simulation | — | ✓ | | Split routing | — | ✓ | | Non-standard tokens | Manual | ✓ | | API key required | Varies | No | | Fee on swap | DEX native | 0% | | Custom fee passthrough | — | ✓ | | Quote latency | Varies | \<50ms | | Rate limits | Varies | None | # Supported Chains (/supported-chains) Pass the chain ID as the path parameter in any endpoint call. This list is fetched live from the API. | Chain | Chain ID | | --- | --- | | Ancient8 | 888888888 | | ApeChain | 33139 | | AppChain | 466 | | Arbitrum | 42161 | | Arbitrum Nova | 42170 | | Avalanche | 43114 | | B2 | 223 | | B3 | 8333 | | Base | 8453 | | Beam | 4337 | | Bera | 80094 | | Bitgert | 32520 | | BitLayer | 200901 | | BitTorrent | 199 | | Blast | 81457 | | BOB | 60808 | | Boba | 288 | | BSC | 56 | | Celo | 42220 | | Chiliz Chain | 88888 | | Core | 1116 | | Corn | 21000000 | | Cyber | 7560 | | Duck Chain | 5545 | | Electroneum | 52014 | | Elysium | 1339 | | Ethereum | 1 | | Flare | 14 | | Flow EVM | 747 | | Fraxtal | 252 | | Funki | 33979 | | Genesys | 16507 | | Gensyn | 685689 | | Gnosis | 100 | | Goat | 2345 | | Gravity | 1625 | | HashKey | 177 | | Hemi | 43111 | | HyperEVM | 999 | | Immutable zkEVM | 13371 | | Ink | 57073 | | Kaia | 8217 | | Katana | 747474 | | KCC | 321 | | Kroma | 255 | | KUB | 96 | | Linea | 59144 | | Lisk | 1135 | | Manta Pacific | 169 | | Mantle | 5000 | | MAP Protocol | 22776 | | Metis | 1088 | | Mint | 185 | | Mode | 34443 | | Monad | 143 | | Morph L2 | 2818 | | Muster | 4078 | | opBNB | 204 | | Optimism | 10 | | Parex | 322202 | | Plasma | 9745 | | PlatON | 210425 | | Polygon | 137 | | Q Network | 35441 | | Qitmeer | 813 | | Rari | 1380012617 | | Redstone | 690 | | Reya | 1729 | | Robinhood | 4663 | | Ronin | 2020 | | Rootstock | 30 | | RSS3 VSL | 12553 | | Sanko | 1996 | | Scroll | 534352 | | SEI V2 | 1329 | | Shape | 360 | | Shibarium | 109 | | Soneium | 1868 | | Songbird | 19 | | Sonic | 146 | | Step | 1234 | | Story | 1514 | | Superposition | 55244 | | Superseed | 5330 | | Swell Chain | 1923 | | Taiko | 167000 | | Telos | 40 | | ThunderCore | 108 | | Ultron | 1231 | | Unichain | 130 | | Vana | 1480 | | WanChain | 888 | | WEMIX | 1111 | | World Chain | 480 | | XDC | 50 | | ZeroG | 16661 | | Zircuit | 48900 | | Zora | 7777777 | Don't see your chain? Reach out on Telegram and we'll prioritize adding support for your project. # Overview (/overview) There is no SDK required. Responses include everything needed to execute a swap directly on-chain. ## Base URL [#base-url] ``` https://api.nordstern.finance/ ``` ## Endpoints [#endpoints] Returns the optimal split-route and ready-to-submit calldata for a token swap. Simulates an arbitrary swap transaction and returns the received output amount, gas usage and return data. Returns current USD prices for one or more tokens. Returns on-chain liquidity depth in USD for one or more tokens. Returns the full list of supported chains with chain IDs and router addresses. # Get Swap Route (/swap-route) The core endpoint. Returns the optimal split-route across all available liquidity sources for the given chain. Routes are simulation-verified and the response includes ready-to-use calldata for direct on-chain execution via the Nordstern Guard Contract. ## Parameters [#parameters] EVM-compatible chain ID (path parameter). Contract address of the input token. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the chain's native token (ETH, MATIC, BNB, etc.). Contract address of the output token. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` to receive the chain's native token. Amount of the input token in its base units (e.g. `1000000000000000000` for 1 ETH, `1000000` for 1 USDC). Use string format to safely handle uint256 values. Wallet address that will receive the output tokens. Slippage tolerance in percent. Default: 0.5. Convenience fee in percent to be added. Default: 0. Address to receive the convenience fee. ## Request [#request] ```bash curl 'https://api.nordstern.finance/aggregator/8453?src=0x4200000000000000000000000000000000000006&dst=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&amount=1000000000000000000&from=0xYourWalletAddress&slippage=0.5' \ -H "Referer: https://yourdomain.com" ``` ```js const params = new URLSearchParams({ src: "0x4200000000000000000000000000000000000006", dst: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", amount: "1000000000000000000", from: "0xYourWalletAddress", slippage: "0.5", }); const response = await fetch( `https://api.nordstern.finance/aggregator/8453?${params}`, { headers: { "Referer": "https://yourdomain.com" } } ); const route = await response.json(); console.log(route); ``` ```python import requests url = "https://api.nordstern.finance/aggregator/8453" params = { "src": "0x4200000000000000000000000000000000000006", "dst": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "amount": "1000000000000000000", "from": "0xYourWalletAddress", "slippage": 0.5, } headers = {"Referer": "https://yourdomain.com"} response = requests.get(url, params=params, headers=headers) print(response.json()) ``` ## Response [#response] Source token address (echoes request param). Destination token address (echoes request param). Input amount in the token's base units. Matches the request amount. `"0"` means no route was found. Estimated gas units the transaction will consume. Add a 20% buffer when using this as a gas limit. Do not pass it directly. Block number at which the route was simulated. Revalidate if more than 1–2 blocks have elapsed before submission. Array of internal swap legs. Ready-to-submit EVM transaction. Pass this directly to your wallet or provider. ### The `tx` object [#the-tx-object] Sender wallet address (echoes request `from` param). Guard Contract address for this chain. Encoded transaction calldata. Submit as-is. Do not modify. `"0"` for ERC-20 inputs. Non-zero when `src` is `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`. Pass it directly when submitting the transaction. ```json { "src": "0x4200000000000000000000000000000000000006", "dst": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "fromAmount": "1000000000000000000", "toAmount": "2120362157", "gasEstimate": "1045694", "simulationBlock": 46334743, "swaps": ..., "tx": { "from": "0xYourWalletAddress", "to": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d", "data": "0x3f0bde25...", "value": "0" } } ``` ## Before submitting [#before-submitting] The API always returns `200`. `toAmount` must be non-zero and `route.tx` must exist. Otherwise the route was not found or simulation failed. ```js if (!route.tx || route.toAmount === "0") { throw new Error("No valid route available"); } ``` Before submitting the transaction, approve the Guard Contract (tx.to) to spend your input token. Call approve(routerAddress, amount) on the ERC-20 contract. If the allowance is already sufficient, skip this step. ## Errors [#errors] | Code | Meaning | | ----- | ------------------------------------------------------------------------------- | | `400` | Missing or invalid parameter. The plain-text response body describes the issue. | | `404` | Chain ID not supported. | See [Errors](/errors) for the full error format. # Simulate Swap (/swap-simulation) 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 [#parameters] EVM-compatible chain ID (path parameter). Wallet 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. Contract address the transaction calls (typically an aggregator router). Must differ from `from`. Transaction calldata as a 0x-prefixed hex string. Submit exactly what you would send on-chain. Contract 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. Input amount in the token's base units. The sender's balance and allowance are overridden to exactly this value. Decimal or 0x-hex. Contract address of the output token to measure. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the chain's native token. Gas 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. Gas limit for the simulation. Default: 50% of the current block gas limit. Block to simulate at: a block number (decimal or 0x-hex) or a tag such as `latest` or `pending`. Default: `latest`. Address the allowance override is granted to, when the router pulls tokens through a separate contract (e.g. Permit2-style flows). Default: `to`. Address 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. ERC-20 base storage slot of the token's balance mapping. Resolved automatically for tokens known to the aggregator; required only for exotic tokens. ERC-20 base storage slot of the token's allowance mapping. Resolved automatically for tokens known to the aggregator; required only for exotic tokens. ## Request [#request] ```bash 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" }' ``` ```js // 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); ``` ```python 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 [#response] Whether the simulated call succeeded. `false` means the transaction would revert on-chain; the simulation itself still ran and returns `200`. Amount of `tokenOut` received by `from`, in base units. `"0"` when `success` is `false`. Gas 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. Raw return data of the call as 0x-prefixed hex. Carries the revert payload when `success` is `false`. Human-readable decoded revert reason. Only present when `success` is `false`. The block parameter the simulation ran at (echoes the request, default `latest`). ```json { "success": true, "amountOut": "2120362157", "gasUsed": 431202, "returnData": "0x000000000000000000000000000000000000000000000000000000007e63c92d", "block": "latest" } ``` A reverting transaction still returns `200`, with the decoded reason: ```json { "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 [#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](/errors) for the full error format. # Get Token Price (/token-price) Returns current USD prices for one or more tokens on any supported chain. Request multiple tokens in a single call by separating addresses with commas. ## Parameters [#parameters] EVM-compatible chain ID (path parameter). Token contract address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the native token. Separate multiple addresses with commas. ## Request [#request] ```bash curl 'https://api.nordstern.finance/prices/8453?token=0x4200000000000000000000000000000000000006,0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' \ -H "Referer: https://yourdomain.com" ``` ```js const tokens = [ "0x4200000000000000000000000000000000000006", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", ]; const response = await fetch( `https://api.nordstern.finance/prices/8453?token=${tokens.join(",")}`, { headers: { "Referer": "https://yourdomain.com" } } ); const prices = await response.json(); console.log(prices); ``` ```python import requests url = "https://api.nordstern.finance/prices/8453" params = { "token": ",".join([ "0x4200000000000000000000000000000000000006", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", ]) } headers = {"Referer": "https://yourdomain.com"} response = requests.get(url, params=params, headers=headers) print(response.json()) ``` ## Response [#response] A flat JSON object keyed by token address. Each value is a `number` representing the current USD price. Unrecognised addresses return `null` rather than an error. Always check for null before using a price in calculations. USD price of the token. `null` if the token is not recognised on this chain. ```json { "0x4200000000000000000000000000000000000006": 4511.529379233013, "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": 1.0 } ``` Prices reflect on-chain liquidity at request time. A 5–15 second client-side cache is safe for most UIs and cuts request volume toward any [abuse thresholds](/rate-limits). ## Errors [#errors] | Code | Meaning | | ----- | -------------------------------------------------------------------------------------------------------- | | `400` | Missing token parameter, or chain\_id is not a number. The plain-text response body describes the issue. | | `404` | Chain ID not supported. | # Get Token Liquidity (/token-liquidity) Returns on-chain liquidity depth in USD for one or more tokens. Use this to assess whether a given position size is practical before routing a swap. ## Parameters [#parameters] EVM-compatible chain ID (path parameter). Token contract address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the native token. Separate multiple addresses with commas. ## Request [#request] ```bash curl 'https://api.nordstern.finance/liquidity/8453?token=0x4200000000000000000000000000000000000006,0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' \ -H "Referer: https://yourdomain.com" ``` ```js const tokens = [ "0x4200000000000000000000000000000000000006", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", ]; const response = await fetch( `https://api.nordstern.finance/liquidity/8453?token=${tokens.join(",")}`, { headers: { "Referer": "https://yourdomain.com" } } ); const liquidity = await response.json(); console.log(liquidity); ``` ```python import requests url = "https://api.nordstern.finance/liquidity/8453" params = { "token": ",".join([ "0x4200000000000000000000000000000000000006", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", ]) } headers = {"Referer": "https://yourdomain.com"} response = requests.get(url, params=params, headers=headers) print(response.json()) ``` ## Response [#response] A flat JSON object keyed by token address. Each value is a `number` representing total on-chain liquidity depth in USD across all DEX pools on the requested chain. A higher value means larger swaps can be executed with less price impact. Total on-chain liquidity in USD. `null` if the token is not recognised on this chain. ```json { "0x4200000000000000000000000000000000000006": 1000000000, "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": 41055139.11223521 } ``` Use liquidity depth as a pre-flight check before requesting a swap route. If the liquidity for a token is significantly lower than your intended swap size, expect high price impact or the quote failing. ## Errors [#errors] | Code | Meaning | | ----- | -------------------------------------------------------------------------------------------------------- | | `400` | Missing token parameter, or chain\_id is not a number. The plain-text response body describes the issue. | | `404` | Chain ID not supported. | # Get Chains (/chains) Returns the full list of supported chains with their chain IDs and metadata. The Nordstern API is live on 100+ EVM-compatible chains. ## Response [#response] A JSON object keyed by chain ID. Each entry describes one supported chain. See the [Supported Chains](/supported-chains) page for a searchable list of all entries. Chain ID as a string. Lowercase internal chain identifier. Guard Contract address for this chain (same as `tx.to` in swap responses). DeFiLlama chain identifier, useful for cross-referencing TVL and price data. ## Example request [#example-request] ```bash curl 'https://api.nordstern.finance/chains' \ -H "Referer: https://yourdomain.com" ``` ```js const response = await fetch( "https://api.nordstern.finance/chains", { headers: { "Referer": "https://yourdomain.com" } } ); const chains = await response.json(); console.log(chains); ``` ```python import requests headers = {"Referer": "https://yourdomain.com"} response = requests.get("https://api.nordstern.finance/chains", headers=headers) print(response.json()) ``` ## Example response [#example-response] Status 200 — chain map (truncated): ```json { "1": { "ChainID": "1", "ChainName": "ethereum", "RouterAddress": "0xa929c559E5e6537359680F39CB4E3708E1a14dd1", "DefillamaName": "ethereum" }, "8453": { "ChainID": "8453", "ChainName": "base", "RouterAddress": "0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d", "DefillamaName": "base" } } ``` Don't see your chain? Reach out on [Telegram](https://t.me/nordstern_fi) and we'll prioritize adding support for your project. # Errors (/errors) ## Status codes [#status-codes] A required parameter is missing or has an invalid format (e.g., non-hex address, non-numeric amount). The response body is a plain-text string describing the specific problem. The requested chain\_id is not supported. Returns an nginx 404 HTML page. Unexpected server error. ## Example 400 bodies [#example-400-bodies] ```text amount must be provided amount must be a base-10 integer src and dst must be valid 0x... addresses ``` The swap endpoint always returns `200` even when no route is found — check that `toAmount` is non-zero and `tx` is present before submitting. See [Get Swap Route](/swap-route#before-submitting). # Rate Limits (/rate-limits) Automated spam and bot behaviour is blocked at the network level, but legitimate integrations (including high-frequency applications) are not subject to hard quotas. ## Best practices [#best-practices] Even without strict limits, well-behaved clients reduce latency and stay well clear of any abuse thresholds. * **Batch token requests.** Both [`/prices`](/token-price) and [`/liquidity`](/token-liquidity) accept comma-separated addresses. Fetch all the tokens you need in a single call instead of one request per token. * **Cache prices for short windows.** Token prices are stable over a few seconds. A 5–15 second client-side cache is safe for most UIs and cuts unnecessary request volume. * **Refresh quotes on user activity, not on idle polling.** Fetch a new route when the user changes inputs or is about to submit. There is no need to keep refreshing when the user is inactive. # Architecture (/architecture) The Guard Contract owns the security guarantees; the Executor Contract owns the routing logic. Separating these concerns means routing can be upgraded without ever touching the security layer. ## The swap pipeline [#the-swap-pipeline] ## Guard Contract [#guard-contract] The Guard Contract is the sole entry point for every Nordstern swap. Any transaction that does not pass through the Guard is not a valid Nordstern swap. Its responsibilities are: * Accepts the input tokens from the user. * Calls the Executor Contract to perform the swap. * After the Executor returns, checks that the output amount ≥ minOutput. * If the check passes, releases the output tokens to the user. * If the check fails (e.g., slippage exceeded), the entire transaction reverts. No funds move. The Guard Contract address varies by chain. See [Contracts](/contracts) for the full list. In the API response this address appears as `tx.to` and is referred to as the Router Contract. Both refer to the same deployed contract. ## Executor Contract [#executor-contract] The Executor is called by the Guard and performs the actual multi-hop routing: it calls each pool contract in the route sequence, converting tokens step by step. It has two key properties: * **Interchangeable.** The Guard can call different Executor implementations. This lets Nordstern ship routing improvements without touching the security layer. * **Trustless by design.** The Executor never controls fund release. Even if an Executor behaved unexpectedly, the Guard's output check would catch it and revert. ## Third-party DEX contracts [#third-party-dex-contracts] Each new venue is integrated by extending the Executor Contract to support that pool's interface, ensuring correct handling of pool-specific quirks such as fee tiers, direction flags, and non-standard token behaviours. All calls to third-party contracts originate from the Executor, not from the user's wallet. The user only approves the Guard Contract (shown as tx.to in the swap response) to spend their input token. # Security (/security) Every guarantee below is enforced in the contract code, not by off-chain policy — verifiable on any supported chain. ## On-chain guarantees [#on-chain-guarantees] The Guard Contract checks that the output amount ≥ minOutput (derived from the slippage parameter) before releasing any funds. If the check fails for any reason (slippage, MEV, or a routing bug), the transaction reverts and nothing moves. The Guard receives the input tokens and releases the output tokens atomically. There is no state where funds sit in the contract between blocks. Every swap either completes fully or reverts entirely. The Executor Contract performs routing but never controls fund release. That is always the Guard's responsibility. Even if an Executor implementation had a bug or was replaced with a malicious one, the Guard's output check prevents loss. Users approve only the Guard Contract (`tx.to` in the swap response) to spend their input token. Third-party DEX contracts are called by the Executor, not by the user's wallet. No additional approvals required. ## Verifying contracts [#verifying-contracts] Every deployment is listed on the [Contracts](/contracts) page. When verifying a swap, confirm that `tx.to` in the API response matches the Guard Contract for your chain. Any swap targeting a different address is not routed through Nordstern. ## Responsible disclosure [#responsible-disclosure] If you discover a security vulnerability in the contracts or API, please report it privately before public disclosure. # Contracts (/contracts) The Guard Contract is deployed independently on each supported chain. It is the entry point for all Nordstern swaps and the address you approve when submitting a transaction — it appears as `tx.to` in every API response. The Guard Contract and Router Contract are synonyms. The table below lists every deployment across all supported chains and is fetched live from the API. | Chain | Chain ID | Guard Contract | | --- | --- | --- | | Ancient8 | 888888888 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | ApeChain | 33139 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | AppChain | 466 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Arbitrum | 42161 | `0x57f96440f1b1cAD53B40A8924BD540b1279A491c` | | Arbitrum Nova | 42170 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Avalanche | 43114 | `0xa575f37e869e6887564F87c07e2885e08D542C4a` | | B2 | 223 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | B3 | 8333 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Base | 8453 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Beam | 4337 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Bera | 80094 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | Bitgert | 32520 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | BitLayer | 200901 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | BitTorrent | 199 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Blast | 81457 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | BOB | 60808 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Boba | 288 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | BSC | 56 | `0x1a3304cBef66de00FbE1548CC4C6585aD22FbCFf` | | Celo | 42220 | `0x911a744ab8eccB504173fBCAbBD7C34648F2A773` | | Chiliz Chain | 88888 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Core | 1116 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | Corn | 21000000 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Cyber | 7560 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Duck Chain | 5545 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Electroneum | 52014 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Elysium | 1339 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Ethereum | 1 | `0xa929c559E5e6537359680F39CB4E3708E1a14dd1` | | Flare | 14 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Flow EVM | 747 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Fraxtal | 252 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Funki | 33979 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Genesys | 16507 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Gensyn | 685689 | `0x9E6d21E759A7A288b80eef94E4737D313D31c13f` | | Gnosis | 100 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Goat | 2345 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Gravity | 1625 | `0x63d3C7Ab37ca36A2A0A338076C163fF60c72527c` | | HashKey | 177 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Hemi | 43111 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | HyperEVM | 999 | `0x2fF506ed9729580EF8Bf04429614beB1baE5F76D` | | Immutable zkEVM | 13371 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Ink | 57073 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Kaia | 8217 | `0xb4FE60CD05A3e68668007Cee83DDFD9A50A45B36` | | Katana | 747474 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | KCC | 321 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Kroma | 255 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | KUB | 96 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Linea | 59144 | `0x2fF506ed9729580EF8Bf04429614beB1baE5F76D` | | Lisk | 1135 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Manta Pacific | 169 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Mantle | 5000 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | MAP Protocol | 22776 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Metis | 1088 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | Mint | 185 | `0xb4FE60CD05A3e68668007Cee83DDFD9A50A45B36` | | Mode | 34443 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | Monad | 143 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Morph L2 | 2818 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Muster | 4078 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | opBNB | 204 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Optimism | 10 | `0xa575f37e869e6887564F87c07e2885e08D542C4a` | | Parex | 322202 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Plasma | 9745 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | PlatON | 210425 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Polygon | 137 | `0x99bA7d569EA69671B399A7cC488b687515F7EC23` | | Q Network | 35441 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Qitmeer | 813 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Rari | 1380012617 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Redstone | 690 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Reya | 1729 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Robinhood | 4663 | `0x603206D6105217DD972E4Ab30676A220CA393346` | | Ronin | 2020 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Rootstock | 30 | `0x63d3C7Ab37ca36A2A0A338076C163fF60c72527c` | | RSS3 VSL | 12553 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Sanko | 1996 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Scroll | 534352 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | SEI V2 | 1329 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Shape | 360 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Shibarium | 109 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Soneium | 1868 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Songbird | 19 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Sonic | 146 | `0x0a354845411CC1212cfb33Acc6A52Fcd4A80e3Ae` | | Step | 1234 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Story | 1514 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Superposition | 55244 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Superseed | 5330 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Swell Chain | 1923 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Taiko | 167000 | `0x63d3C7Ab37ca36A2A0A338076C163fF60c72527c` | | Telos | 40 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | ThunderCore | 108 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Ultron | 1231 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Unichain | 130 | `0x3FFc2315A992b01dc4B3f79C8EEa1921091Ee24f` | | Vana | 1480 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | WanChain | 888 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | WEMIX | 1111 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | World Chain | 480 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | XDC | 50 | `0x0EE6f0900990b23A2a96a6F41EB56693c9076031` | | ZeroG | 16661 | `0x9E6d21E759A7A288b80eef94E4737D313D31c13f` | | Zircuit | 48900 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | | Zora | 7777777 | `0xC87De04e2EC1F4282dFF2933A2D58199f688fC3d` | When submitting a swap, always verify that tx.to in the API response matches the Guard Contract address for your chain. Any swap targeting a different address is not routed through Nordstern. # Infrastructure (/infrastructure) The backend is designed to expand to new chains quickly and to serve global traffic with consistent response times. ## Scalable routing backend [#scalable-routing-backend] The routing engine is horizontally scalable and stateless by design. Adding support for a new chain requires no downtime and no changes to the API surface. New chains go live without affecting existing integrations. This is how Nordstern maintains day-one support for new EVM chains as they launch. ## Multi-region hosting [#multi-region-hosting] API nodes are deployed across multiple geographic regions. Requests are routed to the nearest available node, keeping network overhead minimal regardless of where your users are located. # AI & MCP (/ai-mcp) The Nordstern documentation is built to be consumed by AI agents, not just read by people. Point your assistant at the MCP server below to search and read the docs from inside your editor, or feed it the plain-markdown and `llms.txt` endpoints directly. ## Docs MCP server [#docs-mcp-server] A single [Model Context Protocol](https://modelcontextprotocol.io) endpoint exposes the entire documentation set. Once connected, your assistant can list, search, and read any page without leaving your editor. No install and no API key required. ```text https://docs.nordstern.finance/mcp ``` It speaks **Streamable HTTP**, registers as `nordstern-docs`, and provides three tools: Enumerate every page with its title, URL, and description. Keyword search across page titles, descriptions, and content. Returns the most relevant pages with a short excerpt. Fetch the full markdown of any page (the same text the Copy Markdown button uses). This server serves the documentation only; it does not execute swaps. For the trading API, see the [API Reference](/overview). ## Add it to your client [#add-it-to-your-client] The endpoint is a standard remote MCP server, so any MCP-aware client can connect to it. The URL below reflects the site you're viewing. ### Claude Code ```bash claude mcp add --transport http nordstern-docs https://docs.nordstern.finance/mcp ``` ### Cursor Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (per project): ```json { "mcpServers": { "nordstern-docs": { "url": "https://docs.nordstern.finance/mcp" } } } ``` ### VS Code Add to .vscode/mcp.json: ```json { "servers": { "nordstern-docs": { "type": "http", "url": "https://docs.nordstern.finance/mcp" } } } ``` ### Claude Desktop Add a custom connector under Settings → Connectors, or bridge to it from claude_desktop_config.json and restart the app: ```json { "mcpServers": { "nordstern-docs": { "command": "npx", "args": ["-y", "mcp-remote", "https://docs.nordstern.finance/mcp"] } } } ``` ### Devin Desktop Add to ~/.codeium/windsurf/mcp_config.json (legacy Codeium path, unchanged after the rebrand): ```json { "mcpServers": { "nordstern-docs": { "serverUrl": "https://docs.nordstern.finance/mcp" } } } ``` ## Other AI-friendly endpoints [#other-ai-friendly-endpoints] Every page is also available as raw markdown, so you can feed the docs to an AI tool without setting up MCP. * [llms.txt](/llms.txt) is a structured index of every page, for tools that support the `llms.txt` convention. * [llms-full.txt](/llms-full.txt) concatenates the whole documentation into a single markdown document. * Append `.md` to any page URL (for example [/swap-route.md](/swap-route.md)) to get its raw markdown. * The **Copy Markdown** and **Open in ChatGPT / Claude / …** buttons at the top of every page. # Integrations (/integrations) ## Projects building on Nordstern [#projects-building-on-nordstern] Cross-chain bridge and swap aggregator. LI.FI routes swaps on supported EVM chains through the Nordstern API, giving their users access to Nordstern's split routing and liquidity depth. Leading DEX aggregator. 1inch uses Nordstern as a routing source to extend coverage and execution quality across EVM chains. Intent-based DEX using batch auctions and solvers. CoW Swap solvers use Nordstern for on-chain execution to fill user orders with optimal routing. Cross-chain interoperability and bridging protocol. deBridge uses Nordstern for swap routing on EVM chains as part of its cross-chain transaction flow. Advanced DEX trading interface. Oku integrates the Nordstern API to provide users with optimal swap routes and deep liquidity access. ## Integrate the API [#integrate-the-api] The Nordstern API is REST-based. No SDK, no API key, no registration required. A working swap integration takes minutes. It walks through approvals, calldata submission, and a full end-to-end example in cURL, JavaScript, and Python. ## Become a liquidity source [#become-a-liquidity-source] Are you a DEX, AMM, or PMM looking to be included as a Nordstern liquidity source? Each new venue is integrated by extending the Executor Contract to support that pool's interface. The integration process covers: extending the Executor, simulation testing across token pairs, and deployment to production once routing quality meets the bar. # FAQ (/faq) No. All endpoints are publicly accessible over HTTPS with no authentication. Include a `Referer` header set to your domain so Nordstern can attribute traffic to your project. It attributes API traffic to your integration and helps Nordstern understand usage patterns. Browsers send it automatically on client-side `fetch` calls. Server-side or CLI callers must set it explicitly. See the code examples on each endpoint page. Use the standard native token address: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`. This convention is recognised across DeFi and works for both `src` and `dst`. When used as input, `tx.value` in the response will be non-zero. Pass it directly when submitting the transaction. Yes. The [`/prices`](/token-price) and [`/liquidity`](/token-liquidity) endpoints accept a comma-separated list of token addresses in the `token` parameter. Batch all tokens you need into a single request. Prices and liquidity reflect on-chain state at the time of the request. Routes are simulation-verified at the block number returned in `simulationBlock`. Revalidate before submission if more than 1–2 blocks have elapsed. The default is 0.5%. Because Nordstern quotes are simulation-verified, execution closely matches the quoted price, so you can reduce slippage for stricter execution without significantly increasing the risk of failure. It varies by chain. See the [Contracts](/contracts) page for the full list. Yes. Set the `Referer` header to your application's domain. The API has no CORS restrictions and works from any HTTP client. The API returns 200 with no `tx` field and `toAmount` set to zero. Always check both before submitting. This typically means insufficient on-chain liquidity for the pair. Try the [`/liquidity`](/token-liquidity) endpoint first to verify depth. Not currently. All supported chains are EVM-compatible. See the [Supported Chains](/supported-chains) page for the full list. # Support (/support) We aim to respond within a few hours. The fastest way to reach us. Ask integration questions, report issues, or discuss your use case directly with the team. Follow for API updates, new chain announcements, and ecosystem news. ## For production incidents [#for-production-incidents] Telegram is the fastest channel for urgent issues. Include your chain ID, the transaction hash or API response if available, and a description of the unexpected behaviour.