Every endpoint, what it costs, and what it returns.
Eleven endpoints across identity resolution, trader theses and a live feed. This page covers what a machine-generated spec cannot: how billing works, what a miss means, and how to read each response. For exact request and response shapes, the OpenAPI 3.1 document at GET /openapi.json is the source of truth. The running service generates it, so it cannot drift. The interactive Swagger UI (opens in a new tab) renders the same document and calls any endpoint live with your key.
Authentication
Send your key as a bearer token. X-Api-Key: $KEY is accepted as an alternative. Keys look like fsk_live_… (production) or fsk_test_… (sandbox).
meta.asOf — the freshness marker: the data is best observed as of this time.
meta.requestId — unique per request. Include it if you contact support.
Endpoints
Three families. Every plan reaches every endpoint — pricing is per call, in compute units, not per feature.
Identity
FomoScan identity endpoints: forward and reverse handle-to-wallet resolution.
Endpoint
Answers
Cost
GET /v2/user/handle/{handle}
handle → user + verified wallets
100 CU found, 200 not found
GET /v2/user/id/{id}
FOMO user id → user + verified wallets
100 CU found, 200 not found
GET /v2/user/wallet/{address}
wallet → the trader(s) behind it
30,000 CU found, 200 not found
POST /v2/user/handle/{handle}/resolve
go and resolve this handle, live
30,000 CU found, 200 on a 202 or 404
GET /v2/user/handle/{handle}/pnl
handle → what this trader made, on chain, live
30,000 CU found, 200 not found
POST /v2/user/handles/pnl
up to 100 handles → the same, in one call
30,000 CU per handle found, 200 per miss
FomoScan identity endpoints: forward and reverse handle-to-wallet resolution.
GET /v2/user/handle/{handle}/pnl reads one trader's profit and loss. You are billed on every call. Three outcomes carry three different meanings:
What each PnL endpoint result means
Result
Meaning
404
We do not hold this handle.
200, wallet: null
We know the trader but hold no proven wallet — never that they have none.
200, wallet set, every window null
We asked about that address and got nothing back. This does not mean the trader made no trades.
Theses
A thesis is a trader's written rationale attached to a token. All four endpoints are newest-first and take a before cursor to page backwards.
Endpoint
Answers
Cost
GET /v2/thesis
every thesis, newest first
200 CU per 20 rows
GET /v2/thesis/token/{tokenAddress}
one token's wall
200 CU per 20 rows
GET /v2/thesis/user/{id}
one author's wall
200 CU per 20 rows
GET /v2/thesis/user/{id}/token/{tokenAddress}
one author on one token
200 CU per 20 rows
A thesis is a trader's written rationale attached to a token. All four endpoints are newest-first and take a before cursor to page backwards.
Live feed
The theses feed, pushed over a WebSocket as items are indexed.
Endpoint
Answers
Cost
GET /v2/ws
theses pushed as they are indexed
20,000 CU per minute held open
The theses feed, pushed over a WebSocket as items are indexed.
One socket carries the whole feed. Attach, then send one subscribe frame naming either the firehose or up to 50 token addresses, and change it later without reconnecting — a connection holds one subscription, and a new subscribe replaces whatever you had.
It authenticates with the same Authorization header, so the key cannot come from a browser — hold the socket in your backend.
There is no replay. Take a snapshot from the polling endpoint on connect and reconcile on id after any reconnect.
The pong is mandatory: we ping every 30 seconds and close a socket that does not answer by the next one.
Running out of quota closes the socket with code 1008.
Resolving on demand
POST /v2/user/handle/{handle}/resolve asks for a handle's wallet when FomoScan holds nothing for it yet, and waits for the answer. A handle already held comes back immediately.
When the answer is not ready in time you get a 202 instead of an error, with a reason that is one of queued, timeout, unavailable, rate_limited or not_ingested, all worth retrying, or no_preview, which is a property of the account and not worth retrying. Honour retryAfterSeconds rather than tight-looping.
Repeat calls for the same handle join the request you already have rather than starting a second one.
Billing
Every call costs compute units (CU) from your monthly allowance, at the price listed beside its endpoint above. Plan prices are published at partner.fomoscan.sh (opens in a new tab).
A miss still costs. A lookup that finds nothing is charged 200 CU.
GET /v2/ws is metered per minute held open rather than per call.
Errors that are FomoScan's fault or your client's fault — 401, 403, 429, 5xx — are never billed.
Your monthly allowance is a hard cap with no rollover. Once spent, calls return 402 QUOTA_EXCEEDED until the counter resets; topping up lifts that cap immediately. Wallet reveals draw on a separate monthly allowance; past it, reveal calls return 402 REVEAL_LIMIT_REACHED, which top-ups cannot lift. Check remaining units any time with the unbilled GET /v2/me.
Quota exceeded402
{
"error": { "code": "QUOTA_EXCEEDED", "message": "out of credits - update billing on https://partner.fomoscan.sh" }
}
404 NOT_OBSERVED
A 404 does not mean the handle, wallet or token is unknown to fomo.family. It means FomoScan holds no verified link for it — either no proof has ever been observed, or one was observed but did not meet the verification bar. The correct client behaviour is the same either way: treat it as "no answer today," cache the negative briefly, and retry later. Verification is continuous, so a subject that misses now may resolve next week.
Error codes
Every error uses the same shape: { "error": { "code": "...", "message": "..." } }. A 429 additionally carries retryAfter in seconds.
FomoScan API error codes and their meaning
HTTP
Code
Meaning
400
VALIDATION_ERROR
A malformed handle, address, or query parameter.
401
UNAUTHORIZED
Missing or invalid API key.
402
QUOTA_EXCEEDED
Out of credits — top up at partner.fomoscan.sh.
402
REVEAL_LIMIT_REACHED
Monthly wallet-reveal allowance spent. Top-ups cannot raise it; upgrade the plan or wait for the period to reset.
403
FORBIDDEN_SCOPE
Your key is not provisioned for this endpoint.
404
NOT_OBSERVED
No verified match for the subject you asked about.
429
RATE_LIMITED
Per-minute limit exceeded; retry shortly.
503
OVERLOADED
We are shedding load. Nothing was charged; retry.
Rate limits
Each key has one per-minute request limit across every endpoint, readable from GET /v2/me as ratePerMinute, set by your plan:
FomoScan API rate limits by plan
Plan
Requests / minute
Explore (free)
60
Starter
150
Builder
300
Growth
600
Scale
1,200
Enterprise
per contract
A per-IP burst ceiling sits behind the plan limit as an anti-abuse backstop. Exceeding either returns 429 RATE_LIMITED with a retryAfter.
A thesis page may return pending the first time it is asked for. Poll the same endpoint on your normal interval.
OpenAPI
Paste your key into the interactive reference and call any endpoint directly, or import the OpenAPI 3.1 document into Postman, Insomnia or your code generator.