# 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.