Skip to main content
v2 (https://api.fomoscan.sh/v2) and v3 take the same key and spend from the same balance. Most v3 operations cost what the v2 route they replace costs; the table under Routes and prices lists both.

At a glance

Keys, plans and credits

  • Your v2 key works on v3. A v3 call spends from the monthly credits, top-up and reveal cap a v2 call spends from, so GET /v2/me and GET /v3/me report one balance.
  • Scopes are the v2 scopes: basic covers REST and the stream, http:read REST only and live:read the stream only.
  • The stream takes the plans it takes on v2; WebSocket lists them.
  • A key on a free plan (pilot or explore) without reveals gets 403 PERMISSION_DENIED for every answer that takes a reveal. v2 let such keys reveal a fixed sample of handles and wallets; v3 has no sample set.
  • A refusal (400, 401, 402, 403, 429, 503) costs nothing. A 404 costs the operation’s miss price, as on v2.

Routes and prices

Credits per call. A reveal is one unit of the key’s monthly reveal cap. Each v3 operation lists every answer and its price under Price. New in v3, with no v2 route:
  • GET /v3/traders/{traderId}: 100; 200 for an unknown id.
  • GET /v3/leaderboards: free.
  • GET /v3/rankings: free.
  • GET /v3/capabilities: free.
  • GET /v3/traders/{traderId}/trades: 200 per started 20 rows of limit, plus 100 and a reveal per trader the page shows.
  • GET /v3/wallets/{family}/{address}/trades: 200 per started 20 rows of limit.

Ids and lookups

  • v3 never returns a platform’s own id, such as v2’s id and authorId. Every object carries our id, in the forms Ids lists.
  • v3 has no lookup by a v2 id. Find each trader once by handle (GET /v3/traders/lookup) or by wallet (GET /v3/wallets/{family}/{address}), store the tdr_ id, and call by it from then on:
  • A handle can match traders on several platforms. The lookup lists current handles first, then handles an account held in the last 30 days; platform= narrows it to one platform.
  • A trader merged into another answers 200 with the trader that absorbed it, and canonical.mergedFrom lists the old id. Store the id you get back.
  • Wallet paths name the address family: /v2/user/wallet/{address} is /v3/wallets/svm/{address} or /v3/wallets/evm/{address}. EVM addresses come back lowercase.
  • Token paths and ids name the network: /v3/tokens/{network}/{address}, tok_<network>_<address>, with network one of solana, ethereum, base, bsc, arbitrum, optimism, polygon, robinhood, hyperevm, monad, arc, xlayer, ink or hyperliquid. v2 inferred the chain from the address.

Answers

  • Every object is an envelope (kind, id, canonical, sources); Objects explains it. PnL, boards, rankings and the key are documents that hold envelopes.
  • Money: v2 sent USD as JSON numbers ("netUsd": 1430.12). v3 sends an Amount: { "value": "1430120000", "decimals": 6, "currency": "USD" }. Read value as a big integer or decimal and shift it by decimals; a float loses digits. Token prices carry 18 decimals.
  • Time: v2 sent and took epoch milliseconds (fomoCreatedAt, updatedAt, capturedAt, ?at=). v3 sends RFC3339 in UTC with milliseconds (2026-11-02T09:30:00.000Z) and takes RFC3339 in at; epoch milliseconds in at answer 400.
  • Nulls: v2 used null for a missing value. v3 tells four cases apart: no sources.<platform> key (no side on that platform), no block (the platform cannot provide it, or we hold no reading), a null field (empty when observed), and { "status": "unavailable", "retryable": true } in place of a block (we could not read it for this call).
  • Paging: v2 pages took before=<id of the last item> and answered count, hasMore, nextBefore. v3 lists answer { "items", "hasMore", "nextCursor" }; send nextCursor back as cursor. A cursor works only with the parameters that produced it. Post feeds keep limit from 1 to 100, 20 by default.
  • v2 ignored a query parameter it did not know. v3 answers 400 INVALID_ARGUMENT. HEAD answers 404.

Errors

v2: { "error": { "code", "message", "retryAfter" } }. v3: { "error": { "type", "code", "message", "requestId" } }, with X-Request-Id on every response and Retry-After on 429 and 503.

Fields

User record

  • id (the platform user id): none. Use the trader id (tdr_).
  • handle, name, bio, profilePicture: handle, name, bio, avatarUrl of the profile block in sources.<platform>. canonical.display repeats the newest of them.
  • twitter (a URL): profile.xHandle, the handle without @.
  • followers, following: the followGraph block.
  • solanaAddress, evmAddress: GET /v3/traders/{traderId}/wallets, wallet envelopes with canonical.family, canonical.address and the tier of each owner.
  • Handle suggestions: a missed lookup answers suggestions; match=closest answers the closest trader. Prefixes match through suggestions; there is no /search.
  • walletAvailable: canonical.walletAvailable on GET /v3/traders/{traderId} and GET /v3/traders/lookup, at no extra price and without a reveal.
  • banner, isPumpUser, groupBadges: none.
  • Wallet lookup: v2 answered one user record with the wallet on the other chain. GET /v3/wallets/{family}/{address} answers the wallet with every owner and a tier each (proven, account, partial, weak, unverified); GET /v3/traders/{traderId} reads an owner.

PnL

  • The path takes the tdr_ id in place of the handle. The batch body takes traderIds in place of handles and answers { "items": [ { "trader", "found", "pnl" } ] } in request order, in place of count, missing and entries.
  • status no-wallet is no_wallet.
  • wallet, evmWallet: wallets, a list of wal_ ids, filled only when status is ready.
  • handle, displayName, avatarUrl, twitter, followers: none. Read the trader.
  • In each window: netUsd is realized, volumeUsd is volume, buyVolumeUsd and sellVolumeUsd are buyVolume and sellVolume, trades is tradeCount, updatedAt is asOf, and rank is { "position", "of", "ranking" }. origin says where the figures come from: provider on 24h, 7d and 30d, computed on all.
  • unrealized.unrealizedPnlUsd and holdingsUsd are unrealized.value and holdingsValue.
  • Per window, unrealizedPnlUsd and totalPnlUsd are unrealized and total; approximate, stale and nextUpdateAt keep their v2 names.
  • Wallet PnL (GET /v3/wallets/{family}/{address}/pnl) lists the paired wallet of the other family in wallets; boards replaces pumpBoard. POST /v3/wallets/pnl takes up to 100 wallets.
  • all holds the net flow and rank we compute from our trades. v2 mixed cash flow with whole-wallet figures since 1 January 2025.
  • window (new) narrows windows to one key at the same price.

Posts

Theses, callouts and stream items are one kind, post:
  • thesis: canonical.body. segments: canonical.segments, each { "text", "url" }.
  • tokenAddress and tokenNetwork, callout coinMint and chain: canonical.token.id (tok_<network>_<address>). tokenSymbol, coinSymbol: canonical.token.symbol.
  • authorId and authorHandle, callout wallet and userName: canonical.author.trader and canonical.author.handle.
  • fomoCreatedAt, callout createdAt: canonical.postedAt. firstSeenAt (new) is when we first read the post.
  • likeCount, likes: canonical.likeCount. commentCount, replyCount, viewCount: the engagement block.
  • holdingsUsd, tokenAmount, authorTradeUsd, realizedPnlUsd, unrealizedPnlUsd, pnl, closedAt, callout position: the position block (value, quantity, invested, realizedPnl, unrealizedPnl, totalPnl, closed, closedAt).
  • calledOutAtMcap, multiple, maxMultiplier, mediaUrl: the callPerformance block (marketCapAtCall, multiple, maxMultiple, mediaUrl).
  • Thesis priceUsdAtPost and marketCapAtPost: callPerformance.priceAtCall and callPerformance.marketCapAtCall.
  • thesisHash: none. Key on id.

Tokens

  • GET /v2/token/{address}: GET /v3/tokens/{network}/{address}. The market block per platform carries price, marketCap, liquidity, volume24h, holders and priceChange24h (percent). A token without platform market data is read live, as on v2, into canonical.market.

Boards and rankings

  • /v2/leaderboard/<board> and /v2/pump/leaderboard/traders are /v3/leaderboards/{platform}/{board}; GET /v3/leaderboards lists every board with its windows.
  • window stays. period daily, weekly, monthly is window 24h, 7d, 30d. at takes RFC3339 in place of epoch milliseconds.
  • count is entryCount. An entry is { "rank", "subject", "measures" }: subject is the trader, token or group envelope in place of id, handle, label and avatarUrl. measures holds the figures under snake-case keys, money as amounts: marketCap is market_cap, numTrades is trade_count, memberCount is members.
  • /v2/leaderboard/traders-fomoscan?window=&order= is /v3/rankings/traders_net_flow_<window>?order=. Tied traders share a rank, and order=worst answers the bottom entries with their own ranks, where v2 numbered them from 1.

Account

  • GET /v3/me moves entitlement and usage into api: monthlyUnits, additionalUnits, unitsUsed, unitsRemaining, ratePerMinute, monthlyReveals, revealsUsed, revealsRemaining, unmetered. Stream minutes count in api.unitsUsed.

Limits and refusals

  • A 429 or a 503 costs nothing. Retry after the seconds in Retry-After.
  • A reveal that waits more than 2 seconds on the reveal lock of the key answers 429 with Retry-After: 1, as on v2.

Stream

  • Close codes: 1001 we restart; 1008 no credit for the next minute, or the key lost access; 1009 a frame over 64 KB; 1011 no pong, or billing failed twice in a row; 1013 8 MB of frames wait unread, or frames arrive faster than we handle them.
  • One socket carries every platform, so a client of both v2 sockets pays one minute where v2 charged two.
  • A v2 frame sent to v3 answers an INVALID_ARGUMENT error frame and changes nothing.
  • v3 sends each post once, when it first becomes visible to us. postedAt gives its age.
  • Reconnect with since set to the last cursor you handled. WebSocket holds every frame, error code and a reconnect recipe.

Not in v3 yet

  • Lookup by a v2 id: GET /v2/user/id/{id}, GET /v2/user/id/{id}/profile, and author feeds keyed on that id.
  • Reads on demand: v2 fetched the theses of a token it had not read during the call. GET /v3/tokens/{network}/{address}/posts answers an empty page.
  • Author name, author avatar and token image on each post (authorName, authorAvatarUrl, tokenImageUrl, callout profileImage). Read the author and the token by id.
  • Percentages and cost basis of the author’s position: percentageRealizedPnl, percentageUnrealizedPnl, callout pnlPercentage, avgEntryPriceUsd, avgEntryMcapUsd, costBasisAmount, amountBought.
  • Wallet holdings with cost basis from the buy history: GET /v2/pump/user/wallet/{wallet}/holdings, POST /v2/pump/user/wallets/holdings.
  • Live resolve: POST /v2/user/handle/{handle}/resolve and its 202. v3 answers from stored data.
  • The stats and open holdings of the GET /feed/trader/{handle} card.
  • MCP: the v2 MCP server, its GET /v2/stats/… reads and POST /v2/user/handle/{handle}/reveal.