experiencing high traffic — performance might be degraded
FomoScan · API reference

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

Example requestcurl
curl -s -H "Authorization: Bearer $KEY" \
  "https://api.fomoscan.sh/v2/user/handle/tradername"

Every successful response uses the same envelope:

Response envelope200 OK
{
  "data": { "...": "the answer" },
  "meta": {
    "asOf": "2026-08-19T10:00:00.000Z",
    "requestId": "3f4c9a52-6a7e-4b1d-8f2e-0c1d2e3f4a5b"
  }
}
  • 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.
EndpointAnswersCost
GET /v2/user/handle/{handle}handle → user + verified wallets100 CU found, 200 not found
GET /v2/user/id/{id}FOMO user id → user + verified wallets100 CU found, 200 not found
GET /v2/user/wallet/{address}wallet → the trader(s) behind it30,000 CU found, 200 not found
POST /v2/user/handle/{handle}/resolvego and resolve this handle, live30,000 CU found, 200 on a 202 or 404
GET /v2/user/handle/{handle}/pnlhandle → what this trader made, on chain, live30,000 CU found, 200 not found
POST /v2/user/handles/pnlup to 100 handles → the same, in one call30,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
ResultMeaning
404We do not hold this handle.
200, wallet: nullWe know the trader but hold no proven wallet — never that they have none.
200, wallet set, every window nullWe 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.
EndpointAnswersCost
GET /v2/thesisevery thesis, newest first200 CU per 20 rows
GET /v2/thesis/token/{tokenAddress}one token's wall200 CU per 20 rows
GET /v2/thesis/user/{id}one author's wall200 CU per 20 rows
GET /v2/thesis/user/{id}/token/{tokenAddress}one author on one token200 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.
EndpointAnswersCost
GET /v2/wstheses pushed as they are indexed20,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
HTTPCodeMeaning
400VALIDATION_ERRORA malformed handle, address, or query parameter.
401UNAUTHORIZEDMissing or invalid API key.
402QUOTA_EXCEEDEDOut of credits — top up at partner.fomoscan.sh.
402REVEAL_LIMIT_REACHEDMonthly wallet-reveal allowance spent. Top-ups cannot raise it; upgrade the plan or wait for the period to reset.
403FORBIDDEN_SCOPEYour key is not provisioned for this endpoint.
404NOT_OBSERVEDNo verified match for the subject you asked about.
429RATE_LIMITEDPer-minute limit exceeded; retry shortly.
503OVERLOADEDWe 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
PlanRequests / minute
Explore (free)60
Starter150
Builder300
Growth600
Scale1,200
Enterpriseper 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.

Download the OpenAPI documentcurl
curl -s "https://api.fomoscan.sh/openapi.json" > openapi.json

Questions the reference does not answer: fomoscan-support@proton.me