Indexer API
The NASDANK indexer serves a narrow REST surface and a complete GraphQL one. This is what each covers, and the two traps that cost the most time.
Everything in it is derived. For anything a user will act on — a balance, a claimable amount, a price you are about to trade at — read the chain. The rules on Reading token state apply, and the indexer's own lag is the reason they do.
The two traps
1. REST is version-prefixed, not query-parameterised
# WRONG - reads a dead V1 table and returns zeros forever
curl https: 0
curl https: 1
# RIGHT - the version is a PATH segment
curl https: 2
curl https: 3
curl https: 4 The failure is silent: the bare path answers 200 with zeros rather than erroring, so a client built against it looks like it works and reports an empty protocol.
2. It is behind Cloudflare, which challenges datacenter IPs
This is the most expensive shape of bug in the whole integration, because it passes local review. If you must call from a server, send a real browser User-Agent — and even then, expect it to be blocked. Calling from the browser is the supported path.
REST
| Endpoint | Returns |
|---|---|
GET /api/all/tokens?limit=&offset=&sort= | Every launch, newest first by default |
GET /api/v2|v3|v4/tokens | Launches of one generation |
GET /api/v2|v3|v4/stats | Aggregates for that generation |
GET /api/referrals/:wallet | Referral tree, earnings, and the merkle proof |
A token record
{
1 : 2 , 3 : 1, 4 : 0, 5 : 1, 6 : 1,
7 : [{
8 : 9 ,
10 : 11 ,
12 : 13 ,
14 : 15 ,
16 : 17 ,
18 : 19 ,
20 : 21 ,
22 : false,
23 : 24 ,
25 : 26 ,
27 : 28 imageUri 29 socials 30 status 31 live 32 createdAt 33 createdBlock 34 36362047 35 totalSupply 36 1000000000000000000000000000 37 feeTier 38 rangePreset 39 twoSided 40 protocolBps 41 initSqrtPriceX96 42 1547015046645624099073479981395075 43 tickLower 44 tickUpper 45 wethSeeded 46 0 47 creatorBuyEth 48 0 49 creatorTokensOut 50 0 51 lastSqrtPriceX96 52 1547015046645624099073479981395075 53 lastTick 54 lastPriceWeth 55 2622829694 56 marketCapWeth 57 2622829694000000000 58 reserveWeth 59 0 60 volumeWeth 61 0 62 tradeCount 63 feeWethToProject 64 0 65 feeWethToTreasury 66 0 67 feeTokenToProject 68 0 69 feeTokenToTreasury 70 0 71 feeCollectCount 72 lastFeeAt 73 volume24hWeth 74 0 75 lpBeneficiary 76 0x6a2953b9d68ed5921aa5873a97c9367bec3b16d6 77 feeClaimedWeth 78 0 79 feePendingWeth 80 0"
}]
}Field notes
| Field | What to know |
|---|---|
feeTier | Hundredths of a bip. 10000 is 1%, 3000 is 0.3%, 500 is 0.05%. |
protocolBps | Basis points. 1500 is 15%. |
tokenIsToken0 | Decides whether the pool's price is the coin's price or its reciprocal. Never assume it. |
tickLower at -887200 | Full range. Normal and correct on V3, not a sign of a broken launch. |
Every *Weth field | Wei-denominated strings. Parse as BigInt, never as a JS number. |
launchType | v3 / v4 — Pro / Custom. A v2 record is a historical launch from a tier that is no longer offered. |
pool vs pool id | An address on V3; V4 records identify the pool by its id. |
GraphQL
Mounted at /graphql, with introspection open. This is the whole database rather than a curated slice: trades, creators, vault products, everything the REST surface omits. It also has no version-prefix trap, which is the second reason to prefer it.
query LaunchesByCreator($creator: String!) {
tokens(where: { creator: $creator }, orderBy: 0 , orderDirection: 1 , limit: 50) {
totalCount
items {
address
name
symbol
launchType
pool
createdAt
volumeWeth
feeWethToProject
}
}
}curl -s https: 0
-H 1 \
-H 2 \
-d 3 Checking res.ok is not enough and never has been. A query with a typo comes back as HTTP 200 carrying {"errors":[...]} and no data. Check for errors explicitly.
The indexer is per-chain
The indexer has no concept of a chain at all — no chainId field, no network parameter — and each instance serves exactly one network. Asking Robinhood's indexer about a BNB coin does not return an error; it returns nothing, which reads as "this coin has no pool" rather than "you asked the wrong host". Point at the right base URL per chain and, on a chain with no indexer, produce an honest empty state rather than falling back to another chain's numbers.
Lag
Indexers fall behind. When they do, every derived figure — volume, trade count, 24-hour change, last price — is as old as the lag, while looking completely current. Two consequences:
- Never trigger on indexed data. A standing order evaluated against a lagging last-trade fires against a price that no longer exists.
- Never price a user's trade from it. Take the live mark from the deepest pool.
{ _meta { status } }Token metadata
Each token's metadataUri is an ipfs:// URI pointing at a JSON document with the name, symbol, description, image and socials supplied at launch. Resolve it through a gateway you control.
A gateway that worked for months can start returning nothing, and the symptom is every coin on your site losing its picture at once. Use a dedicated gateway, and make sure a failed image resolves to a placeholder rather than to a broken layout.
Rate limits and etiquette
- Send a real
User-Agent. A missing one is the default cause of "works locally, empty in production". - Page with
limitandoffsetrather than pulling everything. - Cache aggressively at your edge. The data is derived; it does not need to be re-fetched per request.
- Do not poll for something you can read from the chain once.