{"openapi":"3.1.0","info":{"title":"fomoscan API","version":"3.0.0","description":"Coming from v2 (`https://api.fomoscan.sh/v2`)? The section Moving from v2, at the end of this introduction, maps each v2 route to its v3 operation and price and lists what changed.\n\nSocial graph, post and wallet data for trading products, in one shape for every platform. Every price is in credit units.\n\n## Objects\n\nEvery object is an envelope:\n\n```json\n{ \"kind\": \"trader\", \"id\": \"tdr_01jbst8pvcfp79y0938nkrkayd\", \"canonical\": { … }, \"sources\": { \"<platform>\": { \"profile\": { … } } } }\n```\n\n| Field | Meaning |\n| --- | --- |\n| `kind` | `trader`, `wallet`, `post`, `trade`, `token`, `group`. The only field to switch on. Skip kinds you do not know. |\n| `id` | Our id of the object. Store it; see Ids. |\n| `canonical` | Fields that mean the same on every platform. |\n| `sources` | Capability blocks keyed by platform. A block has the same shape on every platform that provides it and carries its own `observedAt`. |\n\nWhat `sources` tells you:\n\n| On the wire | Meaning |\n| --- | --- |\n| `sources.<platform>` absent | The object has no side on that platform. |\n| `sources.<platform>.<block>` absent | The platform cannot provide the block (`GET /v3/capabilities` lists which can), or we hold no reading of it yet. |\n| A block field is `null` | The platform left it empty at `observedAt`, or never fills it (`unfilled` in the capability table). |\n| `{ \"status\": \"unavailable\", \"retryable\": true }` in place of a block | We could not read the block for this call. The rest of the object is current. |\n\nPnL, boards, rankings, follow lists, the key and the capability table are documents about a subject. A document holds envelopes wherever a subject appears.\n\n## Ids\n\n| Kind | Id |\n| --- | --- |\n| `trader` | `tdr_` and 26 lowercase base32 characters |\n| `wallet` | `wal_<family>_<address>`, family `svm` or `evm` |\n| `post` | `pst_` and 26 lowercase base32 characters |\n| `trade` | `trd_` and 26 lowercase base32 characters |\n| `token` | `tok_<network>_<address>` |\n| `group` | `grp_` and 26 lowercase base32 characters |\n\n- A malformed id or a wrong prefix answers 400 `INVALID_ARGUMENT` before any read.\n- A platform's own ids never appear in a response. Find a trader once, by handle (`GET /v3/traders/lookup`) or by wallet (`GET /v3/wallets/{family}/{address}`), then keep our id.\n- An id merged into another trader answers 200 with the trader that absorbed it, whose `canonical.mergedFrom` lists the old id.\n- List cursors start with `c_`, stream cursors with `s_`. Neither works in the place of the other.\n\n## Money and time\n\n- Money and token quantities are `Amount` objects, never JSON numbers. `{ \"value\": \"12345678\", \"decimals\": 6, \"currency\": \"USD\" }` is 12.345678 USD.\n- `value` is an integer in base units, as a string, and negative below zero. Read it with a decimal or big integer type: a float loses digits.\n- `currency` is `USD`, or the token id of a token quantity (`tok_solana_<mint>`).\n- `priceAsOf` is present when we converted a value with a price, and holds the time of that price.\n- Ratios (`returnPct`, `multiple`) and counts are JSON numbers.\n- Times in bodies are RFC3339 in UTC with milliseconds. A time in a query parameter (`at`) is RFC3339 with `Z` or an offset.\n\n## Paging\n\nA list answers one page:\n\n```json\n{ \"items\": [ … ], \"hasMore\": true, \"nextCursor\": \"c_…\" }\n```\n\n- Send `nextCursor` back as `cursor` for the next page. Stop when `hasMore` is `false`.\n- A cursor is opaque and belongs to the query that produced it. Sent with other parameters, it answers 400 `INVALID_ARGUMENT`.\n- `limit` defaults to 50, at most 200. Post feeds, follow lists and trade lists default to 20, at most 100.\n- A page boundary inside a tie of the order neither drops nor repeats a row.\n- The entries of one board or ranking arrive whole, without paging.\n\n## Errors\n\nEvery error answers the same body:\n\n```json\n{ \"error\": { \"type\": \"invalid_request\", \"code\": \"NOT_FOUND\", \"message\": \"Trader not found.\", \"requestId\": \"req_…\" } }\n```\n\n| HTTP | `type` | `code` | When |\n| --- | --- | --- | --- |\n| 400 | `invalid_request` | `INVALID_ARGUMENT` | A parameter, id, cursor or body is malformed, or the operation does not take it. |\n| 401 | `authentication` | `UNAUTHENTICATED` | No key, or the key is unknown, revoked or expired. |\n| 402 | `quota` | `QUOTA_EXCEEDED` | The credit balance cannot pay for the call. |\n| 402 | `quota` | `REVEAL_LIMIT_REACHED` | The answer needs a reveal and the key has used every reveal this month. |\n| 403 | `permission` | `PERMISSION_DENIED` | The key may not make the call: it has no REST scope, its plan is switched off, or a free key asked for a reveal. |\n| 403 | `permission` | `PLAN_REQUIRED` | The plan of the key does not include the stream. REST calls never answer it. |\n| 404 | `invalid_request` | `NOT_FOUND` | The subject of the call does not exist, or no route has this method and path. |\n| 429 | `rate_limit` | `RATE_LIMITED` | Too many requests from the key or the address. Wait `Retry-After` seconds. |\n| 500 | `internal` | `INTERNAL` | The call failed on our side. Retry with backoff, and quote `requestId` if it repeats. |\n| 503 | `overloaded` | `OVERLOADED` | The API holds too many requests at once. Wait `Retry-After` seconds. |\n\n- Act on `code`. `message` is for people and can change.\n- 429 and 503 carry `Retry-After` in seconds.\n- A query parameter the operation does not list answers 400.\n\n## Requests\n\n- Send the key in `Authorization: Bearer <key>` or in `X-Api-Key: <key>`. A key in the query string does not count.\n- Every response carries `X-Request-Id`, the id of the request in our logs. Quote it when you write to us.\n- Every response carries `Cache-Control: private, no-store`.\n- A request body is JSON sent with `Content-Type: application/json`. A body with another content type, or with none, answers 400.\n- `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` report the per-minute window of the key. A key without a limit gets none of them.\n\n## Compatibility\n\n- Inside v3 every change is additive: a new optional field, kind, platform key or block. Skip what you do not know.\n- Removing, renaming or retyping a field needs a new major version.\n\n## Servers\n\nREST calls go to `https://api.fomoscan.sh`. The stream lives on its own host; see the WebSocket section.\n\n## Credits and reveals\n\n- A call that answers takes the credits of the table below from the key's monthly balance; a `free` operation takes none. `GET /v3/me` shows the balance.\n- A refusal (400, 401, 402, 403, 429, 503) costs nothing. A 404 costs what the operation's Price table says.\n- A reveal is one unit of the key's monthly reveal allowance. Operations that show who owns a wallet or what a person earned take them, as the Reveals column says.\n- A metered key that cannot pay for an answer gets 402 `QUOTA_EXCEEDED` in its place. It is never charged past its balance.\n- Each operation lists its prices in full under Price.\n\n| Operation | Credits | Reveals |\n| --- | --- | --- |\n| `GET /v3/traders/{traderId}` | 100 hit, 200 miss | none |\n| `GET /v3/traders/lookup` | 100 hit, 200 miss | none |\n| `GET /v3/wallets/{family}/{address}` | 30,000 hit, 200 miss, 10 flat | one per hit |\n| `GET /v3/traders/{traderId}/wallets` | 100 hit, 200 miss | one when the page lists a wallet |\n| `GET /v3/traders/{traderId}/pnl` | 30,000 hit, 200 miss | one per hit |\n| `POST /v3/traders/pnl` | 30,000 per `ready` item, 200 per other item | one per `ready` item |\n| `GET /v3/posts` | 200 per started 20 rows of `limit`; 10 flat with `platform=pump` | none |\n| `GET /v3/tokens/{network}/{address}/posts` | 200 per started 20 rows of `limit`; 10 flat with `platform=pump` | none |\n| `GET /v3/traders/{traderId}/posts` | 200 per started 20 rows of `limit`; 10 flat with `platform=pump` | none |\n| `GET /v3/tokens/{network}/{address}` | 100 hit, 100 miss | none |\n| `GET /v3/leaderboards` | free | none |\n| `GET /v3/leaderboards/{platform}/{board}` | 500 hit, 200 miss, 10 flat | none |\n| `GET /v3/rankings` | free | none |\n| `GET /v3/rankings/{key}` | 500 hit, 200 miss | none |\n| `GET /v3/me` | free | none |\n| `GET /v3/capabilities` | free | none |\n| `GET /v3` (WebSocket) | 20,000 per started minute per connection | none |\n| `GET /v3/traders/{traderId}/followers` | 200 per started 20 rows of `limit` | none |\n| `GET /v3/traders/{traderId}/following` | 200 per started 20 rows of `limit` | none |\n| `GET /v3/trades` | 200 per started 20 rows of `limit`, plus 100 per trader shown | one per trader shown |\n| `GET /v3/traders/{traderId}/trades` | 200 per started 20 rows of `limit`, plus 100 per trader shown | one per trader shown |\n| `GET /v3/wallets/{family}/{address}/trades` | 200 per started 20 rows of `limit` | none |\n| `GET /v3/wallets/{family}/{address}/pnl` | 500 hit, 200 miss | none |\n| `POST /v3/wallets/pnl` | 500 per `ready` item, 200 per other item | none |\n\n## Rate limits\n\n| Limit | Value | Past it |\n| --- | --- | --- |\n| Per key | The key's `ratePerMinute` (`GET /v3/me`), reported in the `RateLimit-*` headers. | 429 `RATE_LIMITED` with `Retry-After`. |\n| Per address, before the key is checked | 2,400 requests per minute. | 429 `RATE_LIMITED` with `Retry-After`. |\n| Per address and operation | Requests per minute: 2,000 on most operations; 120 on `POST /v3/traders/pnl`; 120 on `GET /v3/me`; 120 on `POST /v3/wallets/pnl`; 600 on `GET /v3/leaderboards/{platform}/{board}`; 600 on `GET /v3/rankings/{key}`. | 429 `RATE_LIMITED` with `Retry-After`. |\n| Requests in flight at once on one API instance, across every key | 30 requests. | 503 `OVERLOADED` with `Retry-After: 1`, before the key is checked. |\n| Requests in flight at once on one API instance, for one key and the keys under it | 15 requests. | 429 `RATE_LIMITED` with `Retry-After: 1`, after the key is checked. |\n\nA refused request costs nothing. Retry after the seconds in `Retry-After`.\n\n## Live posts\n\nLive posts arrive over one WebSocket on the stream host. The WebSocket section at the end of this page says how to connect, what it costs and how to behave on it.\n\n## Moving from v2\n\nv2 (`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.\n\n### At a glance\n\n|  | v2 | v3 |\n| --- | --- | --- |\n| REST | `https://api.fomoscan.sh/v2/…` | `https://api.fomoscan.sh/v3/…` |\n| Reference | `https://api.fomoscan.sh/docs`, `https://docs.fomoscan.sh` | `https://api.fomoscan.sh/v3/docs`, `https://api.fomoscan.sh/v3/openapi.json` |\n| Stream | `wss://api.fomoscan.sh/v2/ws`, `wss://api.fomoscan.sh/v2/ws/pump` | `wss://stream.fomoscan.sh/v3`, one socket for every platform |\n| Key | `fsk_live_…`, `fsk_test_…` | the same key |\n| Headers | `Authorization: Bearer <key>` or `X-Api-Key: <key>` | the same; a key in the query string does not count |\n| Answers | flat JSON records, USD as numbers, epoch milliseconds | envelopes and documents, money as integer strings, RFC3339 times |\n\n### Keys, plans and credits\n\n- 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.\n- Scopes are the v2 scopes: `basic` covers REST and the stream, `http:read` REST only and `live:read` the stream only.\n- The stream takes the plans it takes on v2; the WebSocket section lists them.\n- 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.\n- A refusal (400, 401, 402, 403, 429, 503) costs nothing. A 404 costs the operation's miss price, as on v2.\n\n### Routes and prices\n\nCredits 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.\n\n| v2 | v2 credits | v3 | v3 credits |\n| --- | --- | --- | --- |\n| `GET /v2/user/handle/{handle}` | 100 and a reveal when a wallet is returned; 200 not found | `GET /v3/traders/lookup?handle=`, then `GET /v3/traders/{traderId}/wallets` | 100, 200 with no match; then 100, and a reveal when the page lists a wallet |\n| `GET /v2/user/handle/{handle}/profile` | 100; 200 not found | `GET /v3/traders/lookup?handle=` | 100; 200 with no match |\n| `GET /v2/user/id/{id}`, `GET /v2/user/id/{id}/profile` | 100; 200 not found | not in v3 yet |  |\n| `GET /v2/user/wallet/{address}`, `GET /v2/pump/user/wallet/{wallet}` | 30,000 and a reveal, 200 not found; the `/v2/pump/` route 10 | `GET /v3/wallets/{family}/{address}` | 30,000 and a reveal; 10 when every owner holds tier `account`; 200 without an owner |\n| `POST /v2/user/handle/{handle}/resolve` | 30,000 and a reveal; 200 on a 202 or 404 | `GET /v3/traders/{traderId}/wallets`, stored wallets only | 100, and a reveal when the page lists a wallet; 200 for an unknown trader |\n| `GET /v2/user/handle/{handle}/pnl` | 30,000 and a reveal when `ready`; 200 otherwise | `GET /v3/traders/{traderId}/pnl` | 30,000 and a reveal when `ready`; 200 otherwise |\n| `POST /v2/user/handles/pnl` | per handle: 30,000 and a reveal when `ready`, 200 otherwise | `POST /v3/traders/pnl` | per id: 30,000 and a reveal when `ready`, 200 otherwise |\n| `GET /v2/pump/user/wallet/{wallet}/pnl` | 500 when `ready`; 200 otherwise | `GET /v3/wallets/svm/{address}/pnl` | 500 when `ready`; 200 otherwise |\n| `POST /v2/pump/user/wallets/pnl` | per wallet: 500 when `ready`, 200 otherwise | `POST /v3/wallets/pnl` | per wallet: 500 when `ready`, 200 otherwise |\n| `GET /v2/user/handle/{handle}/holdings`, `POST /v2/user/handles/holdings` | 2,500; 1,250 per handle; allow-listed keys only | allow-listed keys only; v3 keeps its own list | 2,500; 1,250 per trader |\n| `GET /v2/pump/user/wallet/{wallet}/holdings`, `POST /v2/pump/user/wallets/holdings` | 500 per wallet; allow-listed keys only | not in v3 yet |  |\n| `GET /v2/thesis` | 200 per started 20 rows of `limit` | `GET /v3/posts` | 200 per started 20 rows of `limit` |\n| `GET /v2/thesis/token/{tokenAddress}` | 200 per started 20 rows of `limit` | `GET /v3/tokens/{network}/{address}/posts` | 200 per started 20 rows of `limit` |\n| `GET /v2/thesis/user/{id}`, `GET /v2/thesis/user/{id}/token/{tokenAddress}` | 200 per started 20 rows of `limit` | `GET /v3/traders/{traderId}/posts`, with `token=tok_…` for one token | 200 per started 20 rows of `limit`; 200 for an unknown trader |\n| `GET /v2/pump/thesis` | 10 for a page of 25 | `GET /v3/posts?platform=pump` | 10 for a page of up to 100 |\n| `GET /v2/pump/thesis/token/{mint}` | 10 for a page of 25 | `GET /v3/tokens/solana/{address}/posts?platform=pump` | 10 for a page of up to 100 |\n| `GET /v2/pump/thesis/wallet/{wallet}` | 10 for a page of 25 | `GET /v3/wallets/{family}/{address}` once, then `GET /v3/traders/{traderId}/posts?platform=pump` | the wallet lookup once, then 10 for a page of up to 100 |\n| `GET /v2/token/{address}` | 100; 200 not found | `GET /v3/tokens/{network}/{address}` | 100; 100 not found |\n| `GET /v2/leaderboard/traders`, `GET /v2/leaderboard/clans` | 500 | `GET /v3/leaderboards/fomo/traders`, `GET /v3/leaderboards/fomo/clans` | 500; 200 without a capture |\n| `GET /v2/leaderboard/tokens/most-held`, `GET /v2/leaderboard/tokens/trending`, `GET /v2/leaderboard/tokens/graduated` | 10 | `GET /v3/leaderboards/fomo/tokens_most_held`, `GET /v3/leaderboards/fomo/tokens_trending`, `GET /v3/leaderboards/fomo/tokens_graduated` | 10 |\n| `GET /v2/pump/leaderboard/traders` | 10 | `GET /v3/leaderboards/pump/traders` | 10 |\n| `GET /v2/leaderboard/traders-fomoscan` | 500 | `GET /v3/rankings/traders_net_flow_<window>` | 500; 200 without a snapshot |\n| `GET /v2/me` | free | `GET /v3/me` | free |\n| `GET /v2/ws`, `GET /v2/ws/pump` | 20,000 per minute per socket | `wss://stream.fomoscan.sh/v3` | 20,000 per started minute per connection |\n| `POST /v2/user/handle/{handle}/reveal`, `GET /v2/stats/…` | used by the v2 MCP server | not in v3 yet |  |\n| `GET /feed/trades` | not metered | `GET /v3/trades` | 200 per started 20 rows of `limit`, plus 100 and a reveal per trader the page shows |\n| `GET /feed/trader/{handle}` | not metered | `GET /v3/traders/lookup?handle=`, then `GET /v3/traders/{traderId}`, `GET /v3/traders/{traderId}/wallets` and `GET /v3/traders/{traderId}/trades` | each at its own price |\n| `GET /get-followers/{handle}`, `GET /get-following/{handle}` | not metered | `GET /v3/traders/{traderId}/followers`, `GET /v3/traders/{traderId}/following` | 200 per started 20 rows of `limit` |\n| `GET /get-user/{handle}`, `GET /get-user-by-id/{id}`, `GET /search` | not metered | `GET /v3/traders/lookup?handle=` for a whole handle; nothing for an id or a prefix | 100; 200 with no match |\n\nNew in v3, with no v2 route:\n\n- `GET /v3/traders/{traderId}`: 100; 200 for an unknown id.\n- `GET /v3/leaderboards`: free.\n- `GET /v3/rankings`: free.\n- `GET /v3/capabilities`: free.\n- `GET /v3/traders/{traderId}/trades`: 200 per started 20 rows of `limit`, plus 100 and a reveal per trader the page shows.\n- `GET /v3/wallets/{family}/{address}/trades`: 200 per started 20 rows of `limit`.\n\n### Ids and lookups\n\n- v3 never returns a platform's own id, such as v2's `id` and `authorId`. Every object carries our id, in the forms the Ids section at the top lists.\n- 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:\n\n```bash\ncurl -s -H \"Authorization: Bearer $KEY\" \"https://api.fomoscan.sh/v3/traders/lookup?handle=tradername\"\ncurl -s -H \"Authorization: Bearer $KEY\" \"https://api.fomoscan.sh/v3/traders/tdr_01jbst8pvcfp79y0938nkrkayd/wallets\"\n```\n\n```json\n{ \"items\": [ { \"kind\": \"trader\", \"id\": \"tdr_01jbst8pvcfp79y0938nkrkayd\", \"canonical\": { … }, \"sources\": { … } } ], \"hasMore\": false, \"nextCursor\": null }\n```\n\n- 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.\n- 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.\n- 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.\n- 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.\n\n### Answers\n\n- Every object is an envelope (`kind`, `id`, `canonical`, `sources`); the Objects section at the top explains it. PnL, boards, rankings and the key are documents that hold envelopes.\n- 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.\n- 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.\n- 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).\n- 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.\n- v2 ignored a query parameter it did not know. v3 answers 400 `INVALID_ARGUMENT`. `HEAD` answers 404.\n\n### Errors\n\nv2: `{ \"error\": { \"code\", \"message\", \"retryAfter\" } }`. v3: `{ \"error\": { \"type\", \"code\", \"message\", \"requestId\" } }`, with `X-Request-Id` on every response and `Retry-After` on 429 and 503.\n\n| v2 | v3 |\n| --- | --- |\n| 400 `VALIDATION_ERROR` | `INVALID_ARGUMENT` |\n| 401 `UNAUTHORIZED` | `UNAUTHENTICATED` |\n| 402 `QUOTA_EXCEEDED`, `REVEAL_LIMIT_REACHED` | the same codes |\n| 403 `FORBIDDEN_SCOPE`, `FREE_TIER_DISABLED`, `SAMPLE_SET_ONLY`, `FORBIDDEN` | `PERMISSION_DENIED` |\n| 403 `WEBSOCKET_PLAN_REQUIRED` | `PLAN_REQUIRED` |\n| 404 `NOT_FOUND` | `NOT_FOUND` |\n| 429 `RATE_LIMITED`, `retryAfter` in the body | `RATE_LIMITED`, `Retry-After` header |\n| 500 `INTERNAL_ERROR` | `INTERNAL` |\n| 503 `OVERLOADED`, `B2B_DISABLED`, `DATA_UNAVAILABLE`; 504 `TIMEOUT` | 503 `OVERLOADED`, `Retry-After` header |\n| 202 `{ \"pending\": true }` from resolve | none |\n\n### Fields\n\n#### User record\n\n- `id` (the platform user id): none. Use the trader `id` (`tdr_`).\n- `handle`, `name`, `bio`, `profilePicture`: `handle`, `name`, `bio`, `avatarUrl` of the `profile` block in `sources.<platform>`. `canonical.display` repeats the newest of them.\n- `twitter` (a URL): `profile.xHandle`, the handle without `@`.\n- `followers`, `following`: the `followGraph` block.\n- `solanaAddress`, `evmAddress`: `GET /v3/traders/{traderId}/wallets`, wallet envelopes with `canonical.family`, `canonical.address` and the `tier` of each owner.\n- Handle suggestions: a missed lookup answers `suggestions`; `match=closest` answers the closest trader. Prefixes match through suggestions; there is no `/search`.\n- `walletAvailable`: `canonical.walletAvailable` on `GET /v3/traders/{traderId}` and `GET /v3/traders/lookup`, at no extra price and without a reveal.\n- `banner`, `isPumpUser`, `groupBadges`: none.\n- 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.\n\n#### PnL\n\n- 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`.\n- `status` `no-wallet` is `no_wallet`.\n- `wallet`, `evmWallet`: `wallets`, a list of `wal_` ids, filled only when `status` is `ready`.\n- `handle`, `displayName`, `avatarUrl`, `twitter`, `followers`: none. Read the trader.\n- 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`.\n- `unrealized.unrealizedPnlUsd` and `holdingsUsd` are `unrealized.value` and `holdingsValue`.\n- Per window, `unrealizedPnlUsd` and `totalPnlUsd` are `unrealized` and `total`; `approximate`, `stale` and `nextUpdateAt` keep their v2 names.\n- 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.\n- `all` holds the net flow and rank we compute from our trades. v2 mixed cash flow with whole-wallet figures since 1 January 2025.\n- `window` (new) narrows `windows` to one key at the same price.\n\n#### Posts\n\nTheses, callouts and stream items are one kind, `post`:\n\n- `thesis`: `canonical.body`. `segments`: `canonical.segments`, each `{ \"text\", \"url\" }`.\n- `tokenAddress` and `tokenNetwork`, callout `coinMint` and `chain`: `canonical.token.id` (`tok_<network>_<address>`). `tokenSymbol`, `coinSymbol`: `canonical.token.symbol`.\n- `authorId` and `authorHandle`, callout `wallet` and `userName`: `canonical.author.trader` and `canonical.author.handle`.\n- `fomoCreatedAt`, callout `createdAt`: `canonical.postedAt`. `firstSeenAt` (new) is when we first read the post.\n- `likeCount`, `likes`: `canonical.likeCount`. `commentCount`, `replyCount`, `viewCount`: the `engagement` block.\n- `holdingsUsd`, `tokenAmount`, `authorTradeUsd`, `realizedPnlUsd`, `unrealizedPnlUsd`, `pnl`, `closedAt`, callout `position`: the `position` block (`value`, `quantity`, `invested`, `realizedPnl`, `unrealizedPnl`, `totalPnl`, `closed`, `closedAt`).\n- `calledOutAtMcap`, `multiple`, `maxMultiplier`, `mediaUrl`: the `callPerformance` block (`marketCapAtCall`, `multiple`, `maxMultiple`, `mediaUrl`).\n- Thesis `priceUsdAtPost` and `marketCapAtPost`: `callPerformance.priceAtCall` and `callPerformance.marketCapAtCall`.\n- `thesisHash`: none. Key on `id`.\n\n#### Tokens\n\n- `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`.\n\n#### Boards and rankings\n\n- `/v2/leaderboard/<board>` and `/v2/pump/leaderboard/traders` are `/v3/leaderboards/{platform}/{board}`; `GET /v3/leaderboards` lists every board with its windows.\n- `window` stays. `period` `daily`, `weekly`, `monthly` is `window` `24h`, `7d`, `30d`. `at` takes RFC3339 in place of epoch milliseconds.\n- `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`.\n- `/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.\n\n#### Account\n\n- `GET /v3/me` moves `entitlement` and `usage` into `api`: `monthlyUnits`, `additionalUnits`, `unitsUsed`, `unitsRemaining`, `ratePerMinute`, `monthlyReveals`, `revealsUsed`, `revealsRemaining`, `unmetered`. Stream minutes count in `api.unitsUsed`.\n\n### Limits and refusals\n\n|  | v2 | v3 |\n| --- | --- | --- |\n| Per key | `ratePerMinute`, a fixed minute | the same `ratePerMinute` |\n| Per address, before the key | 2,400 per minute | 2,400 per minute |\n| Per address and route, per minute | 2,000 by default; 600 on boards; 120 on `/v2/me` and batches; 10 on resolve | 2,000 by default; 120 on `POST /v3/traders/pnl`, `GET /v3/me` and `POST /v3/wallets/pnl`; 600 on `GET /v3/leaderboards/{platform}/{board}` and `GET /v3/rankings/{key}` |\n| Headers | `x-ratelimit-*` for the route limit | `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` for the key |\n| 429 | `retryAfter` in the body | `Retry-After` header |\n| Load | 503 `OVERLOADED` | 503 `OVERLOADED` with `Retry-After: 1` past 30 requests in flight on one API instance, before the key is checked |\n| Requests in flight per key | none | 429 `RATE_LIMITED` with `Retry-After: 1` past 15 requests in flight for one key and its child keys on one API instance |\n\n- A 429 or a 503 costs nothing. Retry after the seconds in `Retry-After`.\n- A reveal that waits more than 2 seconds on the reveal lock of the key answers 429 with `Retry-After: 1`, as on v2.\n\n### Stream\n\n|  | v2 | v3 |\n| --- | --- | --- |\n| URL | `wss://api.fomoscan.sh/v2/ws` (theses), `wss://api.fomoscan.sh/v2/ws/pump` (callouts) | `wss://stream.fomoscan.sh/v3`, every platform on one socket |\n| Key | `Authorization: Bearer` or `X-Api-Key` on the upgrade | the same; a refusal is an HTTP status: 401, 402, 403 `PERMISSION_DENIED` (scope), 403 `PLAN_REQUIRED`, 429 |\n| Subscribe | `{ \"type\": \"subscribe\", \"subscription\": { \"type\": \"all\" } }` | `{ \"type\": \"subscribe\", \"topic\": \"posts\" }` |\n| Tokens | `\"subscription\": { \"type\": \"tokens\", \"tokens\": [\"<address>\"] }`, up to 50 | `\"tokens\": [\"tok_solana_<mint>\"]`, up to 50 |\n| Platforms | one socket per feed | `\"platforms\": [ … ]`, every platform when left out |\n| Acknowledgement | `replaced`, then `subscription` | one `subscribed` frame that carries `subscription` and `replaced` |\n| Items | `thesis` with `data`, `pump_callout` with `callout` | `post` with `cursor` and `item`, the envelope `GET /v3/posts` returns |\n| Errors | `error` with a string | `error` with `{ \"type\", \"code\", \"message\", \"requestId\" }` |\n| Replay | none | `\"since\": \"s_…\"` replays the last 5 minutes, then `replay_done` |\n| Heartbeat | ping every 30 s, close 1011 after 90 s of silence | the same |\n| Subscribe rate | no limit | 10 `subscribe` or `unsubscribe` frames per 60 s |\n| Price | 20,000 credits per minute, per socket | 20,000 credits per started minute per connection, charged on connect and every 60 s, subscribed or not |\n\n```json\n{\"type\":\"subscribe\",\"topic\":\"posts\",\"platforms\":[\"fomo\",\"pump\"],\"tokens\":[\"tok_solana_<mint>\"],\"since\":\"s_…\"}\n```\n\n- 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.\n- One socket carries every platform, so a client of both v2 sockets pays one minute where v2 charged two.\n- A v2 frame sent to v3 answers an `INVALID_ARGUMENT` error frame and changes nothing.\n- v3 sends each post once, when it first becomes visible to us. `postedAt` gives its age.\n- Reconnect with `since` set to the last `cursor` you handled. The WebSocket section at the end of this page holds every frame, error code and a reconnect recipe.\n\n### Not in v3 yet\n\n- Lookup by a v2 `id`: `GET /v2/user/id/{id}`, `GET /v2/user/id/{id}/profile`, and author feeds keyed on that id.\n- 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.\n- Author name, author avatar and token image on each post (`authorName`, `authorAvatarUrl`, `tokenImageUrl`, callout `profileImage`). Read the author and the token by id.\n- Percentages and cost basis of the author's position: `percentageRealizedPnl`, `percentageUnrealizedPnl`, callout `pnlPercentage`, `avgEntryPriceUsd`, `avgEntryMcapUsd`, `costBasisAmount`, `amountBought`.\n- Wallet holdings with cost basis from the buy history: `GET /v2/pump/user/wallet/{wallet}/holdings`, `POST /v2/pump/user/wallets/holdings`.\n- Live resolve: `POST /v2/user/handle/{handle}/resolve` and its 202. v3 answers from stored data.\n- The stats and open holdings of the `GET /feed/trader/{handle}` card.\n- MCP: the v2 MCP server, its `GET /v2/stats/…` reads and `POST /v2/user/handle/{handle}/reveal`."},"servers":[{"url":"https://api.fomoscan.sh","description":"The API host"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"paths":{"/v3/traders/{traderId}":{"get":{"operationId":"getTrader","summary":"Read one trader","description":"The trader behind this id. `canonical` says what to show and which platforms the trader is on; `sources` holds the blocks of each platform (`profile`, `followGraph`, `tradingStats`).\n\n- An id merged into another trader answers 200 with the trader that absorbed it: `id` differs from the one you sent, and `canonical.mergedFrom` lists yours. Store the new `id`.\n- Each field of `canonical.display` comes from the newest `profile` block (by `observedAt`) that has it, so a newer profile with an empty field never blanks a value another platform shows.\n- When the trader holds two accounts on one platform, each block comes from the account whose block is newest.\n- The envelope carries no wallets: `GET /v3/traders/{traderId}/wallets` lists them.\n- `canonical.walletAvailable` is `true` when `GET /v3/traders/{traderId}/wallets` lists at least one wallet for the trader and `false` when it lists none, so you know before you pay its reveal whether an address will come back. It never carries the address and takes no reveal.\n\n## Price\n\nThe price depends on the answer.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| The trader exists. | 100 | 0 |\n| 404: no trader has this id. | 200 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 100 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Traders"],"x-operation":1,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraderEnvelope"},"example":{"kind":"trader","id":"tdr_01jbst8pvcfp79y0938nkrkayd","canonical":{"display":{"handle":"nightowl","name":"Night Owl","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp"},"platforms":["fomo","pump"],"mergedFrom":["tdr_01jbst8zcefy8b28t5cy4tqkff"],"firstSeenAt":"2025-03-14T16:20:05.412Z","walletAvailable":true},"sources":{"fomo":{"profile":{"handle":"nightowl","name":"Night Owl","bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":null,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":18450,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"},"tradingStats":{"swapCount":1840,"tradeCount":977,"volume":{"value":"482113250000","decimals":6,"currency":"USD"},"avgHoldSeconds":15120.5,"observedAt":"2026-11-01T08:42:10.250Z"}},"pump":{"profile":{"handle":"nightowl","name":null,"bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":false,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":2210,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"}}}}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/lookup":{"get":{"operationId":"lookupTraders","summary":"Find traders by handle","description":"The traders whose handle on a platform matches `handle`. Look a trader up once, then store our id and use it from then on.\n\n- The match covers the handle each account holds now and every handle it held in the last 30 days, so a renamed account still answers.\n- Order: traders whose current handle matches first, then traders who held it in the last 30 days. Inside each group, the newest profile `observedAt` first, then trader id.\n- One handle can match several traders, for example two people with the same handle on two platforms. Check `canonical.platforms` and `sources` before you pick one.\n- `canonical.walletAvailable` is `true` when `GET /v3/traders/{traderId}/wallets` lists at least one wallet for the trader and `false` when it lists none, so you know before you pay its reveal whether an address will come back. It never carries the address and takes no reveal.\n- No match answers 200 with an empty page. This operation never answers 404.\n- The first page of a miss carries `suggestions`: up to 5 traders whose handle or name looks like `handle` (a typo, a repeated letter, spaces) or whose handle starts with it, closest first, with a small lift for followed traders. Each names the platform, handle and name of the account that matched.\n- With `match=closest` that miss answers with the first suggestion as the only item and `match: \"closest\"`. Check it before you store the id: a close handle is a guess, not proof.\n- Paged with `cursor` and `limit` (default 50, maximum 200).\n\n## Price\n\nThe price depends on the answer.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| At least one trader holds or held the handle. | 100 | 0 |\n| None does, and `match=closest` answers with the first suggestion. | 100 | 0 |\n| None does, and no trader answers: an empty page with `suggestions`. | 200 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 100 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Traders"],"x-operation":2,"parameters":[{"name":"handle","in":"query","description":"The handle to find, 1 to 64 characters. A leading `@` is dropped, and letter case does not count.","required":true,"schema":{"type":"string","minLength":1,"maxLength":65}},{"name":"platform","in":"query","description":"Only accounts on this platform, for the matches and the suggestions. Leave it out for every platform.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"match","in":"query","description":"`exact` (the default): only traders that hold the handle or held it in the last 30 days. `closest`: when none does, answer with the first of `suggestions` instead of an empty page.","required":false,"schema":{"default":"exact","type":"string","enum":["exact","closest"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 200. 50 when left out.","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraderLookup"},"example":{"items":[{"kind":"trader","id":"tdr_01jbst8pvcfp79y0938nkrkayd","canonical":{"display":{"handle":"nightowl","name":"Night Owl","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp"},"platforms":["fomo","pump"],"mergedFrom":["tdr_01jbst8zcefy8b28t5cy4tqkff"],"firstSeenAt":"2025-03-14T16:20:05.412Z","walletAvailable":true},"sources":{"fomo":{"profile":{"handle":"nightowl","name":"Night Owl","bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":null,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":18450,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"},"tradingStats":{"swapCount":1840,"tradeCount":977,"volume":{"value":"482113250000","decimals":6,"currency":"USD"},"avgHoldSeconds":15120.5,"observedAt":"2026-11-01T08:42:10.250Z"}},"pump":{"profile":{"handle":"nightowl","name":null,"bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":false,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":2210,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"}}}}],"hasMore":false,"nextCursor":null,"match":"closest","suggestions":[{"trader":{"kind":"trader","id":"tdr_01jbst8pvcfp79y0938nkrkayd","canonical":{"display":{"handle":"nightowl","name":"Night Owl","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp"},"platforms":["fomo","pump"],"mergedFrom":["tdr_01jbst8zcefy8b28t5cy4tqkff"],"firstSeenAt":"2025-03-14T16:20:05.412Z"},"sources":{"fomo":{"profile":{"handle":"nightowl","name":"Night Owl","bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":null,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":18450,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"},"tradingStats":{"swapCount":1840,"tradeCount":977,"volume":{"value":"482113250000","decimals":6,"currency":"USD"},"avgHoldSeconds":15120.5,"observedAt":"2026-11-01T08:42:10.250Z"}},"pump":{"profile":{"handle":"nightowl","name":null,"bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":false,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":2210,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"}}}},"platform":"fomo","handle":"nightowl","name":"Night Owl"}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `handle` is empty once the `@` is dropped, or longer than 64 characters.\n- `match` is neither `exact` nor `closest`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/wallets/{family}/{address}":{"get":{"operationId":"getWallet","summary":"Read one wallet and who owns it","description":"One wallet and the traders linked to it as owners. Each owner carries a `tier`, how sure we are, and the links behind it.\n\n- An EVM address matches in any letter case and comes back lowercase.\n- Owners: strongest tier first, then the earliest `firstVerifiedAt`, then trader id.\n- A tier is capped at `weak` when two or more traders hold the wallet, or the wallet carries a `custodial` or `exchange` label.\n- A wallet we know without an owner answers 200 with an empty `owners` list.\n- A link read from the wallet a platform profile shows never counts; every other active link does, at its tier.\n\n## Price\n\nThe price depends on the answer. The Reveals column says when a reveal is taken.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| An owner holds a tier other than `account`. | 30,000 | 1 |\n| Every owner holds the tier `account`. | 10 | 0 |\n| The wallet has no owner (200 with the envelope), or we never saw it (404). | 200 | 0 |\n\nReveals count against a key with a monthly reveal cap. When the answer needs more reveals than the key has left, the call is refused before any credit is taken: 402 `REVEAL_LIMIT_REACHED`, or 403 `PERMISSION_DENIED` for a key on a free plan without reveals.\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 10 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Wallets"],"x-operation":3,"parameters":[{"name":"family","in":"path","description":"The address family: `svm` for Solana, `evm` for EVM networks.","required":true,"schema":{"type":"string","enum":["svm","evm"]}},{"name":"address","in":"path","description":"The wallet address. An EVM address matches in any letter case.","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletEnvelope"},"example":{"kind":"wallet","id":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","canonical":{"family":"svm","address":"9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","firstSeenAt":"2025-03-14T16:20:05.412Z","lastSeenAt":"2026-11-01T08:57:12.000Z","labels":[],"owners":[{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","tier":"proven","links":[{"platform":"fomo","method":"svm_dual_proof","firstVerifiedAt":"2025-06-02T10:41:17.006Z","lastVerifiedAt":"2026-10-29T03:12:55.810Z"}]}]},"sources":{}}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `address` is not a valid address of `family`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.\n\n`REVEAL_LIMIT_REACHED`: the answer needs a reveal and the key has used every reveal this month. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.\n\n`PERMISSION_DENIED` also when a key on a free plan without reveals asks for an answer that needs one. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. We never saw this wallet.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/{traderId}/wallets":{"get":{"operationId":"listTraderWallets","summary":"List the wallets of a trader","description":"The wallets of a trader, each as a wallet envelope whose `owners` lists this trader alone.\n\n- The list covers every account of the trader on every platform, merges included.\n- Order: tier strongest first, then the earliest `firstVerifiedAt`, then family and address.\n- A link read from the wallet a platform profile shows never counts; every other active link does, at its tier.\n- A trader without wallets answers 200 with an empty page.\n- Paged with `cursor` and `limit` (default 50, maximum 200).\n\n## Price\n\nThe price depends on the answer. The Reveals column says when a reveal is taken.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| The page lists at least one wallet. | 100 | 1 |\n| The page lists no wallet. | 100 | 0 |\n| 404: no trader has this id. | 200 | 0 |\n\nReveals count against a key with a monthly reveal cap. When the answer needs more reveals than the key has left, the call is refused before any credit is taken: 402 `REVEAL_LIMIT_REACHED`, or 403 `PERMISSION_DENIED` for a key on a free plan without reveals.\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 100 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Traders"],"x-operation":4,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 200. 50 when left out.","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletCollection"},"example":{"items":[{"kind":"wallet","id":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","canonical":{"family":"svm","address":"9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","firstSeenAt":"2025-03-14T16:20:05.412Z","lastSeenAt":"2026-11-01T08:57:12.000Z","labels":[],"owners":[{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","tier":"proven","links":[{"platform":"fomo","method":"svm_dual_proof","firstVerifiedAt":"2025-06-02T10:41:17.006Z","lastVerifiedAt":"2026-10-29T03:12:55.810Z"}]}]},"sources":{}},{"kind":"wallet","id":"wal_evm_0x52908400098527886e0f7030069857d2e4169ee7","canonical":{"family":"evm","address":"0x52908400098527886e0f7030069857d2e4169ee7","firstSeenAt":"2025-09-30T07:15:00.000Z","lastSeenAt":"2026-10-31T19:04:27.000Z","labels":[],"owners":[{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","tier":"partial","links":[{"platform":"fomo","method":"evm_single_relay","firstVerifiedAt":"2025-10-01T11:20:31.442Z","lastVerifiedAt":"2026-10-31T19:05:02.118Z"}]}]},"sources":{}}],"hasMore":false,"nextCursor":null}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.\n\n`REVEAL_LIMIT_REACHED`: the answer needs a reveal and the key has used every reveal this month. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.\n\n`PERMISSION_DENIED` also when a key on a free plan without reveals asks for an answer that needs one. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/{traderId}/pnl":{"get":{"operationId":"getTraderPnl","summary":"Read a trader's PnL across whole wallets","description":"A trader's profit and loss over the wallets we verified for them. `24h`, `7d`, `30d` and `unrealized` come from our data provider and cover the whole wallets on every venue; `all` is ours, computed from the ranking of net flow.\n\nRead `status` first:\n\n| `status` | Meaning | What to do |\n| --- | --- | --- |\n| `ready` | The figures are present, and `wallets` lists the wallets they cover. | Use them. When `stale` is `true`, a call after `nextUpdateAt` can carry newer figures. |\n| `pending` | No reading exists yet, and a read is running. Every provider value is `null`. | Call again after `retryAfterSeconds` (30). |\n| `failed` | The last read of our data provider failed. | Call again after `retryAfterSeconds`. |\n| `no_wallet` | The trader holds no wallet that passes the wallet rule below. | Nothing to wait for. |\n| `unavailable` | Provider reads are switched off, or this month's provider budget is spent and we hold no reading of the last 7 days. | Call again next month or ask us; `all` can still hold figures. |\n\n- Wallet rule: verified links only (tiers `proven`, `account`, `partial`), one wallet per address family, and none that another trader also holds. Per family the strongest tier wins, then the newest `lastVerifiedAt`.\n- `wallets` is empty for every status but `ready`.\n- When no fresh reading exists, the call asks our data provider for one and waits for it. A read that misses the wait finishes and serves your next call.\n- A call that cannot read a figure again serves the stored one, at most 7 days old, with `stale` `true`. `nextUpdateAt` is when the first provider figure falls due to be read again.\n- `window` keeps one key in `windows`. `status` stays the same.\n- Every window carries `realized`, `unrealized` and `total` (`realized` plus `unrealized`). On `24h`, `7d` and `30d`, `unrealized` covers the open positions last traded inside the window, on UTC calendar days.\n- When our data provider fails to read a window, the call counts it from per-token totals of the positions and marks it `approximate`; the next reading replaces it. When that fails too, the window waits an hour before it is read again.\n- `all` takes `netFlow`, `volume`, `tradeCount`, `returnPct` and `rank` from the ranking `traders_net_flow_all`; its `realized`, `unrealized` and `total` are `null`. It is `null` when that ranking does not list the trader.\n\n## Price\n\nThe price depends on the answer. The Reveals column says when a reveal is taken.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `status` is `ready`. | 30,000 | 1 |\n| Any other `status`, or 404. | 200 | 0 |\n\nReveals count against a key with a monthly reveal cap. When the answer needs more reveals than the key has left, the call is refused before any credit is taken: 402 `REVEAL_LIMIT_REACHED`, or 403 `PERMISSION_DENIED` for a key on a free plan without reveals.\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.\n- A read of our data provider runs up to 8 seconds inside the call. Past that the call answers with what we hold, and the read finishes for your next call.","tags":["Traders"],"x-operation":5,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"window","in":"query","description":"One window: `24h`, `7d`, `30d` or `all`. Leave it out for all four. `status` stays the same either way.","required":false,"schema":{"type":"string","enum":["24h","7d","30d","all"]}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PnlDocument"},"example":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","status":"ready","retryAfterSeconds":null,"wallets":["wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","wal_evm_0x52908400098527886e0f7030069857d2e4169ee7"],"windows":{"24h":{"origin":"provider","status":"ready","realized":{"value":"1250500000","decimals":6,"currency":"USD"},"unrealized":{"value":"412150000","decimals":6,"currency":"USD"},"total":{"value":"1662650000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"18050500000","decimals":6,"currency":"USD"},"buyVolume":{"value":"8400000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"9650500000","decimals":6,"currency":"USD"},"returnPct":14.88690476,"tradeCount":21,"buys":12,"sells":9,"tokensTraded":6,"winningTokens":4,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false},"7d":{"origin":"provider","status":"ready","realized":{"value":"-312750000","decimals":6,"currency":"USD"},"unrealized":{"value":"1506900000","decimals":6,"currency":"USD"},"total":{"value":"1194150000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"80160000000","decimals":6,"currency":"USD"},"buyVolume":{"value":"41200000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"38960000000","decimals":6,"currency":"USD"},"returnPct":-0.79635371,"tradeCount":105,"buys":58,"sells":47,"tokensTraded":19,"winningTokens":8,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false},"30d":{"origin":"provider","status":"ready","realized":{"value":"9884200000","decimals":6,"currency":"USD"},"unrealized":{"value":"2101300000","decimals":6,"currency":"USD"},"total":{"value":"11985500000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"312410000000","decimals":6,"currency":"USD"},"buyVolume":{"value":"152300000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"160110000000","decimals":6,"currency":"USD"},"returnPct":6.57956223,"tradeCount":412,"buys":214,"sells":198,"tokensTraded":61,"winningTokens":27,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false},"all":{"origin":"computed","status":"ready","realized":null,"unrealized":null,"total":null,"unpricedProceeds":null,"netFlow":{"value":"48210330000","decimals":6,"currency":"USD"},"volume":{"value":"1290446800000","decimals":6,"currency":"USD"},"buyVolume":null,"sellVolume":null,"returnPct":7.76186035,"tradeCount":3105,"buys":null,"sells":null,"tokensTraded":null,"winningTokens":null,"rank":{"position":37,"of":18204,"ranking":"traders_net_flow_all"},"asOf":"2026-11-01T08:40:00.000Z","approximate":false}},"unrealized":{"origin":"provider","value":{"value":"2318400000","decimals":6,"currency":"USD"},"holdingsValue":{"value":"11904650000","decimals":6,"currency":"USD"},"positions":9,"excludedPositions":2,"asOf":"2026-11-01T08:55:00.000Z"},"asOf":"2026-11-01T08:55:00.000Z","nextUpdateAt":"2026-11-01T11:55:00.000Z","stale":false}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.\n\n`REVEAL_LIMIT_REACHED`: the answer needs a reveal and the key has used every reveal this month. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.\n\n`PERMISSION_DENIED` also when a key on a free plan without reveals asks for an answer that needs one. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/pnl":{"post":{"operationId":"bulkTraderPnl","summary":"Read the PnL of up to 100 traders","description":"The PnL of up to 100 traders in one call. `items` follows the order of `traderIds`, one item per distinct id.\n\n- Each item holds the id as you sent it, `found`, and the document `GET /v3/traders/{traderId}/pnl` returns, or `null` when no trader has the id.\n- Two ids that resolve to one trader after merges are two items.\n- Every rule of `GET /v3/traders/{traderId}/pnl` applies per item: `status`, `retryAfterSeconds`, `wallets`, `window`.\n- An unknown id is an item with `found: false`. This operation never answers 404.\n\n## Price\n\n**Per item**: 30,000 credits and one reveal for each item whose `status` is `ready`, 200 credits for every other item. Before any work the whole batch is refused when the balance holds less than 200 credits per item (402 `QUOTA_EXCEEDED`), or the key has fewer reveals left this month than items, whatever their status turns out to be.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| Each item whose `status` is `ready`. | 30,000 | 1 |\n| Each item with another `status`, or not found. | 200 | 0 |\n| 100 ids, 60 of them `ready`. | 1,808,000 | 60 |\n\nReveals count against a key with a monthly reveal cap. When the answer needs more reveals than the key has left, the call is refused before any credit is taken: 402 `REVEAL_LIMIT_REACHED`, or 403 `PERMISSION_DENIED` for a key on a free plan without reveals.\n\n## Limits\n\n- 120 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.\n- A read of our data provider runs up to 8 seconds inside the call. Past that the call answers with what we hold, and the read finishes for your next call.","tags":["Traders"],"x-operation":6,"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PnlBulk"},"example":{"items":[{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","found":true,"pnl":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","status":"ready","retryAfterSeconds":null,"wallets":["wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","wal_evm_0x52908400098527886e0f7030069857d2e4169ee7"],"windows":{"7d":{"origin":"provider","status":"ready","realized":{"value":"-312750000","decimals":6,"currency":"USD"},"unrealized":{"value":"1506900000","decimals":6,"currency":"USD"},"total":{"value":"1194150000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"80160000000","decimals":6,"currency":"USD"},"buyVolume":{"value":"41200000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"38960000000","decimals":6,"currency":"USD"},"returnPct":-0.79635371,"tradeCount":105,"buys":58,"sells":47,"tokensTraded":19,"winningTokens":8,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false}},"unrealized":{"origin":"provider","value":{"value":"2318400000","decimals":6,"currency":"USD"},"holdingsValue":{"value":"11904650000","decimals":6,"currency":"USD"},"positions":9,"excludedPositions":2,"asOf":"2026-11-01T08:55:00.000Z"},"asOf":"2026-11-01T08:55:00.000Z","nextUpdateAt":"2026-11-01T11:55:00.000Z","stale":false}},{"trader":"tdr_01jbst8v3xft7t04hmasw9nf6y","found":true,"pnl":{"trader":"tdr_01jbst8v3xft7t04hmasw9nf6y","status":"pending","retryAfterSeconds":30,"wallets":[],"windows":{"7d":{"origin":"provider","status":"pending","realized":null,"unrealized":null,"total":null,"unpricedProceeds":null,"netFlow":null,"volume":null,"buyVolume":null,"sellVolume":null,"returnPct":null,"tradeCount":null,"buys":null,"sells":null,"tokensTraded":null,"winningTokens":null,"rank":null,"asOf":null,"approximate":false}},"unrealized":null,"asOf":null,"nextUpdateAt":null,"stale":false}},{"trader":"tdr_01jbsta48he8h86ct48hanask6","found":false,"pnl":null}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `traderIds` is empty, holds more than 100 ids, or holds a value that is not a trader id.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.\n\n`REVEAL_LIMIT_REACHED`: the answer needs a reveal and the key has used every reveal this month. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.\n\n`PERMISSION_DENIED` also when a key on a free plan without reveals asks for an answer that needs one. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"traderIds":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"},"description":"1 to 100 trader ids. A repeated id counts once."},"window":{"description":"One window: `24h`, `7d`, `30d` or `all`. Leave it out for all four. `status` stays the same either way.","type":"string","enum":["24h","7d","30d","all"]}},"required":["traderIds"],"additionalProperties":false}}}}}},"/v3/posts":{"get":{"operationId":"listPosts","summary":"Read the post feed","description":"The newest posts of every platform, newest first: the REST side of the stream, with the same post envelopes, for backfill and for gaps.\n\n- Order: post time newest first, then post id. A page boundary inside a tie neither drops nor repeats a post.\n- Each post carries its blocks under its own platform's key in `sources`.\n- Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, on every call. A short or empty page costs the same as a full one.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 1. | 200 | 0 |\n| `limit` 20 (the default). | 200 | 0 |\n| `limit` 50. | 600 | 0 |\n| `limit` 100 (the maximum). | 1,000 | 0 |\n| `platform=pump`, any `limit`. | 10 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 10 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Posts"],"x-operation":9,"parameters":[{"name":"platform","in":"query","description":"Only posts from this platform. Leave it out for every platform.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCollection"},"example":{"items":[{"kind":"post","id":"pst_01jbsta8h2ecsr8h2nank6cxvq","canonical":{"platform":"fomo","author":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl"},"token":{"id":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","symbol":"BONK"},"body":"Adding here. Chart at https://example.com/c/bonk","segments":[{"text":"Adding here. Chart at ","url":null},{"text":"example.com/c/bonk","url":"https://example.com/c/bonk"}],"likeCount":41,"postedAt":"2026-11-01T08:58:31.000Z","firstSeenAt":"2026-11-01T08:58:33.184Z","revision":0},"sources":{"fomo":{"position":{"quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"value":{"value":"77276000","decimals":6,"currency":"USD"},"invested":{"value":"60000000","decimals":6,"currency":"USD"},"realizedPnl":{"value":"0","decimals":6,"currency":"USD"},"unrealizedPnl":{"value":"17276000","decimals":6,"currency":"USD"},"totalPnl":{"value":"17276000","decimals":6,"currency":"USD"},"closed":false,"closedAt":null,"observedAt":"2026-11-01T08:58:33.184Z"},"callPerformance":{"marketCapAtCall":{"value":"1290000000000000","decimals":6,"currency":"USD"},"priceAtCall":{"value":"15650000000000","decimals":18,"currency":"USD"},"multiple":null,"maxMultiple":null,"maxMultipleAt":null,"mediaUrl":null,"quotedPost":null,"observedAt":"2026-11-01T08:58:33.184Z"}}}},{"kind":"post","id":"pst_01jbstacskeh28anb6csvqf248","canonical":{"platform":"pump","author":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl"},"token":{"id":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","symbol":"BONK"},"body":"Adding here. Chart at https://example.com/c/bonk","segments":[{"text":"Adding here. Chart at ","url":null},{"text":"example.com/c/bonk","url":"https://example.com/c/bonk"}],"likeCount":41,"postedAt":"2026-11-01T08:51:12.000Z","firstSeenAt":"2026-11-01T08:58:33.184Z","revision":0},"sources":{"pump":{"position":{"quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"value":{"value":"77276000","decimals":6,"currency":"USD"},"invested":{"value":"60000000","decimals":6,"currency":"USD"},"realizedPnl":{"value":"0","decimals":6,"currency":"USD"},"unrealizedPnl":null,"totalPnl":{"value":"17276000","decimals":6,"currency":"USD"},"closed":false,"closedAt":null,"observedAt":"2026-11-01T08:58:33.184Z"},"engagement":{"commentCount":14,"replyCount":6,"repostCount":3,"quoteCount":1,"viewCount":2290,"observedAt":"2026-11-01T08:58:33.184Z"},"callPerformance":{"marketCapAtCall":{"value":"1290000000000000","decimals":6,"currency":"USD"},"priceAtCall":{"value":"15650000000000","decimals":18,"currency":"USD"},"multiple":1.1971,"maxMultiple":1.42,"maxMultipleAt":"2026-11-01T08:59:50.000Z","mediaUrl":"https://img.example.com/a/7d3b9f2a6c1e8d4b0a5f3c7e2b9d6a1f.webp","quotedPost":null,"observedAt":"2026-11-01T08:58:33.184Z"}}}}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/tokens/{network}/{address}/posts":{"get":{"operationId":"listTokenPosts","summary":"Read the posts about a token","description":"The posts about one token, newest first.\n\n- `GET /v3/tokens/{network}/{address}` reads the token itself.\n- A token we never saw answers 200 with an empty page, never 404.\n- Order as in `GET /v3/posts`. Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, on every call. A short or empty page costs the same as a full one.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 1. | 200 | 0 |\n| `limit` 20 (the default). | 200 | 0 |\n| `limit` 50. | 600 | 0 |\n| `limit` 100 (the maximum). | 1,000 | 0 |\n| `platform=pump`, any `limit`. | 10 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 10 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Posts"],"x-operation":10,"parameters":[{"name":"network","in":"path","description":"The network the token lives on.","required":true,"schema":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"]}},{"name":"address","in":"path","description":"The token address on that network: the mint on Solana.","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"platform","in":"query","description":"Only posts from this platform. Leave it out for every platform.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCollection"},"example":{"items":[{"kind":"post","id":"pst_01jbsta8h2ecsr8h2nank6cxvq","canonical":{"platform":"fomo","author":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl"},"token":{"id":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","symbol":"BONK"},"body":"Adding here. Chart at https://example.com/c/bonk","segments":[{"text":"Adding here. Chart at ","url":null},{"text":"example.com/c/bonk","url":"https://example.com/c/bonk"}],"likeCount":41,"postedAt":"2026-11-01T08:58:31.000Z","firstSeenAt":"2026-11-01T08:58:33.184Z","revision":0},"sources":{"fomo":{"position":{"quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"value":{"value":"77276000","decimals":6,"currency":"USD"},"invested":{"value":"60000000","decimals":6,"currency":"USD"},"realizedPnl":{"value":"0","decimals":6,"currency":"USD"},"unrealizedPnl":{"value":"17276000","decimals":6,"currency":"USD"},"totalPnl":{"value":"17276000","decimals":6,"currency":"USD"},"closed":false,"closedAt":null,"observedAt":"2026-11-01T08:58:33.184Z"},"callPerformance":{"marketCapAtCall":{"value":"1290000000000000","decimals":6,"currency":"USD"},"priceAtCall":{"value":"15650000000000","decimals":18,"currency":"USD"},"multiple":null,"maxMultiple":null,"maxMultipleAt":null,"mediaUrl":null,"quotedPost":null,"observedAt":"2026-11-01T08:58:33.184Z"}}}},{"kind":"post","id":"pst_01jbstacskeh28anb6csvqf248","canonical":{"platform":"pump","author":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl"},"token":{"id":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","symbol":"BONK"},"body":"Adding here. Chart at https://example.com/c/bonk","segments":[{"text":"Adding here. Chart at ","url":null},{"text":"example.com/c/bonk","url":"https://example.com/c/bonk"}],"likeCount":41,"postedAt":"2026-11-01T08:51:12.000Z","firstSeenAt":"2026-11-01T08:58:33.184Z","revision":0},"sources":{"pump":{"position":{"quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"value":{"value":"77276000","decimals":6,"currency":"USD"},"invested":{"value":"60000000","decimals":6,"currency":"USD"},"realizedPnl":{"value":"0","decimals":6,"currency":"USD"},"unrealizedPnl":null,"totalPnl":{"value":"17276000","decimals":6,"currency":"USD"},"closed":false,"closedAt":null,"observedAt":"2026-11-01T08:58:33.184Z"},"engagement":{"commentCount":14,"replyCount":6,"repostCount":3,"quoteCount":1,"viewCount":2290,"observedAt":"2026-11-01T08:58:33.184Z"},"callPerformance":{"marketCapAtCall":{"value":"1290000000000000","decimals":6,"currency":"USD"},"priceAtCall":{"value":"15650000000000","decimals":18,"currency":"USD"},"multiple":1.1971,"maxMultiple":1.42,"maxMultipleAt":"2026-11-01T08:59:50.000Z","mediaUrl":"https://img.example.com/a/7d3b9f2a6c1e8d4b0a5f3c7e2b9d6a1f.webp","quotedPost":null,"observedAt":"2026-11-01T08:58:33.184Z"}}}}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `address` is not a valid address on `network`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/{traderId}/posts":{"get":{"operationId":"listTraderPosts","summary":"Read the posts of a trader","description":"The posts of one trader over every account the trader holds, newest first.\n\n- `token` keeps the posts about one token.\n- Order as in `GET /v3/posts`. Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, on every call. A short or empty page costs the same as a full one.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 1. | 200 | 0 |\n| `limit` 20 (the default). | 200 | 0 |\n| `limit` 50. | 600 | 0 |\n| `limit` 100 (the maximum). | 1,000 | 0 |\n| `platform=pump`, any `limit`. | 10 | 0 |\n| 404: no trader has this id. Flat as above with `platform=pump`. | 200 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 10 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Posts"],"x-operation":11,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"token","in":"query","description":"Only posts about this token: `tok_<network>_<address>`.","required":false,"schema":{"type":"string","minLength":5,"maxLength":200}},{"name":"platform","in":"query","description":"Only posts from this platform. Leave it out for every platform.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCollection"},"example":{"items":[{"kind":"post","id":"pst_01jbsta8h2ecsr8h2nank6cxvq","canonical":{"platform":"fomo","author":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl"},"token":{"id":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","symbol":"BONK"},"body":"Adding here. Chart at https://example.com/c/bonk","segments":[{"text":"Adding here. Chart at ","url":null},{"text":"example.com/c/bonk","url":"https://example.com/c/bonk"}],"likeCount":41,"postedAt":"2026-11-01T08:58:31.000Z","firstSeenAt":"2026-11-01T08:58:33.184Z","revision":0},"sources":{"fomo":{"position":{"quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"value":{"value":"77276000","decimals":6,"currency":"USD"},"invested":{"value":"60000000","decimals":6,"currency":"USD"},"realizedPnl":{"value":"0","decimals":6,"currency":"USD"},"unrealizedPnl":{"value":"17276000","decimals":6,"currency":"USD"},"totalPnl":{"value":"17276000","decimals":6,"currency":"USD"},"closed":false,"closedAt":null,"observedAt":"2026-11-01T08:58:33.184Z"},"callPerformance":{"marketCapAtCall":{"value":"1290000000000000","decimals":6,"currency":"USD"},"priceAtCall":{"value":"15650000000000","decimals":18,"currency":"USD"},"multiple":null,"maxMultiple":null,"maxMultipleAt":null,"mediaUrl":null,"quotedPost":null,"observedAt":"2026-11-01T08:58:33.184Z"}}}}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `token` is not a token id (`tok_<network>_<address>`).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/tokens/{network}/{address}":{"get":{"operationId":"getToken","summary":"Read one token","description":"One token: network, address, symbol, name, decimals and our copy of its image, with a `market` block per platform that shows the token and the market across trading venues in `canonical.market`.\n\n- `market.price` is USD per whole token with 18 decimals; the other market values are USD with 6. `holders` is a count of wallets, `priceChange24h` a change in percent.\n- Each `market` block is the newest reading we hold from that platform, as of its `observedAt`. A field the platform never fills (`unfilled` in `GET /v3/capabilities`) is always `null`.\n- When no platform shows the token, we read its market from our market data provider during the call, at most once every 5 minutes per token, on Solana, Ethereum, Base, BNB Chain, Robinhood and Arc. A token we had not seen before is answered from that read. The price of the call does not change.\n- Trades (`GET /v3/trades`) carry token quantities only. Read prices here.\n\n## Price\n\nThe price depends on the answer.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| We hold the token, or our market data provider read it within the wait. | 100 | 0 |\n| 404: we never saw the token, and the provider did not know it within the wait. | 100 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 100 credits left gets 402 `QUOTA_EXCEEDED` before any work.\n- When no platform shows the token, a read of our market data provider runs up to 2 seconds inside the call. Past that the call answers with what we hold, and the read finishes for your next call.","tags":["Tokens"],"x-operation":12,"parameters":[{"name":"network","in":"path","description":"The network the token lives on.","required":true,"schema":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"]}},{"name":"address","in":"path","description":"The token address on that network: the mint on Solana.","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenEnvelope"},"example":{"kind":"token","id":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","canonical":{"network":"solana","address":"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","symbol":"BONK","name":"Bonk","decimals":5,"imageUrl":"https://img.example.com/a/4c2e8a1f7b3d9e6a0f5c1b8d2e7a4f3c.webp","firstSeenAt":"2025-01-09T00:12:40.000Z","market":{"price":{"value":"18741200000000","decimals":18,"currency":"USD"},"marketCap":{"value":"1544807000000000","decimals":6,"currency":"USD"},"fdv":{"value":"1663510000000000","decimals":6,"currency":"USD"},"liquidity":{"value":"38102440000000","decimals":6,"currency":"USD"},"volume24h":{"value":"241905300000000","decimals":6,"currency":"USD"},"holders":991027,"priceChange24h":-4.76310482,"observedAt":"2026-11-01T08:55:00.000Z"}},"sources":{"fomo":{"market":{"price":{"value":"18734000000000","decimals":18,"currency":"USD"},"marketCap":{"value":"1544210000000000","decimals":6,"currency":"USD"},"fdv":null,"liquidity":{"value":"21480320000000","decimals":6,"currency":"USD"},"volume24h":{"value":"187340100000000","decimals":6,"currency":"USD"},"holders":982114,"priceChange24h":-4.81726533,"observedAt":"2026-11-01T08:55:00.000Z"}}}}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `address` is not a valid address on `network`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. We never saw this token, and our market data provider did not know it within the wait.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/leaderboards":{"get":{"operationId":"listLeaderboards","summary":"List the leaderboards platforms publish","description":"Every leaderboard a platform publishes that we capture, with its windows and the time of its newest capture.\n\n- Order: platform, then board name.\n- A board whose `latestCapturedAt` is `null` has no capture yet: `GET /v3/leaderboards/{platform}/{board}` answers 404 for it.\n- Paged with `cursor` and `limit` (default 50, maximum 200).\n\n## Price\n\n**Free.** The call needs a key and takes no credits.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| Every call. | 0 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.","tags":["Leaderboards"],"x-operation":13,"parameters":[{"name":"platform","in":"query","description":"Only boards of this platform. Leave it out for every platform.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 200. 50 when left out.","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaderboardCollection"},"example":{"items":[{"platform":"fomo","board":"traders","category":"spot_trading","metric":"pnl","windows":["24h","7d","30d","all"],"defaultWindow":"24h","subjectType":"trader","latestCapturedAt":"2026-11-01T08:30:00.000Z"},{"platform":"fomo","board":"clans","category":"groups","metric":"pnl","windows":["24h","7d","30d"],"defaultWindow":"24h","subjectType":"group","latestCapturedAt":"2026-11-01T08:30:00.000Z"},{"platform":"fomo","board":"tokens_trending","category":"tokens","metric":null,"windows":[],"defaultWindow":null,"subjectType":"token","latestCapturedAt":"2026-11-01T08:30:00.000Z"}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/leaderboards/{platform}/{board}":{"get":{"operationId":"getLeaderboard","summary":"Read one capture of a platform leaderboard","description":"One capture of a platform leaderboard, as the platform showed it: the rank, the subject and the figures the platform publishes for each entry.\n\n- Without `at`, the newest capture of the window. With `at`, the newest capture at or before that time. Older captures thin out to one per hour, then one per day.\n- `window` takes one of the board's `windows`; without it you get `defaultWindow`.\n- A subject is a trader, token or group envelope. A platform account shows as its trader, the object `GET /v3/traders/{traderId}` returns without `canonical.walletAvailable`.\n- `entries` holds the entries of the capture by rank and is not paged. An entry whose subject we cannot read is left out, so `entries` can hold fewer rows than `entryCount`.\n- A figure the platform did not publish is absent from `measures`.\n- These are the platforms' own boards. Our rankings are `GET /v3/rankings/{key}`.\n\n## Price\n\nThe price depends on the answer.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| A capture exists. | 500 | 0 |\n| 404: the board has no capture. | 200 | 0 |\n| The boards `fomo/tokens_trending`, `fomo/tokens_graduated`, `fomo/tokens_most_held` and `pump/traders`, any answer, a 404 included. | 10 | 0 |\n| 404: the board is not in `GET /v3/leaderboards`. | 0 | 0 |\n\n## Limits\n\n- 600 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 10 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Leaderboards"],"x-operation":14,"parameters":[{"name":"platform","in":"path","description":"The platform that publishes the board.","required":true,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"board","in":"path","description":"The board name, as `GET /v3/leaderboards` lists it.","required":true,"schema":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"}},{"name":"window","in":"query","description":"One of the board's `windows`. Leave it out for its `defaultWindow`. A board without windows answers 400 to any value.","required":false,"schema":{"type":"string","enum":["24h","7d","30d","90d","all"]}},{"name":"at","in":"query","description":"An RFC3339 time with `Z` or an offset, not in the future. Answers the newest capture at or before it. Leave it out for the newest capture.","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaderboardDocument"},"example":{"platform":"fomo","board":"traders","category":"spot_trading","metric":"pnl","window":"24h","capturedAt":"2026-11-01T08:30:00.000Z","entryCount":2,"entries":[{"rank":1,"subject":{"kind":"trader","id":"tdr_01jbst8pvcfp79y0938nkrkayd","canonical":{"display":{"handle":"nightowl","name":"Night Owl","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp"},"platforms":["fomo","pump"],"mergedFrom":["tdr_01jbst8zcefy8b28t5cy4tqkff"],"firstSeenAt":"2025-03-14T16:20:05.412Z"},"sources":{"fomo":{"profile":{"handle":"nightowl","name":"Night Owl","bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":null,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":18450,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"},"tradingStats":{"swapCount":1840,"tradeCount":977,"volume":{"value":"482113250000","decimals":6,"currency":"USD"},"avgHoldSeconds":15120.5,"observedAt":"2026-11-01T08:42:10.250Z"}},"pump":{"profile":{"handle":"nightowl","name":null,"bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":false,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":2210,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"}}}},"measures":{"pnl":{"value":"1520250000","decimals":6,"currency":"USD"},"volume":{"value":"84213550000","decimals":6,"currency":"USD"},"trade_count":122}},{"rank":2,"subject":{"kind":"trader","id":"tdr_01jbst8v3xft7t04hmasw9nf6y","canonical":{"display":{"handle":"tidecaller","name":null,"avatarUrl":null},"platforms":["fomo"],"mergedFrom":[],"firstSeenAt":"2025-08-19T12:03:44.090Z"},"sources":{"fomo":{"profile":{"handle":"tidecaller","name":null,"bio":null,"avatarUrl":null,"xHandle":null,"verified":null,"observedAt":"2026-10-30T22:10:09.533Z"}}}},"measures":{"pnl":{"value":"1311900000","decimals":6,"currency":"USD"},"volume":{"value":"20977000000","decimals":6,"currency":"USD"},"trade_count":48}}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `window` is not one of the board's `windows`, or the board has no windows.\n- `at` is in the future, or not RFC3339 (epoch milliseconds are refused).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. The board is not in `GET /v3/leaderboards`, or it has no capture (none at or before `at`).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/rankings":{"get":{"operationId":"listRankings","summary":"List our rankings","description":"Every ranking we compute from our own data, with its metric, window, size and the time of its newest snapshot.\n\n- Order: key as text, so `_24h` sorts before `_30d`, `_7d` and `_all`.\n- Paged with `cursor` and `limit` (default 50, maximum 200).\n\n## Price\n\n**Free.** The call needs a key and takes no credits.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| Every call. | 0 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.","tags":["Rankings"],"x-operation":15,"parameters":[{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 200. 50 when left out.","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RankingCollection"},"example":{"items":[{"key":"traders_net_flow_24h","title":"Traders by net flow, 24 hours","subjectType":"trader","category":"spot_trading","metric":"net_flow","window":"24h","size":100,"latestComputedAt":"2026-11-01T08:40:00.000Z"},{"key":"traders_net_flow_7d","title":"Traders by net flow, 7 days","subjectType":"trader","category":"spot_trading","metric":"net_flow","window":"7d","size":100,"latestComputedAt":"2026-11-01T08:40:00.000Z"}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/rankings/{key}":{"get":{"operationId":"getRanking","summary":"Read the newest snapshot of one of our rankings","description":"The newest snapshot of one of our rankings.\n\n- `order=best`: rank 1 first, then subject id. `order=worst`: the bottom entries, lowest value first.\n- Ties share a rank, 1 plus the number of subjects with a better value, on both orders.\n- `total` counts every ranked subject; `entries` holds at most `size` of them and is not paged.\n- Our rankings never mix with the platforms' boards (`GET /v3/leaderboards/{platform}/{board}`).\n\n## Price\n\nThe price depends on the answer.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| A snapshot exists. | 500 | 0 |\n| 404: the ranking has no snapshot yet. | 200 | 0 |\n| 404: the key is not in `GET /v3/rankings`. | 0 | 0 |\n\n## Limits\n\n- 600 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Rankings"],"x-operation":16,"parameters":[{"name":"key","in":"path","description":"A ranking key, as `GET /v3/rankings` lists it.","required":true,"schema":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$"}},{"name":"order","in":"query","description":"`best` (the default): rank 1 first. `worst`: the bottom entries, lowest value first.","required":false,"schema":{"default":"best","type":"string","enum":["best","worst"]}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RankingDocument"},"example":{"key":"traders_net_flow_24h","title":"Traders by net flow, 24 hours","category":"spot_trading","metric":"net_flow","window":"24h","order":"best","dataAsOf":"2026-11-01T08:35:00.000Z","computedAt":"2026-11-01T08:40:00.000Z","total":9420,"entries":[{"rank":1,"subject":{"kind":"trader","id":"tdr_01jbst8pvcfp79y0938nkrkayd","canonical":{"display":{"handle":"nightowl","name":"Night Owl","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp"},"platforms":["fomo","pump"],"mergedFrom":["tdr_01jbst8zcefy8b28t5cy4tqkff"],"firstSeenAt":"2025-03-14T16:20:05.412Z"},"sources":{"fomo":{"profile":{"handle":"nightowl","name":"Night Owl","bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":null,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":18450,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"},"tradingStats":{"swapCount":1840,"tradeCount":977,"volume":{"value":"482113250000","decimals":6,"currency":"USD"},"avgHoldSeconds":15120.5,"observedAt":"2026-11-01T08:42:10.250Z"}},"pump":{"profile":{"handle":"nightowl","name":null,"bio":"Solana memecoins, small size, long holds.","avatarUrl":"https://img.example.com/a/9b1f0c7e3d2a4b5c8e6f1a2b3c4d5e6f.webp","xHandle":"nightowl_sol","verified":false,"observedAt":"2026-11-01T08:42:10.250Z"},"followGraph":{"followers":2210,"following":312,"observedAt":"2026-11-01T08:42:10.250Z"}}}},"value":{"value":"4210330000","decimals":6,"currency":"USD"},"measures":{"volume":{"value":"18050500000","decimals":6,"currency":"USD"},"trade_count":21,"roi":60.84217174}},{"rank":2,"subject":{"kind":"trader","id":"tdr_01jbst8v3xft7t04hmasw9nf6y","canonical":{"display":{"handle":"tidecaller","name":null,"avatarUrl":null},"platforms":["fomo"],"mergedFrom":[],"firstSeenAt":"2025-08-19T12:03:44.090Z"},"sources":{"fomo":{"profile":{"handle":"tidecaller","name":null,"bio":null,"avatarUrl":null,"xHandle":null,"verified":null,"observedAt":"2026-10-30T22:10:09.533Z"}}}},"value":{"value":"2877120000","decimals":6,"currency":"USD"},"measures":{"volume":{"value":"20977000000","decimals":6,"currency":"USD"},"trade_count":48,"roi":31.79159199}}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. The key is not in `GET /v3/rankings`, or the ranking has no snapshot yet.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/me":{"get":{"operationId":"getMe","summary":"Read the calling key, its plan and its usage","description":"The key that made the call, its plan and scopes, and what it used this billing month (UTC).\n\n- `api.unitsUsed` counts REST calls and stream minutes together. It reads the stored counter, which can miss the newest calls.\n- `unitsRemaining` is `null` for an unmetered key and never below 0.\n- `monthlyReveals` `null` means the key has no reveal cap.\n- Any active key may call it; it needs no REST scope.\n\n## Price\n\n**Free.** The call needs a key and takes no credits.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| Every call. | 0 | 0 |\n\n## Limits\n\n- 120 requests per minute from one address on this operation, beside the per-minute limit of the key.","tags":["Account"],"x-operation":17,"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeDocument"},"example":{"key":{"prefix":"08Kl59cW","name":"Desk production","environment":"live"},"plan":"growth","scopes":["basic"],"api":{"period":"2026-11","monthlyUnits":20000000,"additionalUnits":0,"unitsUsed":1284600,"unitsRemaining":18715400,"unmetered":false,"ratePerMinute":600,"monthlyReveals":1500,"revealsUsed":42,"revealsRemaining":1458},"websocket":{"period":"2026-11","minutesUsed":null,"minutesIncluded":null,"unlimited":false}}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/capabilities":{"get":{"operationId":"getCapabilities","summary":"Read which platform provides which block","description":"Which platform provides which block for each kind, the fields a platform never fills, and every leaderboard we capture. The API answers from the same registry, so this table and the answers agree.\n\n- A block a platform does not provide never appears under that platform in `sources`.\n- A field listed in `unfilled` is always `null` for that platform.\n- Any active key may call it; it needs no REST scope.\n\n## Price\n\n**Free.** The call needs a key and takes no credits.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| Every call. | 0 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.","tags":["Account"],"x-operation":18,"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapabilitiesDocument"},"example":{"kinds":{"trader":{"followGraph":{"platforms":["fomo","pump"],"unfilled":{}},"profile":{"platforms":["fomo","hyperliquid","legend","polymarket","pump","risex"],"unfilled":{"fomo":["verified"],"hyperliquid":["handle","bio","avatarUrl","xHandle","verified"],"legend":["verified"],"polymarket":["name","bio"],"pump":["name"],"risex":["verified"]}},"tradingStats":{"platforms":["fomo"],"unfilled":{}}},"wallet":{},"post":{"callPerformance":{"platforms":["fomo","pump"],"unfilled":{"fomo":["multiple","maxMultiple","maxMultipleAt","mediaUrl","quotedPost"]}},"engagement":{"platforms":["pump"],"unfilled":{}},"position":{"platforms":["fomo","pump"],"unfilled":{"pump":["unrealizedPnl","closedAt"]}}},"trade":{},"token":{"market":{"platforms":["fomo","pump"],"unfilled":{"fomo":["fdv"],"pump":["price","fdv","liquidity","priceChange24h"]}}},"group":{}},"leaderboards":[{"platform":"fomo","board":"clans","category":"groups","metric":"pnl","windows":["24h","7d","30d"],"defaultWindow":"24h","subjectType":"group"},{"platform":"fomo","board":"tokens_graduated","category":"tokens","metric":null,"windows":[],"defaultWindow":null,"subjectType":"token"},{"platform":"fomo","board":"tokens_most_held","category":"tokens","metric":null,"windows":[],"defaultWindow":null,"subjectType":"token"},{"platform":"fomo","board":"tokens_trending","category":"tokens","metric":null,"windows":[],"defaultWindow":null,"subjectType":"token"},{"platform":"fomo","board":"traders","category":"spot_trading","metric":"pnl","windows":["24h","7d","30d","all"],"defaultWindow":"24h","subjectType":"trader"},{"platform":"hyperliquid","board":"traders","category":"perp_trading","metric":"pnl","windows":["24h","7d","30d","all"],"defaultWindow":"30d","subjectType":"trader"},{"platform":"legend","board":"traders","category":"perp_trading","metric":"pnl","windows":["24h","7d","30d","all"],"defaultWindow":"30d","subjectType":"trader"},{"platform":"polymarket","board":"traders_pnl","category":"prediction","metric":"pnl","windows":["24h","7d","30d","all"],"defaultWindow":"30d","subjectType":"trader"},{"platform":"polymarket","board":"traders_volume","category":"prediction","metric":"volume","windows":["24h","7d","30d","all"],"defaultWindow":"30d","subjectType":"trader"},{"platform":"pump","board":"clans","category":"groups","metric":"pnl","windows":["24h","7d","30d"],"defaultWindow":"7d","subjectType":"group"},{"platform":"pump","board":"traders","category":"spot_trading","metric":"pnl","windows":["24h","7d","30d"],"defaultWindow":"7d","subjectType":"trader"},{"platform":"risex","board":"traders","category":"perp_trading","metric":"pnl","windows":["24h","7d","30d","all"],"defaultWindow":"30d","subjectType":"trader"}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/{traderId}/followers":{"get":{"operationId":"listTraderFollowers","summary":"List the traders who follow a trader","description":"The traders who follow this trader, as trader envelopes, with the platform of each edge and the time a crawl last saw it.\n\n- The list covers every account of the trader on a platform with a follow graph (`followGraph` in `GET /v3/capabilities`).\n- One item per edge: a trader on the other side of two platforms appears twice, once per platform.\n- An edge between two accounts of the same trader is left out, so a merge never makes a trader follow itself.\n- `counts` holds, per platform, the platform's own count (`reported`) and the edges we hold (`stored`). Every page carries it.\n- Order: `observedAt` newest first, then the account ids. A page boundary inside a tie neither drops nor repeats an edge.\n- Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, on every call. A short or empty page costs the same as a full one.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 1. | 200 | 0 |\n| `limit` 20 (the default). | 200 | 0 |\n| `limit` 50. | 600 | 0 |\n| `limit` 100 (the maximum). | 1,000 | 0 |\n| 404: no trader has this id. | 200 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Traders"],"x-operation":20,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"platform","in":"query","description":"Only edges on this platform. A platform without a follow graph answers an empty page.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowListDocument"},"example":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","direction":"followers","counts":{"fomo":{"reported":18450,"stored":17982,"observedAt":"2026-11-01T08:42:10.250Z"},"pump":{"reported":2210,"stored":1604,"observedAt":"2026-11-01T08:42:10.250Z"}},"items":[{"subject":{"kind":"trader","id":"tdr_01jbst8v3xft7t04hmasw9nf6y","canonical":{"display":{"handle":"tidecaller","name":null,"avatarUrl":null},"platforms":["fomo"],"mergedFrom":[],"firstSeenAt":"2025-08-19T12:03:44.090Z"},"sources":{"fomo":{"profile":{"handle":"tidecaller","name":null,"bio":null,"avatarUrl":null,"xHandle":null,"verified":null,"observedAt":"2026-10-30T22:10:09.533Z"}}}},"platform":"fomo","observedAt":"2026-10-31T23:12:40.071Z"}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/{traderId}/following":{"get":{"operationId":"listTraderFollowing","summary":"List the traders a trader follows","description":"The traders this trader follows, as trader envelopes, with the platform of each edge and the time a crawl last saw it.\n\n- The list covers every account of the trader on a platform with a follow graph (`followGraph` in `GET /v3/capabilities`).\n- One item per edge: a trader on the other side of two platforms appears twice, once per platform.\n- An edge between two accounts of the same trader is left out, so a merge never makes a trader follow itself.\n- `counts` holds, per platform, the platform's own count (`reported`) and the edges we hold (`stored`). Every page carries it.\n- Order: `observedAt` newest first, then the account ids. A page boundary inside a tie neither drops nor repeats an edge.\n- Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, on every call. A short or empty page costs the same as a full one.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 1. | 200 | 0 |\n| `limit` 20 (the default). | 200 | 0 |\n| `limit` 50. | 600 | 0 |\n| `limit` 100 (the maximum). | 1,000 | 0 |\n| 404: no trader has this id. | 200 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Traders"],"x-operation":21,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"platform","in":"query","description":"Only edges on this platform. A platform without a follow graph answers an empty page.","required":false,"schema":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowListDocument"},"example":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","direction":"following","counts":{"fomo":{"reported":312,"stored":312,"observedAt":"2026-11-01T08:42:10.250Z"},"pump":{"reported":null,"stored":0,"observedAt":null}},"items":[{"subject":{"kind":"trader","id":"tdr_01jbst8v3xft7t04hmasw9nf6y","canonical":{"display":{"handle":"tidecaller","name":null,"avatarUrl":null},"platforms":["fomo"],"mergedFrom":[],"firstSeenAt":"2025-08-19T12:03:44.090Z"},"sources":{"fomo":{"profile":{"handle":"tidecaller","name":null,"bio":null,"avatarUrl":null,"xHandle":null,"verified":null,"observedAt":"2026-10-30T22:10:09.533Z"}}}},"platform":"fomo","observedAt":"2026-10-31T23:12:40.071Z"}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/trades":{"get":{"operationId":"listTrades","summary":"Read the newest trades of the traders we mapped","description":"The newest on-chain trades of the wallets we mapped to a trader, on every network we index, newest first. Each trade names its owner.\n\n- A wallet appears when a trader holds an active link to it, at any tier. A link read from the wallet a platform profile shows never counts; every other active link does, at its tier.\n- `owner` is the first owner the wallet envelope lists, with the tier capped as there: a wallet two traders hold shows one of them at `weak`.\n- `network` and `side` narrow the feed.\n- Quantities only: read prices from `GET /v3/tokens/{network}/{address}`.\n- Order: block time newest first, then trade id. A trade without a block time is left out.\n- Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, plus **100 credits and one reveal for each distinct trader the page shows as an owner**, on every call. A trader on two pages takes two reveals.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 20 (the default), an empty page. | 200 | 0 |\n| `limit` 20 (the default), the page shows 5 distinct traders. | 700 | 5 |\n| `limit` 100 (the maximum), an empty page. | 1,000 | 0 |\n| `limit` 100 (the maximum), the page shows 12 distinct traders. | 2,200 | 12 |\n\nReveals count against a key with a monthly reveal cap. When the answer needs more reveals than the key has left, the call is refused before any credit is taken: 402 `REVEAL_LIMIT_REACHED`, or 403 `PERMISSION_DENIED` for a key on a free plan without reveals.\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Trades"],"x-operation":22,"parameters":[{"name":"network","in":"query","description":"Only trades on this network. Leave it out for every network.","required":false,"schema":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"]}},{"name":"side","in":"query","description":"One side: `buy`, `sell` or `swap`. Leave it out for every side.","required":false,"schema":{"type":"string","enum":["buy","sell","swap"]}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradeCollection"},"example":{"items":[{"kind":"trade","id":"trd_01jbsta8h2ecsr8h2nank6cxvq","canonical":{"network":"solana","txHash":"5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW","blockNumber":371904117,"executedAt":"2026-11-01T08:57:12.000Z","wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","side":"buy","token":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"quoteToken":"tok_solana_So11111111111111111111111111111111111111112","quoteQuantity":{"value":"326814220","decimals":9,"currency":"tok_solana_So11111111111111111111111111111111111111112"},"platform":"fomo","verification":"chain","owner":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl","tier":"proven"}},"sources":{}},{"kind":"trade","id":"trd_01jbstacskeh28anb6csvqf248","canonical":{"network":"solana","txHash":"3nTq8bVf9Lw2Hk7Yd4Rx6Cm1Pz5Js8Ga2Ue9Wo4Bt7Nc3Fy6Qh1Dk5Mv8Xr2Lp9Sg4Ja7Ze3Tb6Wn1Ku5Yc8Hf2Vd","blockNumber":371903650,"executedAt":"2026-11-01T08:54:03.000Z","wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","side":"sell","token":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","quantity":{"value":"150000000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"quoteToken":"tok_solana_So11111111111111111111111111111111111111112","quoteQuantity":{"value":"121480930","decimals":9,"currency":"tok_solana_So11111111111111111111111111111111111111112"},"platform":"fomo","verification":"chain","owner":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl","tier":"proven"}},"sources":{}}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.\n\n`REVEAL_LIMIT_REACHED`: the answer needs a reveal and the key has used every reveal this month. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.\n\n`PERMISSION_DENIED` also when a key on a free plan without reveals asks for an answer that needs one. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/traders/{traderId}/trades":{"get":{"operationId":"listTraderTrades","summary":"Read the trades of a trader's wallets","description":"The trades of the wallets `GET /v3/traders/{traderId}/wallets` lists for the trader, newest first. `owner` is this trader, with its tier on each wallet.\n\n- `network` and `token` narrow the list.\n- Order as in `GET /v3/trades`. Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, plus **100 credits and one reveal for each distinct trader the page shows as an owner**, on every call. A trader on two pages takes two reveals.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 20 (the default), an empty page. | 200 | 0 |\n| `limit` 20 (the default), the page lists trades. | 300 | 1 |\n| `limit` 100 (the maximum), an empty page. | 1,000 | 0 |\n| `limit` 100 (the maximum), the page lists trades. | 1,100 | 1 |\n| 404: no trader has this id. | 200 | 0 |\n\nReveals count against a key with a monthly reveal cap. When the answer needs more reveals than the key has left, the call is refused before any credit is taken: 402 `REVEAL_LIMIT_REACHED`, or 403 `PERMISSION_DENIED` for a key on a free plan without reveals.\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Trades"],"x-operation":23,"parameters":[{"name":"traderId","in":"path","description":"A trader id: `tdr_` and 26 characters. `GET /v3/traders/lookup` finds it by handle.","required":true,"schema":{"type":"string","pattern":"^tdr_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"network","in":"query","description":"Only trades on this network. Leave it out for every network.","required":false,"schema":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"]}},{"name":"token","in":"query","description":"Only trades in this token: `tok_<network>_<address>`.","required":false,"schema":{"type":"string","minLength":5,"maxLength":200}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradeCollection"},"example":{"items":[{"kind":"trade","id":"trd_01jbsta8h2ecsr8h2nank6cxvq","canonical":{"network":"solana","txHash":"5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW","blockNumber":371904117,"executedAt":"2026-11-01T08:57:12.000Z","wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","side":"buy","token":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"quoteToken":"tok_solana_So11111111111111111111111111111111111111112","quoteQuantity":{"value":"326814220","decimals":9,"currency":"tok_solana_So11111111111111111111111111111111111111112"},"platform":"fomo","verification":"chain","owner":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl","tier":"proven"}},"sources":{}},{"kind":"trade","id":"trd_01jbstacskeh28anb6csvqf248","canonical":{"network":"solana","txHash":"3nTq8bVf9Lw2Hk7Yd4Rx6Cm1Pz5Js8Ga2Ue9Wo4Bt7Nc3Fy6Qh1Dk5Mv8Xr2Lp9Sg4Ja7Ze3Tb6Wn1Ku5Yc8Hf2Vd","blockNumber":371903650,"executedAt":"2026-11-01T08:54:03.000Z","wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","side":"sell","token":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","quantity":{"value":"150000000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"quoteToken":"tok_solana_So11111111111111111111111111111111111111112","quoteQuantity":{"value":"121480930","decimals":9,"currency":"tok_solana_So11111111111111111111111111111111111111112"},"platform":"fomo","verification":"chain","owner":{"trader":"tdr_01jbst8pvcfp79y0938nkrkayd","handle":"nightowl","tier":"proven"}},"sources":{}}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `token` is not a token id (`tok_<network>_<address>`).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.\n\n`REVEAL_LIMIT_REACHED`: the answer needs a reveal and the key has used every reveal this month. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.\n\n`PERMISSION_DENIED` also when a key on a free plan without reveals asks for an answer that needs one. Nothing is charged.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. No trader has this id, merges included.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/wallets/{family}/{address}/trades":{"get":{"operationId":"listWalletTrades","summary":"Read the trades of one wallet","description":"The trades of one wallet, mapped to a trader or not, newest first. `owner` is `null`: `GET /v3/wallets/{family}/{address}` names the owners.\n\n- `network` and `token` narrow the list.\n- A wallet without trades, or one we never saw, answers 200 with an empty page.\n- Order as in `GET /v3/trades`. Paged with `cursor` and `limit` (default 20, maximum 100). Follow `nextCursor` to read older rows.\n\n## Price\n\n**200 credits per started 20 rows of `limit`**, on every call. A short or empty page costs the same as a full one.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `limit` 1. | 200 | 0 |\n| `limit` 20 (the default). | 200 | 0 |\n| `limit` 50. | 600 | 0 |\n| `limit` 100 (the maximum). | 1,000 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Trades"],"x-operation":24,"parameters":[{"name":"family","in":"path","description":"The address family: `svm` for Solana, `evm` for EVM networks.","required":true,"schema":{"type":"string","enum":["svm","evm"]}},{"name":"address","in":"path","description":"The wallet address. An EVM address matches in any letter case.","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"network","in":"query","description":"Only trades on this network. Leave it out for every network.","required":false,"schema":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"]}},{"name":"token","in":"query","description":"Only trades in this token: `tok_<network>_<address>`.","required":false,"schema":{"type":"string","minLength":5,"maxLength":200}},{"name":"cursor","in":"query","description":"The `nextCursor` of the previous page, sent back as it came. Leave it out for the first page. A cursor belongs to the query that produced it: sent with other parameters it answers 400 `INVALID_ARGUMENT`.","required":false,"schema":{"type":"string","minLength":3,"maxLength":1024}},{"name":"limit","in":"query","description":"Rows per page, 1 to 100. 20 when left out.","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradeCollection"},"example":{"items":[{"kind":"trade","id":"trd_01jbsta8h2ecsr8h2nank6cxvq","canonical":{"network":"solana","txHash":"5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW","blockNumber":371904117,"executedAt":"2026-11-01T08:57:12.000Z","wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","side":"buy","token":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","quantity":{"value":"412500000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"quoteToken":"tok_solana_So11111111111111111111111111111111111111112","quoteQuantity":{"value":"326814220","decimals":9,"currency":"tok_solana_So11111111111111111111111111111111111111112"},"platform":"fomo","verification":"chain","owner":null},"sources":{}},{"kind":"trade","id":"trd_01jbstacskeh28anb6csvqf248","canonical":{"network":"solana","txHash":"3nTq8bVf9Lw2Hk7Yd4Rx6Cm1Pz5Js8Ga2Ue9Wo4Bt7Nc3Fy6Qh1Dk5Mv8Xr2Lp9Sg4Ja7Ze3Tb6Wn1Ku5Yc8Hf2Vd","blockNumber":371903650,"executedAt":"2026-11-01T08:54:03.000Z","wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","side":"sell","token":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","quantity":{"value":"150000000000","decimals":5,"currency":"tok_solana_DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},"quoteToken":"tok_solana_So11111111111111111111111111111111111111112","quoteQuantity":{"value":"121480930","decimals":9,"currency":"tok_solana_So11111111111111111111111111111111111111112"},"platform":"fomo","verification":"chain","owner":null},"sources":{}}],"hasMore":true,"nextCursor":"c_eyJxIjoiazNKOXhRMm1aN2FCIiwidiI6eyJzIjoiMjAyNi0xMS0wMVQwODo0MTowMi45MTdaIiwiaSI6IjAxOTJmM2E1LTIyMjItNzMzMy04NDQ0LTU1NTU2NjY2Nzc3NyJ9fQ"}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `address` is not a valid address of `family`.\n- `token` is not a token id (`tok_<network>_<address>`).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/wallets/{family}/{address}/pnl":{"get":{"operationId":"getWalletPnl","summary":"Read one wallet's PnL across the whole wallet","description":"The profit and loss of one wallet in the windows of `GET /v3/traders/{traderId}/pnl`. `24h`, `7d`, `30d` and `unrealized` come from our data provider for this wallet; `all` is ours, computed from the trades we index.\n\n- `status`, `retryAfterSeconds`, `asOf`, `nextUpdateAt`, `stale` and `window` follow the rules of `GET /v3/traders/{traderId}/pnl`. `no_wallet` cannot occur.\n- `wallets` names the wallets the figures cover, Solana first. When a platform keys this wallet to accounts of one trader, the wallet of the other family that trader holds as an account key on that platform joins it, and every figure covers both. It is listed whatever the status and takes no reveal.\n- `boards` says where the accounts keyed by these wallets stand on the newest capture of each platform board that ranks accounts, as the platform shows it.\n- Any wallet we hold answers, mapped to a trader or not. The document names no owner: `GET /v3/wallets/{family}/{address}` does.\n- `all` is `null` when we hold no figure of the wallet. Its `realized` and `unrealized` are ours, from the trades we index, and `total` is their sum. Its `rank` is `null`: no ranking lists wallets.\n\n## Price\n\nThe price depends on the answer.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| `status` is `ready`. | 500 | 0 |\n| Any other `status`, or 404 for a wallet we never saw. | 200 | 0 |\n\n## Limits\n\n- 2,000 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.\n- A read of our data provider runs up to 8 seconds inside the call. Past that the call answers with what we hold, and the read finishes for your next call.","tags":["Wallets"],"x-operation":25,"parameters":[{"name":"family","in":"path","description":"The address family: `svm` for Solana, `evm` for EVM networks.","required":true,"schema":{"type":"string","enum":["svm","evm"]}},{"name":"address","in":"path","description":"The wallet address. An EVM address matches in any letter case.","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"window","in":"query","description":"One window: `24h`, `7d`, `30d` or `all`. Leave it out for all four. `status` stays the same either way.","required":false,"schema":{"type":"string","enum":["24h","7d","30d","all"]}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletPnlDocument"},"example":{"wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","wallets":["wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","wal_evm_0x52908400098527886e0f7030069857d2e4169ee7"],"status":"ready","retryAfterSeconds":null,"windows":{"24h":{"origin":"provider","status":"ready","realized":{"value":"1250500000","decimals":6,"currency":"USD"},"unrealized":{"value":"412150000","decimals":6,"currency":"USD"},"total":{"value":"1662650000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"18050500000","decimals":6,"currency":"USD"},"buyVolume":{"value":"8400000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"9650500000","decimals":6,"currency":"USD"},"returnPct":14.88690476,"tradeCount":21,"buys":12,"sells":9,"tokensTraded":6,"winningTokens":4,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false},"7d":{"origin":"provider","status":"ready","realized":{"value":"-312750000","decimals":6,"currency":"USD"},"unrealized":{"value":"1506900000","decimals":6,"currency":"USD"},"total":{"value":"1194150000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"80160000000","decimals":6,"currency":"USD"},"buyVolume":{"value":"41200000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"38960000000","decimals":6,"currency":"USD"},"returnPct":-0.79635371,"tradeCount":105,"buys":58,"sells":47,"tokensTraded":19,"winningTokens":8,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false},"30d":{"origin":"provider","status":"ready","realized":{"value":"9884200000","decimals":6,"currency":"USD"},"unrealized":{"value":"2101300000","decimals":6,"currency":"USD"},"total":{"value":"11985500000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"312410000000","decimals":6,"currency":"USD"},"buyVolume":{"value":"152300000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"160110000000","decimals":6,"currency":"USD"},"returnPct":6.57956223,"tradeCount":412,"buys":214,"sells":198,"tokensTraded":61,"winningTokens":27,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false},"all":{"origin":"computed","status":"ready","realized":{"value":"6120400000","decimals":6,"currency":"USD"},"unrealized":{"value":"-184250000","decimals":6,"currency":"USD"},"total":{"value":"5936150000","decimals":6,"currency":"USD"},"unpricedProceeds":{"value":"0","decimals":6,"currency":"USD"},"netFlow":{"value":"5310200000","decimals":6,"currency":"USD"},"volume":{"value":"96480500000","decimals":6,"currency":"USD"},"buyVolume":{"value":"45585150000","decimals":6,"currency":"USD"},"sellVolume":{"value":"50895350000","decimals":6,"currency":"USD"},"returnPct":11.64896902,"tradeCount":288,"buys":151,"sells":137,"tokensTraded":44,"winningTokens":19,"rank":null,"asOf":"2026-11-01T08:35:00.000Z","approximate":false}},"unrealized":{"origin":"provider","value":{"value":"2318400000","decimals":6,"currency":"USD"},"holdingsValue":{"value":"11904650000","decimals":6,"currency":"USD"},"positions":9,"excludedPositions":2,"asOf":"2026-11-01T08:55:00.000Z"},"asOf":"2026-11-01T08:55:00.000Z","nextUpdateAt":"2026-11-01T11:55:00.000Z","stale":false,"boards":[{"platform":"fomo","board":"traders","window":"7d","rank":14,"measures":{"pnl":{"value":"8421300000","decimals":6,"currency":"USD"}},"capturedAt":"2026-11-01T08:30:00.000Z"}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `address` is not a valid address of `family`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`. We never saw this wallet.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v3/wallets/pnl":{"post":{"operationId":"bulkWalletPnl","summary":"Read the PnL of up to 100 wallets","description":"The PnL of up to 100 wallets in one call. `items` follows the order of `wallets`, one item per distinct wallet.\n\n- Each item holds the wallet's `wal_` id, `found`, and the document `GET /v3/wallets/{family}/{address}/pnl` returns, or `null` when we never saw the wallet.\n- Each item costs what `GET /v3/wallets/{family}/{address}/pnl` costs for its answer: the hit price when `ready`, the miss price otherwise and when not found. No reveal.\n- The whole batch is refused with 402 before any read unless the key holds the hit price for every item.\n- An unknown wallet is an item with `found: false`. This operation never answers 404.\n\n## Price\n\n**Per item**: 500 credits and one reveal for each item whose `status` is `ready`, 200 credits for every other item. Before any work the whole batch is refused when the balance holds less than 200 credits per item (402 `QUOTA_EXCEEDED`), or the key has fewer reveals left this month than items, whatever their status turns out to be.\n\n| Answer | Credits | Reveals |\n| --- | --- | --- |\n| Each item whose `status` is `ready`. | 500 | 0 |\n| Each item with another `status`, or a wallet we never saw. | 200 | 0 |\n| 100 wallets, 60 of them `ready`. | 38,000 | 0 |\n\n## Limits\n\n- 120 requests per minute from one address on this operation, beside the per-minute limit of the key.\n- A key with less than 200 credits left gets 402 `QUOTA_EXCEEDED` before any work.","tags":["Wallets"],"x-operation":26,"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletPnlBulk"},"example":{"items":[{"wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","found":true,"pnl":{"wallet":"wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","wallets":["wal_svm_9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","wal_evm_0x52908400098527886e0f7030069857d2e4169ee7"],"status":"ready","retryAfterSeconds":null,"windows":{"7d":{"origin":"provider","status":"ready","realized":{"value":"-312750000","decimals":6,"currency":"USD"},"unrealized":{"value":"1506900000","decimals":6,"currency":"USD"},"total":{"value":"1194150000","decimals":6,"currency":"USD"},"unpricedProceeds":null,"netFlow":null,"volume":{"value":"80160000000","decimals":6,"currency":"USD"},"buyVolume":{"value":"41200000000","decimals":6,"currency":"USD"},"sellVolume":{"value":"38960000000","decimals":6,"currency":"USD"},"returnPct":-0.79635371,"tradeCount":105,"buys":58,"sells":47,"tokensTraded":19,"winningTokens":8,"rank":null,"asOf":"2026-11-01T08:55:00.000Z","approximate":false}},"unrealized":{"origin":"provider","value":{"value":"2318400000","decimals":6,"currency":"USD"},"holdingsValue":{"value":"11904650000","decimals":6,"currency":"USD"},"positions":9,"excludedPositions":2,"asOf":"2026-11-01T08:55:00.000Z"},"asOf":"2026-11-01T08:55:00.000Z","nextUpdateAt":"2026-11-01T11:55:00.000Z","stale":false,"boards":[{"platform":"fomo","board":"traders","window":"7d","rank":14,"measures":{"pnl":{"value":"8421300000","decimals":6,"currency":"USD"}},"capturedAt":"2026-11-01T08:30:00.000Z"}]}},{"wallet":"wal_svm_11111111111111111111111111111112","found":false,"pnl":null}]}}}},"400":{"description":"`INVALID_ARGUMENT`: a parameter, an id, a cursor or the body is malformed, or the operation does not take it.\n\n- `wallets` is empty, holds more than 100 wallets, or holds an address that is not valid for its `family`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: no key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: the credit balance cannot pay for the call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: the key may not make this call.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: too many requests. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: the call failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: the API holds too many requests at once. Retry after the seconds in `Retry-After`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"wallets":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"family":{"type":"string","enum":["svm","evm"],"description":"The address family: `svm` for Solana, `evm` for EVM networks."},"address":{"type":"string","minLength":1,"maxLength":128,"description":"The wallet address. An EVM address matches in any letter case."}},"required":["family","address"],"additionalProperties":false},"description":"1 to 100 wallets. A wallet repeated, in any letter case for EVM, counts once."},"window":{"description":"One window: `24h`, `7d`, `30d` or `all`. Leave it out for all four. `status` stays the same either way.","type":"string","enum":["24h","7d","30d","all"]}},"required":["wallets"],"additionalProperties":false}}}}}},"/v3":{"servers":[{"url":"wss://stream.fomoscan.sh","description":"The stream host"}],"get":{"operationId":"stream","summary":"Live posts (WebSocket)","description":"One WebSocket pushes every new post as we publish it, from every platform, narrowed to the platforms and tokens you choose. A `post` frame carries the envelope `GET /v3/posts` returns.\n\nThis path lives on the stream host and answers only a WebSocket upgrade, so \"Try it out\" cannot open it. A plain `GET` gets `404`.\n\n## Connect\n\nURL: `wss://stream.fomoscan.sh/v3`\n\nSend the key on the upgrade request in one of the two headers every REST call takes:\n\n- `Authorization: Bearer <key>`\n- `X-Api-Key: <key>`\n\nThe URL takes no key parameter. A browser `WebSocket` cannot set headers, so hold the socket on your server and relay frames to your front end. Never ship the key to a browser.\n\n```sh\nnpx wscat -c 'wss://stream.fomoscan.sh/v3' -H \"Authorization: Bearer $FOMOSCAN_KEY\"\n```\n\n```js\nimport WebSocket from 'ws';\n\nconst socket = new WebSocket('wss://stream.fomoscan.sh/v3', {\n  headers: { Authorization: `Bearer ${apiKey}` },\n});\nsocket.on('message', (data) => {\n  const frame = JSON.parse(data.toString());\n  if (frame.type === 'ready') socket.send(JSON.stringify({ type: 'subscribe', topic: 'posts' }));\n  if (frame.type === 'post') handle(frame.item, frame.cursor);\n});\n```\n\nFrames you send before `ready` wait in a queue of 32 frames or 64 KB and run after it.\n\n## Which keys may connect\n\nThe stream checks the key before the upgrade. A refusal is an HTTP status with the error body every REST call uses, listed under Responses below.\n\n| Check | Rule | Refusal |\n| --- | --- | --- |\n| Key | An active key that has not expired. | `401 UNAUTHENTICATED` |\n| Scope | The key holds `basic` or `live:read`. | `403 PERMISSION_DENIED` |\n| Plan | `growth`, `pro`, `scale`, `enterprise`, `custom`, `legacy`, and every plan whose name starts with `legacy-`. A key on a free plan (`pilot` or `explore`) connects unless its monthly reveal allowance is zero; an unmetered free key always connects. A key on any other plan connects only when it is unmetered. | `403 PLAN_REQUIRED` |\n| Credit | At least 20,000 credits left, one minute; an unmetered key always passes. | `402 QUOTA_EXCEEDED` |\n| Rate | The per-minute request limit of the key, and a limit per address. | `429 RATE_LIMITED` |\n\nWhile free keys are switched off, a key on a free plan gets `403 PERMISSION_DENIED`.\n\nThe stream checks the key again before every minute charge, through an authentication cache that holds a key for up to 30 seconds. A key that was revoked or expired, or lost the scope or the plan, gets an error frame and the socket closes with `1008`.\n\n## Price\n\nEach open connection costs **20,000 credits per started minute**, taken from the same credit balance as REST calls.\n\n- The stream charges the first minute on attach, before the upgrade completes, and one more every 60 seconds while the socket is open. A socket without a subscription pays the same.\n- The price is per socket: one token, fifty tokens or every post cost the same. One socket carries every platform; each socket you open is charged on its own.\n- An upgrade needs 20,000 credits left, or it gets `402 QUOTA_EXCEEDED`. A key with too few credits for the next minute gets an error frame with `QUOTA_EXCEEDED`, and the socket closes with `1008`.\n- An unmetered key is counted and never refused. A child key pays from its parent's balance, as on REST.\n- `GET /v3/me` shows the balance: socket minutes count in `api.unitsUsed`, and `websocket.minutesUsed` is `null`. Your usage lists each minute under `GET /v3`.\n\n## Client frames\n\nSend JSON text frames. The stream takes `subscribe` and `unsubscribe`; schema `StreamClientFrame`.\n\n### subscribe\n\n```json\n{\n  \"type\": \"subscribe\",\n  \"topic\": \"posts\",\n  \"platforms\": [\n    \"fomo\",\n    \"pump\"\n  ],\n  \"tokens\": [\n    \"tok_solana_EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n    \"tok_base_0x833589fcd6edb6e08f4c7c32d4f71b54bda02913\"\n  ],\n  \"since\": \"s_eyJzZXEiOjEwNDIxN30\"\n}\n```\n\n| Field | Rule |\n| --- | --- |\n| `topic` | Required: `posts`. |\n| `platforms` | Optional. One or more of `fomo`, `pump`, `hyperliquid`, `markets`, `polymarket`, `legend`, `risex`; posts come from `fomo` and `pump` today. Omit the field for every platform. An empty list, `null` or an unknown name is rejected. |\n| `tokens` | Optional. 1 to 50 token ids, `tok_<network>_<address>`. Omit the field for every token. A post without a token never matches a token filter. An empty list, `null` or a value that is not a token id is rejected. |\n| `since` | Optional. The `cursor` of a `post` or `replay_done` frame you received. The stream replays what you missed first; see Replay. |\n\n- A post must match both filters.\n- A connection holds one subscription. A new `subscribe` replaces it in full, so send the whole token list each time.\n- Nothing arrives before the first accepted `subscribe`.\n- A field the frame type does not take is rejected.\n- A rejected frame changes nothing and keeps the socket open.\n\n### unsubscribe\n\n```json\n{\n  \"type\": \"unsubscribe\"\n}\n```\n\nClears the subscription. The socket stays open and keeps being charged.\n\n## Server frames\n\nEvery frame is a JSON object with a `type`; schema `StreamServerFrame`. Ignore types and fields you do not know: new ones arrive as additive changes.\n\n### ready\n\nOnce, after the upgrade and the first minute charge. `connectionId` names this connection in our logs, and error frames carry it as `requestId`.\n\n```json\n{\n  \"type\": \"ready\",\n  \"connectionId\": \"0192f3a4-5b6c-7d8e-9f01-23456789abcd\"\n}\n```\n\n### subscribed\n\nAfter every accepted `subscribe`. `subscription` is what you receive from now on, normalised: duplicates dropped, EVM token addresses lowercased, and `platforms` or `tokens` set to `null` when they do not filter. `replaced` is the subscription it replaced, or `null`.\n\n```json\n{\n  \"type\": \"subscribed\",\n  \"subscription\": {\n    \"topic\": \"posts\",\n    \"platforms\": [\n      \"fomo\",\n      \"pump\"\n    ],\n    \"tokens\": [\n      \"tok_solana_EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n      \"tok_base_0x833589fcd6edb6e08f4c7c32d4f71b54bda02913\"\n    ]\n  },\n  \"replaced\": {\n    \"topic\": \"posts\",\n    \"platforms\": null,\n    \"tokens\": null\n  }\n}\n```\n\n### unsubscribed\n\nAfter every `unsubscribe`. `replaced` is the subscription it cleared, or `null`.\n\n```json\n{\n  \"type\": \"unsubscribed\",\n  \"replaced\": {\n    \"topic\": \"posts\",\n    \"platforms\": [\n      \"fomo\",\n      \"pump\"\n    ],\n    \"tokens\": [\n      \"tok_solana_EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n      \"tok_base_0x833589fcd6edb6e08f4c7c32d4f71b54bda02913\"\n    ]\n  }\n}\n```\n\n### post\n\nOne per delivered post. `item` is the post envelope, the same object `GET /v3/posts` returns (schema `PostEnvelope`). `cursor` is the stream cursor of this post: store the last one you processed.\n\n```json\n{ \"type\": \"post\", \"cursor\": \"s_eyJzZXEiOjEwNDIzMH0\", \"item\": { \"kind\": \"post\", \"id\": \"pst_…\", \"canonical\": { … }, \"sources\": { … } } }\n```\n\n### replay_done\n\nAfter the last replayed post and before the first live one. `cursor` is the newest cursor the replay sent, or your own `since` when nothing was replayed.\n\n```json\n{\n  \"type\": \"replay_done\",\n  \"cursor\": \"s_eyJzZXEiOjEwNDIzMX0\"\n}\n```\n\n### error\n\nA frame the stream rejected, or the moment before the stream closes the socket. Act on `code`; `message` is for people. `requestId` is the connection id.\n\n```json\n{\n  \"type\": \"error\",\n  \"error\": {\n    \"type\": \"invalid_request\",\n    \"code\": \"INVALID_ARGUMENT\",\n    \"message\": \"The cursor is older than the replay window.\",\n    \"requestId\": \"0192f3a4-5b6c-7d8e-9f01-23456789abcd\"\n  }\n}\n```\n\n## Error frames\n\n| `code` | When | The socket |\n| --- | --- | --- |\n| `INVALID_ARGUMENT` | The frame is not JSON or not an object; it has an unknown `type`, field or `topic`; a `platforms` or `tokens` filter breaks the rules above; `since` is malformed, or names no post (\"The cursor is not valid.\"). | Stays open. Nothing changes. |\n| `INVALID_ARGUMENT` | A frame larger than 64 KB. | Closes with `1009`. |\n| `INVALID_ARGUMENT` | `since` is older than the replay window: \"The cursor is older than the replay window.\" | Stays open. The error comes before `subscribed`, and the subscription runs without a replay. |\n| `RATE_LIMITED` | More than 10 `subscribe` or `unsubscribe` frames in 60 seconds. | Stays open. The frame is ignored. |\n| `OVERLOADED` | The stream could not attach the subscription. | Stays open. Send the `subscribe` again. |\n| `OVERLOADED` | Charging a minute failed on our side 2 times in a row. | Closes with `1011`. Reconnect with `since`. |\n| `QUOTA_EXCEEDED` | The balance cannot pay the next minute. | Closes with `1008`. |\n| `UNAUTHENTICATED` | At a minute charge the key is revoked or expired. | Closes with `1008`. |\n| `PERMISSION_DENIED` | At a minute charge the key has lost the stream scope, or free keys are switched off. | Closes with `1008`. |\n| `PLAN_REQUIRED` | At a minute charge the plan of the key no longer includes the stream. | Closes with `1008`. |\n\nAt most 10 error frames in 10 seconds answer rejected frames; past that a rejected frame changes nothing and gets no answer. The replay window error, `OVERLOADED` for a `subscribe`, and the error before a close always arrive.\n\n## Replay with `since`\n\n- Every `post` frame carries a `cursor` (`s_…`). Store the last one you processed and send it back as it is; do not parse it.\n- A `subscribe` with `since` sends the posts published after that cursor which match the new filters, oldest first, then `replay_done`, then live posts. Live posts published while the replay loads wait and follow `replay_done`; a post in both arrives once.\n- The replay window is the last 5 minutes by publication time. A `since` older than that gets the error frame `INVALID_ARGUMENT` \"The cursor is older than the replay window.\", then `subscribed`, and no `replay_done`: live posts flow, and you fill the gap from `GET /v3/posts`, deduplicated on `item.id`.\n- A `since` that names no post gets `INVALID_ARGUMENT` \"The cursor is not valid.\", and the subscription does not change.\n- Stream cursors work only here. The `c_` cursors of REST collections are a different thing.\n\n## Ordering and duplicates\n\n- Posts arrive in the order we published them, which can differ from `canonical.postedAt`. Sort by `postedAt` when you need the author time order.\n- On one connection a post arrives once. A `subscribe` without `since` continues after the newest post the connection already sent, so it repeats nothing.\n- A `subscribe` with `since` replays everything after that cursor, posts this connection already delivered included. Reconnect with the last cursor you processed and nothing repeats; an older cursor repeats posts.\n- Deduplicate on `item.id` wherever you merge the stream with REST pages or with a replay from an older cursor.\n- The stream sends a post once, when we publish it. Later edits, counts and hides send no frame; read the post from REST for its current state.\n\n## Heartbeats\n\n- The server sends a WebSocket ping every 30 seconds. Browser and Node `ws` clients answer with a pong on their own; a hand-written client must answer itself.\n- The stream closes a socket it heard nothing from (no pong, no frame) for 90 seconds with `1011`.\n- Watch the other direction too: when neither a ping nor a frame arrives for 75 seconds, the path is dead. Terminate the socket and reconnect.\n\n## Limits\n\n| Limit | Value | Past it |\n| --- | --- | --- |\n| Inbound frame | 64 KB | Error frame `INVALID_ARGUMENT` and close `1009`; over 1 MiB, close `1009` with no frame. |\n| Frames sent before `ready` | 32 frames or 64 KB | Close `1009`. |\n| Frames waiting for the stream to handle them | 32 frames or 64 KB | Close `1013`. |\n| Frames waiting for you to read them | 8 MB | Close `1013`. |\n| `subscribe` and `unsubscribe` | 10 in 60 seconds | Error frame `RATE_LIMITED`; the frame is ignored. |\n| Error frames that answer rejected frames | 10 in 10 seconds | Further rejected frames get no answer. |\n| Tokens in one filter | 50 | Error frame `INVALID_ARGUMENT`. |\n| Replay window | 5 minutes | Error frame `INVALID_ARGUMENT`; no replay. |\n\n## Close codes\n\n| Code | Meaning | What to do |\n| --- | --- | --- |\n| `1001` | The stream is restarting for a deploy. | Reconnect at once with `since`. |\n| `1008` | The key may not continue: the balance is spent, the key is revoked or expired, or it lost the stream scope or plan. An error frame names the code first. | Do not retry in a loop. Fix the key or the balance, then reconnect with `since`. |\n| `1009` | A frame larger than 64 KB (larger than 1 MiB closes with no error frame), or more than 32 frames or 64 KB sent before `ready`. | Fix the client first: the same frames close the next socket too. |\n| `1011` | Nothing heard from you for 90 seconds, or charging a minute failed on our side 2 times in a row (after an `OVERLOADED` error frame). | Reconnect with backoff and `since`. |\n| `1013` | You read too slowly (8 MB wait in the send buffer) or send faster than the stream handles (32 frames or 64 KB wait). | Read faster or narrow the filters, then reconnect with `since`. |\n\nAny other code, or a drop without a close frame (`1006` in most libraries), means the network path broke: reconnect with backoff and `since`.\n\n## Reconnect correctly\n\n1. Store the `cursor` of each post once you have processed it.\n2. On close, read the code. `1008`: stop and fix the key or the balance. `1009`: fix the client. Anything else: reconnect.\n3. Reconnect at once after `1001`. Otherwise wait 1, 2, 4 and up to 30 seconds between attempts, with jitter. A refused handshake with `429` or `503` names the wait in `Retry-After`; `401`, `402` and `403` need a fix before a retry.\n4. After `ready`, send the same `subscribe` with `since` set to the stored cursor.\n5. Process the replayed posts, then `replay_done`, then live posts.\n6. When the replay window error arrives instead, fill the gap from `GET /v3/posts` and deduplicate on `item.id`.","tags":["WebSocket"],"x-operation":19,"responses":{"101":{"description":"Switching Protocols. The socket is open, the first minute is charged, and `ready` follows."},"400":{"description":"`INVALID_ARGUMENT`: The WebSocket handshake is not valid: `Sec-WebSocket-Key`, `Sec-WebSocket-Version` or `Sec-WebSocket-Protocol`.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"`UNAUTHENTICATED`: No key, or the key is unknown, revoked or expired.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"`QUOTA_EXCEEDED`: The balance cannot pay the first minute.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`PERMISSION_DENIED`: The key has no stream scope, or free keys are switched off. `PLAN_REQUIRED`: The plan of the key does not include the stream.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`NOT_FOUND`: Another path, or a request without the WebSocket upgrade headers.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"429":{"description":"`RATE_LIMITED`: Too many requests from the key or the address. Retry after `Retry-After` seconds.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"`INTERNAL`: The handshake failed on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`OVERLOADED`: The stream is restarting, or could not charge the first minute. Retry after `Retry-After` seconds.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-Api-Key"}},"headers":{"X-Request-Id":{"description":"The id of this request, as in our logs.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests per minute allowed for the key.","schema":{"type":"integer","minimum":0}},"RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the current minute ends.","schema":{"type":"integer","minimum":0}}},"schemas":{"Time":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$","description":"A time in RFC3339, UTC, with milliseconds: `2026-11-01T09:12:44.120Z`."},"Platform":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"Amount":{"type":"object","properties":{"value":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$","description":"An integer in base units, as a string, and negative below zero. Read it with a decimal or big integer type; a float loses digits."},"decimals":{"type":"integer","minimum":0,"maximum":36,"description":"The power of ten between base units and one whole unit: `value` ÷ 10^`decimals`."},"currency":{"type":"string","minLength":1,"description":"`USD`, or the token id (`tok_<network>_<address>`) of a token quantity."},"priceAsOf":{"description":"The time of the price we converted the value with. Absent when no price was used.","$ref":"#/components/schemas/Time"}},"required":["value","decimals","currency"],"description":"Money or a token quantity, never a JSON number. `{ \"value\": \"12345678\", \"decimals\": 6, \"currency\": \"USD\" }` is 12.345678 USD."},"Unavailable":{"type":"object","properties":{"status":{"type":"string","const":"unavailable","description":"Always `unavailable`."},"retryable":{"type":"boolean","description":"`true` when a later call can return the block."}},"required":["status","retryable"],"description":"Stands in for a capability block we could not read at the time of the call. The other blocks of the object are current."},"TraderEnvelope":{"type":"object","properties":{"kind":{"type":"string","const":"trader","description":"The kind of object, `trader` here, and the only field to switch on. Skip objects whose kind you do not know."},"id":{"type":"string","description":"Our id of the object, `tdr_` and 26 lowercase base32 characters. Store it: it stays the same across calls and never holds a platform's own id."},"canonical":{"type":"object","properties":{"display":{"anyOf":[{"type":"object","properties":{"handle":{"description":"`handle` of the newest `profile` block that has one, `null` when none has.","type":["string","null"]},"name":{"description":"`name` of the newest `profile` block that has one, `null` when none has.","type":["string","null"]},"avatarUrl":{"description":"`avatarUrl` of the newest `profile` block that has one, `null` when none has.","type":["string","null"]}},"required":["handle","name","avatarUrl"]},{"type":"null"}],"description":"What to show for the trader. Each field comes from the `profile` block with the newest `observedAt` among the blocks in `sources` whose field is not `null`; a tie goes to the platform key that sorts first. One field can come from another platform than the next. `null` when no profile exists."},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/Platform"},"description":"The platforms the trader holds an account on, sorted."},"mergedFrom":{"type":"array","items":{"type":"string"},"description":"The `tdr_` ids of traders merged into this one, sorted. A request for one of them answers with this trader."},"firstSeenAt":{"description":"When we first saw the trader.","$ref":"#/components/schemas/Time"},"walletAvailable":{"description":"`true` when `GET /v3/traders/{traderId}/wallets` lists at least one wallet for the trader, so its reveal returns an address; `false` when it lists none. Never the address. Sent by `GET /v3/traders/{traderId}` and `GET /v3/traders/lookup` at no extra charge and without a reveal, and absent from the trader envelopes of every other operation.","type":"boolean"}},"required":["display","platforms","mergedFrom","firstSeenAt"],"description":"Fields that mean the same on every platform."},"sources":{"type":"object","propertyNames":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"additionalProperties":{"type":"object","properties":{"profile":{"description":"The public profile of the account on this platform.","anyOf":[{"type":"object","properties":{"handle":{"description":"The handle on this platform, without `@`.","type":["string","null"]},"name":{"description":"The display name on this platform.","type":["string","null"]},"bio":{"description":"The profile text on this platform.","type":["string","null"]},"avatarUrl":{"description":"Our mirrored copy of the avatar (`/a/<key>.webp`), never the platform link.","type":["string","null"]},"xHandle":{"description":"The X handle the platform shows, without `@`.","type":["string","null"]},"verified":{"description":"The platform's own verified badge. We do not check it.","type":["boolean","null"]},"observedAt":{"description":"When we read this block from the platform. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["handle","name","bio","avatarUrl","xHandle","verified","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]},"followGraph":{"description":"Follower and following counts on this platform.","anyOf":[{"type":"object","properties":{"followers":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Followers on this platform, as the platform counts them."},"following":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Accounts this account follows, as the platform counts them."},"observedAt":{"description":"When we read this block from the platform. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["followers","following","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]},"tradingStats":{"description":"Trading figures the platform publishes. The platform's numbers, never ours.","anyOf":[{"type":"object","properties":{"swapCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Swaps the platform reports for the account."},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades the platform reports for the account."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Traded volume the platform reports, in USD."},"avgHoldSeconds":{"description":"The average time the account held a position, in seconds, as the platform reports.","type":["number","null"]},"observedAt":{"description":"When we read this block from the platform. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["swapCount","tradeCount","volume","avgHoldSeconds","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]}}},"description":"Capability blocks keyed by platform. A platform key is absent when the object has no side on that platform. A block is absent when the platform cannot provide it (`GET /v3/capabilities` lists which can) or we hold no reading of it yet. A field is `null` when the platform left it empty at `observedAt` or never fills it (`unfilled` in `GET /v3/capabilities`). Skip platform keys and blocks you do not know."}},"required":["kind","id","canonical","sources"],"description":"A trader: one person behind accounts on one or more platforms. The envelope carries no wallets; `GET /v3/traders/{traderId}/wallets` lists them."},"WalletEnvelope":{"type":"object","properties":{"kind":{"type":"string","const":"wallet","description":"The kind of object, `wallet` here, and the only field to switch on. Skip objects whose kind you do not know."},"id":{"type":"string","description":"Our id of the object, `wal_<family>_<address>`, family `svm` or `evm`. Store it: it stays the same across calls and never holds a platform's own id."},"canonical":{"type":"object","properties":{"family":{"type":"string","enum":["svm","evm"],"description":"`svm` for Solana addresses, `evm` for EVM addresses."},"address":{"type":"string","description":"The address. EVM addresses are lowercase."},"firstSeenAt":{"description":"When we first saw the wallet.","$ref":"#/components/schemas/Time"},"lastSeenAt":{"description":"When we last saw the wallet act or appear.","$ref":"#/components/schemas/Time"},"labels":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","enum":["treasury","fee_receiver","router","cosigner","custodial","exchange"],"description":"What the wallet is."},"platform":{"anyOf":[{"$ref":"#/components/schemas/Platform"},{"type":"null"}],"description":"The platform the label belongs to, or `null` for a label of no platform."},"observedAt":{"description":"When we set or last confirmed the label.","$ref":"#/components/schemas/Time"}},"required":["label","platform","observedAt"]},"description":"What we know the wallet is, if anything."},"owners":{"type":"array","items":{"type":"object","properties":{"trader":{"type":"string","description":"The `tdr_` id of the owner."},"tier":{"type":"string","enum":["proven","account","partial","weak","unverified"],"description":"How sure we are that the trader owns the wallet, strongest first: `proven` (an on-chain proof), `account` (the wallet is the key of the platform account), `partial` (a one-sided proof), `weak` (an ambiguous or imported link), `unverified`. The strongest tier over the trader's links, capped at `weak` when another trader also holds the wallet or the wallet carries a `custodial` or `exchange` label."},"links":{"type":"array","items":{"type":"object","properties":{"platform":{"description":"The platform of the account that holds the link.","$ref":"#/components/schemas/Platform"},"method":{"description":"The method behind the link, such as `svm_dual_proof`. It sets the tier. `null` for an unverified link.","type":["string","null"]},"firstVerifiedAt":{"description":"When we first verified the link.","$ref":"#/components/schemas/Time"},"lastVerifiedAt":{"description":"When we last verified the link.","$ref":"#/components/schemas/Time"}},"required":["platform","method","firstVerifiedAt","lastVerifiedAt"]},"description":"The trader's active links to the wallet."}},"required":["trader","tier","links"]},"description":"The traders who own the wallet: strongest tier first, then the earliest `firstVerifiedAt`, then trader id."}},"required":["family","address","firstSeenAt","lastSeenAt","labels","owners"],"description":"Fields that mean the same on every platform."},"sources":{"type":"object","propertyNames":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"additionalProperties":{"type":"object","properties":{}},"description":"Capability blocks keyed by platform. A platform key is absent when the object has no side on that platform. A block is absent when the platform cannot provide it (`GET /v3/capabilities` lists which can) or we hold no reading of it yet. A field is `null` when the platform left it empty at `observedAt` or never fills it (`unfilled` in `GET /v3/capabilities`). Skip platform keys and blocks you do not know."}},"required":["kind","id","canonical","sources"],"description":"A wallet address and the traders linked to it as owners, each with a tier."},"PostEnvelope":{"type":"object","properties":{"kind":{"type":"string","const":"post","description":"The kind of object, `post` here, and the only field to switch on. Skip objects whose kind you do not know."},"id":{"type":"string","description":"Our id of the object, `pst_` and 26 lowercase base32 characters. Store it: it stays the same across calls and never holds a platform's own id."},"canonical":{"type":"object","properties":{"platform":{"description":"The platform the post appeared on, and the one key of `sources`.","$ref":"#/components/schemas/Platform"},"author":{"anyOf":[{"type":"object","properties":{"trader":{"type":"string","description":"The `tdr_` id of the author."},"handle":{"description":"The author account's current handle.","type":["string","null"]}},"required":["trader","handle"]},{"type":"null"}],"description":"Who wrote the post. `null` when the platform did not say."},"token":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"The `tok_` id of the token."},"symbol":{"description":"The token symbol.","type":["string","null"]}},"required":["id","symbol"]},{"type":"null"}],"description":"The token the post is about. `null` for a post without a token."},"body":{"description":"The post text.","type":["string","null"]},"segments":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","description":"A run of text."},"url":{"description":"The link of the run, or `null` for plain text.","type":["string","null"]}},"required":["text","url"]},"description":"The body split into runs of text and links, in order. Empty for plain text."},"likeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Likes on the post."},"postedAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the author published the post, per the platform."},"firstSeenAt":{"description":"When we first read the post.","$ref":"#/components/schemas/Time"},"revision":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many edits we stored. 0 means the post was never edited."}},"required":["platform","author","token","body","segments","likeCount","postedAt","firstSeenAt","revision"],"description":"Fields that mean the same on every platform."},"sources":{"type":"object","propertyNames":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"additionalProperties":{"type":"object","properties":{"position":{"description":"The author's position in the post token, as the platform reports it.","anyOf":[{"type":"object","properties":{"quantity":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Tokens the author holds in the post token, in the token (currency is its `tok_` id)."},"value":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"What the position is worth, in USD."},"invested":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"What the author paid into the position, in USD."},"realizedPnl":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD."},"unrealizedPnl":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on the tokens still held, in USD."},"totalPnl":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Realized plus unrealized profit or loss, in USD."},"closed":{"description":"`true` once the author sold the whole position.","type":["boolean","null"]},"closedAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the author closed the position."},"observedAt":{"description":"When we read this block from the platform. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["quantity","value","invested","realizedPnl","unrealizedPnl","totalPnl","closed","closedAt","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]},"engagement":{"description":"Comment, reply, repost, quote and view counts.","anyOf":[{"type":"object","properties":{"commentCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Comments on the post."},"replyCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Replies to the post."},"repostCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Reposts of the post."},"quoteCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Posts that quote this post."},"viewCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Views of the post, as the platform counts them."},"observedAt":{"description":"When we read this block from the platform. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["commentCount","replyCount","repostCount","quoteCount","viewCount","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]},"callPerformance":{"description":"How the token moved since the post, as the platform reports it.","anyOf":[{"type":"object","properties":{"marketCapAtCall":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Market cap of the token when the post went out, in USD."},"priceAtCall":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Price of one whole token when the post went out, in USD with 18 decimals."},"multiple":{"description":"Current price over the price at the call: 2 means the token doubled.","type":["number","null"]},"maxMultiple":{"description":"The highest `multiple` the token reached since the call.","type":["number","null"]},"maxMultipleAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the token reached `maxMultiple`."},"mediaUrl":{"description":"Our mirrored copy of the image attached to the post.","type":["string","null"]},"quotedPost":{"description":"The `pst_` id of the post this post quotes.","type":["string","null"]},"observedAt":{"description":"When we read this block from the platform. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["marketCapAtCall","priceAtCall","multiple","maxMultiple","maxMultipleAt","mediaUrl","quotedPost","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]}}},"description":"Capability blocks keyed by platform. A platform key is absent when the object has no side on that platform. A block is absent when the platform cannot provide it (`GET /v3/capabilities` lists which can) or we hold no reading of it yet. A field is `null` when the platform left it empty at `observedAt` or never fills it (`unfilled` in `GET /v3/capabilities`). Skip platform keys and blocks you do not know."}},"required":["kind","id","canonical","sources"],"description":"A post (a call or thesis) about a token, from one platform."},"TokenEnvelope":{"type":"object","properties":{"kind":{"type":"string","const":"token","description":"The kind of object, `token` here, and the only field to switch on. Skip objects whose kind you do not know."},"id":{"type":"string","description":"Our id of the object, `tok_<network>_<address>`. Store it: it stays the same across calls and never holds a platform's own id."},"canonical":{"type":"object","properties":{"network":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"],"description":"The network the token lives on."},"address":{"type":"string","description":"The token address on that network (the mint on Solana)."},"symbol":{"description":"The token symbol.","type":["string","null"]},"name":{"description":"The token name.","type":["string","null"]},"decimals":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Decimals of the token: base units per whole token as a power of ten."},"imageUrl":{"description":"Our mirrored copy of the token image.","type":["string","null"]},"firstSeenAt":{"description":"When we first saw the token.","$ref":"#/components/schemas/Time"},"market":{"anyOf":[{"type":"object","properties":{"price":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD for one whole token, with 18 decimals."},"marketCap":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Market cap in USD, with 6 decimals."},"fdv":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Fully diluted value in USD, with 6 decimals."},"liquidity":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Liquidity in USD, with 6 decimals."},"volume24h":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Traded volume of the last 24 hours in USD, with 6 decimals."},"holders":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The number of wallets that hold the token."},"priceChange24h":{"description":"Change of the price over the last 24 hours in percent, rounded to 8 decimals: `12.5` is a rise of 12.5 %, `-40` a fall of 40 %.","type":["number","null"]},"observedAt":{"description":"When we read this block. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["price","marketCap","fdv","liquidity","volume24h","holders","priceChange24h","observedAt"]},{"type":"null"}],"description":"The token market across trading venues as our market data provider read it, every field as the provider sent it; `null` when we hold no such reading. `GET /v3/tokens/{network}/{address}` reads it when no platform shows the token and the reading we hold is missing or older than 5 minutes; every other answer serves the reading we hold. `observedAt` says how old it is."}},"required":["network","address","symbol","name","decimals","imageUrl","firstSeenAt","market"],"description":"Fields that mean the same on every platform."},"sources":{"type":"object","propertyNames":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"additionalProperties":{"type":"object","properties":{"market":{"description":"Price, market cap, liquidity, volume, holders and price change as the platform showed them in the newest reading we hold. A token keeps its last reading after it leaves the platform boards we read; `observedAt` says how old it is. A field listed under `unfilled` in `GET /v3/capabilities` is always `null`.","anyOf":[{"type":"object","properties":{"price":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD for one whole token, with 18 decimals."},"marketCap":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Market cap in USD, with 6 decimals."},"fdv":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Fully diluted value in USD, with 6 decimals."},"liquidity":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Liquidity in USD, with 6 decimals."},"volume24h":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Traded volume of the last 24 hours in USD, with 6 decimals."},"holders":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The number of wallets that hold the token."},"priceChange24h":{"description":"Change of the price over the last 24 hours in percent, rounded to 8 decimals: `12.5` is a rise of 12.5 %, `-40` a fall of 40 %.","type":["number","null"]},"observedAt":{"description":"When we read this block. Every value in the block is as of this time.","$ref":"#/components/schemas/Time"}},"required":["price","marketCap","fdv","liquidity","volume24h","holders","priceChange24h","observedAt"]},{"$ref":"#/components/schemas/Unavailable"}]}}},"description":"Capability blocks keyed by platform. A platform key is absent when the object has no side on that platform. A block is absent when the platform cannot provide it (`GET /v3/capabilities` lists which can) or we hold no reading of it yet. A field is `null` when the platform left it empty at `observedAt` or never fills it (`unfilled` in `GET /v3/capabilities`). Skip platform keys and blocks you do not know."}},"required":["kind","id","canonical","sources"],"description":"A token on one network."},"GroupEnvelope":{"type":"object","properties":{"kind":{"type":"string","const":"group","description":"The kind of object, `group` here, and the only field to switch on. Skip objects whose kind you do not know."},"id":{"type":"string","description":"Our id of the object, `grp_` and 26 lowercase base32 characters. Store it: it stays the same across calls and never holds a platform's own id."},"canonical":{"type":"object","properties":{"platform":{"description":"The platform that hosts the group.","$ref":"#/components/schemas/Platform"},"name":{"description":"The group name.","type":["string","null"]},"description":{"description":"The group text, as the platform shows it.","type":["string","null"]},"imageUrl":{"description":"Our mirrored copy of the group image.","type":["string","null"]},"memberCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Members, as the platform counts them."},"firstSeenAt":{"description":"When we first saw the group.","$ref":"#/components/schemas/Time"},"observedAt":{"description":"When we last read the group from the platform.","$ref":"#/components/schemas/Time"}},"required":["platform","name","description","imageUrl","memberCount","firstSeenAt","observedAt"],"description":"Fields that mean the same on every platform."},"sources":{"type":"object","propertyNames":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"additionalProperties":{"type":"object","properties":{}},"description":"Capability blocks keyed by platform. A platform key is absent when the object has no side on that platform. A block is absent when the platform cannot provide it (`GET /v3/capabilities` lists which can) or we hold no reading of it yet. A field is `null` when the platform left it empty at `observedAt` or never fills it (`unfilled` in `GET /v3/capabilities`). Skip platform keys and blocks you do not know."}},"required":["kind","id","canonical","sources"],"description":"A group of traders a platform runs, such as a clan. Appears as a board subject."},"TradeEnvelope":{"type":"object","properties":{"kind":{"type":"string","const":"trade","description":"The kind of object, `trade` here, and the only field to switch on. Skip objects whose kind you do not know."},"id":{"type":"string","description":"Our id of the object, `trd_` and 26 lowercase base32 characters. Store it: it stays the same across calls and never holds a platform's own id."},"canonical":{"type":"object","properties":{"network":{"type":"string","enum":["solana","ethereum","base","bsc","arbitrum","optimism","polygon","robinhood","hyperevm","monad","arc","xlayer","ink","hyperliquid"],"description":"The network of the transaction."},"txHash":{"type":"string","description":"The transaction hash (the signature on Solana)."},"blockNumber":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The block, or the slot on Solana."},"executedAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"The block time of the transaction."},"wallet":{"type":"string","description":"The `wal_` id of the wallet that traded."},"side":{"type":"string","enum":["buy","sell","swap"],"description":"`buy` and `sell` trade `token` against `quoteToken`; `swap` trades two tokens."},"token":{"type":"string","description":"The `tok_` id of the token traded."},"quantity":{"description":"How much of `token` moved, in that token.","$ref":"#/components/schemas/Amount"},"quoteToken":{"description":"The `tok_` id of the token paid or received for it.","type":["string","null"]},"quoteQuantity":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"How much of `quoteToken` moved, in that token."},"platform":{"anyOf":[{"$ref":"#/components/schemas/Platform"},{"type":"null"}],"description":"The platform that routed the trade, when we can tell."},"verification":{"type":"string","enum":["chain","relay"],"description":"`chain`: we read it from the chain. `relay`: a relay reported it and the chain has not confirmed it yet."},"owner":{"anyOf":[{"type":"object","properties":{"trader":{"type":"string","description":"The `tdr_` id of the owner."},"handle":{"description":"The owner's `canonical.display.handle`.","type":["string","null"]},"tier":{"type":"string","enum":["proven","account","partial","weak","unverified"],"description":"How sure we are that the trader owns the wallet, strongest first: `proven` (an on-chain proof), `account` (the wallet is the key of the platform account), `partial` (a one-sided proof), `weak` (an ambiguous or imported link), `unverified`."}},"required":["trader","handle","tier"]},{"type":"null"}],"description":"The trader the operation shows as the owner of `wallet`. `null` on `GET /v3/wallets/{family}/{address}/trades`."}},"required":["network","txHash","blockNumber","executedAt","wallet","side","token","quantity","quoteToken","quoteQuantity","platform","verification","owner"],"description":"Fields that mean the same on every platform."},"sources":{"type":"object","propertyNames":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]},"additionalProperties":{"type":"object","properties":{}},"description":"Capability blocks keyed by platform. A platform key is absent when the object has no side on that platform. A block is absent when the platform cannot provide it (`GET /v3/capabilities` lists which can) or we hold no reading of it yet. A field is `null` when the platform left it empty at `observedAt` or never fills it (`unfilled` in `GET /v3/capabilities`). Skip platform keys and blocks you do not know."}},"required":["kind","id","canonical","sources"],"description":"One on-chain swap by one wallet. Quantities only; prices come from the token."},"SubjectEnvelope":{"oneOf":[{"$ref":"#/components/schemas/TraderEnvelope"},{"$ref":"#/components/schemas/TokenEnvelope"},{"$ref":"#/components/schemas/GroupEnvelope"}]},"TraderCollection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TraderEnvelope"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["items","hasMore","nextCursor"],"description":"One page of a list. Pass `nextCursor` back as `cursor` for the next page."},"TraderSuggestion":{"type":"object","properties":{"trader":{"description":"The suggested trader, as its envelope.","$ref":"#/components/schemas/TraderEnvelope"},"platform":{"description":"The platform of the account that made the suggestion.","$ref":"#/components/schemas/Platform"},"handle":{"description":"The handle of that account, `null` when it has none and its name matched.","type":["string","null"]},"name":{"description":"The name of that account, `null` when it has none.","type":["string","null"]}},"required":["trader","platform","handle","name"],"description":"A trader whose handle or name is close to the handle looked up."},"TraderLookup":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TraderEnvelope"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]},"match":{"type":"string","enum":["exact","closest"],"description":"`exact`: the items hold the handle or held it in the last 30 days, or the page is empty. `closest`: no trader does, and the only item is the first of `suggestions`."},"suggestions":{"description":"Present on a first page where no trader holds or held the handle: up to 5 traders whose handle or name is close to it, or whose handle starts with it, best first. Empty when the handle has fewer than 3 characters once spaces are dropped, or nothing is close.","maxItems":5,"type":"array","items":{"$ref":"#/components/schemas/TraderSuggestion"}}},"required":["items","hasMore","nextCursor","match"],"description":"The traders that hold or held the handle, one page of them, with `suggestions` when none does."},"WalletCollection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WalletEnvelope"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["items","hasMore","nextCursor"],"description":"One page of a list. Pass `nextCursor` back as `cursor` for the next page."},"PostCollection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PostEnvelope"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["items","hasMore","nextCursor"],"description":"One page of a list. Pass `nextCursor` back as `cursor` for the next page."},"TradeCollection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TradeEnvelope"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["items","hasMore","nextCursor"],"description":"One page of a list. Pass `nextCursor` back as `cursor` for the next page."},"LeaderboardSummary":{"type":"object","properties":{"platform":{"description":"The platform that publishes the board.","$ref":"#/components/schemas/Platform"},"board":{"type":"string","description":"The board name, unique within its platform."},"category":{"type":"string","enum":["perp_trading","spot_trading","prediction","content","impressions","social","referrals","tokens","groups"],"description":"What the board or ranking ranks."},"metric":{"anyOf":[{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"]},{"type":"null"}],"description":"The metric the board sorts by, or `null` when the platform does not say."},"windows":{"type":"array","items":{"type":"string","enum":["24h","7d","30d","90d","all"]},"description":"The windows the board takes as `window`. Empty for a board without windows."},"defaultWindow":{"anyOf":[{"type":"string","enum":["24h","7d","30d","90d","all"]},{"type":"null"}],"description":"The window you get without `window`, or `null` for a board without windows."},"subjectType":{"type":"string","enum":["trader","token","group"],"description":"The kind of every entry subject."},"latestCapturedAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"The newest capture over all windows of the board, or `null` before the first."}},"required":["platform","board","category","metric","windows","defaultWindow","subjectType","latestCapturedAt"],"description":"A leaderboard a platform publishes, which we capture as it shows it."},"LeaderboardCollection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LeaderboardSummary"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["items","hasMore","nextCursor"],"description":"One page of a list. Pass `nextCursor` back as `cursor` for the next page."},"LeaderboardDocument":{"type":"object","properties":{"platform":{"description":"The platform that publishes the board.","$ref":"#/components/schemas/Platform"},"board":{"type":"string","description":"The board name, unique within its platform."},"category":{"type":"string","enum":["perp_trading","spot_trading","prediction","content","impressions","social","referrals","tokens","groups"],"description":"What the board or ranking ranks."},"metric":{"anyOf":[{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"]},{"type":"null"}],"description":"The metric the board sorts by, or `null` when the platform does not say."},"window":{"anyOf":[{"type":"string","enum":["24h","7d","30d","90d","all"]},{"type":"null"}],"description":"The window of this capture, or `null` for a board without windows."},"capturedAt":{"description":"When we captured the board.","$ref":"#/components/schemas/Time"},"entryCount":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Entries the capture stored. `entries` leaves out a subject we cannot read."},"entries":{"type":"array","items":{"type":"object","properties":{"rank":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The rank the platform showed. 1 is the top of the board."},"subject":{"description":"The trader, token or group at this rank, as its envelope.","$ref":"#/components/schemas/SubjectEnvelope"},"measures":{"type":"object","propertyNames":{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"]},"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"number"}]},"description":"Figures of the entry keyed by metric. Money is an `Amount`; ratios and counts are numbers. A metric the source did not store is absent."}},"required":["rank","subject","measures"]},"description":"The entries of the capture by rank, not paged. An entry whose subject we cannot read is left out, so `entries` can hold fewer rows than `entryCount`."}},"required":["platform","board","category","metric","window","capturedAt","entryCount","entries"],"description":"One capture of a platform leaderboard, as the platform showed it."},"RankingSummary":{"type":"object","properties":{"key":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."},"title":{"type":"string","description":"A title to show."},"subjectType":{"type":"string","enum":["trader","token","group"],"description":"The kind of every entry subject."},"category":{"type":"string","enum":["perp_trading","spot_trading","prediction","content","impressions","social","referrals","tokens","groups"],"description":"What the board or ranking ranks."},"metric":{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"],"description":"The metric the ranking orders by."},"window":{"anyOf":[{"type":"string","enum":["24h","7d","30d","90d","all"]},{"type":"null"}],"description":"The time window of the metric, or `null` for no window."},"size":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The most entries one snapshot returns."},"latestComputedAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When we computed the newest snapshot, or `null` before the first."}},"required":["key","title","subjectType","category","metric","window","size","latestComputedAt"],"description":"A ranking we compute from our own data."},"RankingCollection":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RankingSummary"},"description":"The rows of this page, in the order the operation states."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["items","hasMore","nextCursor"],"description":"One page of a list. Pass `nextCursor` back as `cursor` for the next page."},"RankingDocument":{"type":"object","properties":{"key":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."},"title":{"type":"string","description":"A title to show."},"category":{"type":"string","enum":["perp_trading","spot_trading","prediction","content","impressions","social","referrals","tokens","groups"],"description":"What the board or ranking ranks."},"metric":{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"],"description":"The metric the ranking orders by."},"window":{"anyOf":[{"type":"string","enum":["24h","7d","30d","90d","all"]},{"type":"null"}],"description":"The time window of the metric, or `null` for no window."},"order":{"type":"string","enum":["best","worst"],"description":"`best`: the top entries. `worst`: the bottom entries, lowest value first."},"dataAsOf":{"description":"The time of the newest data the snapshot used.","$ref":"#/components/schemas/Time"},"computedAt":{"description":"When we computed the snapshot.","$ref":"#/components/schemas/Time"},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Subjects ranked. `entries` holds at most `size` of them."},"entries":{"type":"array","items":{"type":"object","properties":{"rank":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a better value. Ties share a rank."},"subject":{"description":"The subject at this rank, as its envelope.","$ref":"#/components/schemas/SubjectEnvelope"},"value":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"number"}],"description":"The value of `metric`: an `Amount` for money, a number for the rest."},"measures":{"type":"object","propertyNames":{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"]},"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"number"}]},"description":"Figures of the entry keyed by metric. Money is an `Amount`; ratios and counts are numbers. A metric the source did not store is absent."}},"required":["rank","subject","value","measures"]},"description":"The entries in `order`. Not paged."}},"required":["key","title","category","metric","window","order","dataAsOf","computedAt","total","entries"],"description":"The newest snapshot of one of our rankings."},"PnlDocument":{"type":"object","properties":{"trader":{"type":"string","description":"The `tdr_` id of the trader, after merges."},"status":{"type":"string","enum":["ready","pending","failed","no_wallet","unavailable"],"description":"`ready`: figures present. Only this status takes a reveal. `pending`: no reading yet; call again after `retryAfterSeconds`. `failed`: the last read failed; call again after `retryAfterSeconds`. `no_wallet`: the trader holds no verified wallet (tier `proven`, `account` or `partial`) that no other trader also holds. `unavailable`: provider reads are off or this month's provider budget is spent."},"retryAfterSeconds":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Seconds to wait before you ask again while `status` is `pending` or `failed`; else `null`."},"wallets":{"type":"array","items":{"type":"string"},"description":"The `wal_` ids the figures cover, at most one per address family. Empty unless `status` is `ready`."},"windows":{"type":"object","properties":{"24h":{"description":"The last 24 hours, from our data provider.","type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},"7d":{"description":"The last 7 days, from our data provider.","type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},"30d":{"description":"The last 30 days, from our data provider.","type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},"all":{"description":"All time, computed by us. `null` when we hold no figure.","anyOf":[{"type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},{"type":"null"}]}},"description":"One entry per window. With `window` set, only that key is present."},"unrealized":{"anyOf":[{"type":"object","properties":{"origin":{"type":"string","const":"provider","description":"Always `provider`: our data provider reads it."},"value":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on the tokens still held, in USD. `null` when not known."},"holdingsValue":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"What the held tokens are worth, in USD. `null` when not known."},"positions":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Positions counted. `null` when not known."},"excludedPositions":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Positions left out, such as tokens without a price. `null` when not known."},"asOf":{"description":"When our data provider read the wallets.","$ref":"#/components/schemas/Time"}},"required":["origin","value","holdingsValue","positions","excludedPositions","asOf"]},{"type":"null"}],"description":"Unrealized profit or loss over the wallets, from our data provider. `null` without a reading."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"The oldest `asOf` among the ready windows, else the ranking time of `all`, else `null`."},"nextUpdateAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the first figure from our data provider falls due to be read again: its `asOf` plus its refresh interval. The first call after that time reads it again. Earlier than now when `stale` is `true`. `null` unless `status` is `ready`."},"stale":{"type":"boolean","description":"`true` when at least one figure from our data provider is past its refresh interval and this call could not read it again: the read failed, did not finish within the 8 second wait, or this month's provider budget is spent. A later call can carry newer figures. The computed `all` window does not count. `false` unless `status` is `ready`."}},"required":["trader","status","retryAfterSeconds","wallets","windows","unrealized","asOf","nextUpdateAt","stale"],"description":"A trader's profit and loss over the wallets we verified for them, per window."},"PnlBulk":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"trader":{"type":"string","description":"The id as you sent it."},"found":{"type":"boolean","description":"`false` when no trader has this id."},"pnl":{"anyOf":[{"$ref":"#/components/schemas/PnlDocument"},{"type":"null"}],"description":"The PnL document, or `null` when not found."}},"required":["trader","found","pnl"]},"description":"One item per distinct id you sent, in your order."}},"required":["items"],"description":"The PnL of several traders, one item per id."},"WalletPnlDocument":{"type":"object","properties":{"wallet":{"type":"string","description":"The `wal_` id of the wallet asked for."},"wallets":{"type":"array","items":{"type":"string"},"description":"The `wal_` ids the figures cover, one per address family, Solana first: the wallet asked for and, when a platform keys it to an account of one trader, the wallet of the other family the same trader holds as an account key on that platform. Listed whatever the status."},"status":{"type":"string","enum":["ready","pending","failed","unavailable"],"description":"`ready`: figures present. `pending`: no reading yet; call again after `retryAfterSeconds`. `failed`: the last read failed; call again after `retryAfterSeconds`. `unavailable`: provider reads are off or this month's provider budget is spent."},"retryAfterSeconds":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Seconds to wait before you ask again while `status` is `pending` or `failed`; else `null`."},"windows":{"type":"object","properties":{"24h":{"description":"The last 24 hours, from our data provider.","type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},"7d":{"description":"The last 7 days, from our data provider.","type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},"30d":{"description":"The last 30 days, from our data provider.","type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},"all":{"description":"All time, computed by us. `null` when we hold no figure.","anyOf":[{"type":"object","properties":{"origin":{"type":"string","enum":["computed","provider"],"description":"`provider`: figures of the whole wallets from our data provider, every venue. `computed`: our figures from the trades and rankings we compute."},"status":{"type":"string","enum":["ready","pending"],"description":"`ready`: the values hold a reading. `pending`: no reading yet, and every value is `null`."},"realized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss taken by selling, in USD. `null` when not known."},"unrealized":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on tokens still held, in USD. On `24h`, `7d` and `30d`: the open positions last traded inside the window, on UTC calendar days (`24h` from 00:00 UTC today, `7d` and `30d` from 00:00 UTC 6 and 29 days before), from the reading of the top `unrealized`, which leaves out the same positions. On `all`: our own figure from the trades we hold, on a wallet. `null` when not known, and on the `all` of a trader."},"total":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"`realized` plus `unrealized`, in USD: one formula on every window. `null` when either is `null`."},"unpricedProceeds":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Proceeds of tokens sold beyond the position we saw them buy, in USD. `null` when not known."},"netFlow":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells minus USD paid for buys, in USD. `null` when not known."},"volume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Buy volume plus sell volume, in USD. `null` when not known."},"buyVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD paid for buys, in USD. `null` when not known."},"sellVolume":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"USD received from sells, in USD. `null` when not known."},"returnPct":{"description":"Return in percent, rounded to 8 decimals: 10 means a 10 % gain. `null` when the base is zero or not known.","type":["number","null"]},"tradeCount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Trades in the window. `null` when not known."},"buys":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Buys in the window. `null` when not known."},"sells":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sells in the window. `null` when not known."},"tokensTraded":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Distinct tokens traded in the window. `null` when not known."},"winningTokens":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Tokens closed at a profit in the window. `null` when not known."},"rank":{"anyOf":[{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"1 plus the number of subjects with a higher value. Ties share a position."},"of":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Subjects in the ranking."},"ranking":{"type":"string","description":"The ranking key, for `GET /v3/rankings/{key}`."}},"required":["position","of","ranking"]},{"type":"null"}],"description":"Where the trader stands in our ranking for this window. Set on a trader's `all`; `null` on the other windows and on a wallet."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the figures were read or computed. `null` while `pending`."},"approximate":{"type":"boolean","description":"`true` when our data provider could not read this window and we counted it from per-token totals of the wallets' positions instead: each token's whole realized profit, volume and trade count lands in the window of its last trade, so `24h`, `7d` and `30d` can show more than happened inside them. The next reading of the window replaces these figures. `false` otherwise, while `pending`, and on a computed window."}},"required":["origin","status","realized","unrealized","total","unpricedProceeds","netFlow","volume","buyVolume","sellVolume","returnPct","tradeCount","buys","sells","tokensTraded","winningTokens","rank","asOf","approximate"]},{"type":"null"}]}},"description":"One entry per window. With `window` set, only that key is present."},"unrealized":{"anyOf":[{"type":"object","properties":{"origin":{"type":"string","const":"provider","description":"Always `provider`: our data provider reads it."},"value":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"Profit or loss on the tokens still held, in USD. `null` when not known."},"holdingsValue":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"null"}],"description":"What the held tokens are worth, in USD. `null` when not known."},"positions":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Positions counted. `null` when not known."},"excludedPositions":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Positions left out, such as tokens without a price. `null` when not known."},"asOf":{"description":"When our data provider read the wallets.","$ref":"#/components/schemas/Time"}},"required":["origin","value","holdingsValue","positions","excludedPositions","asOf"]},{"type":"null"}],"description":"Unrealized profit or loss of the wallet, from our data provider. `null` without a reading."},"asOf":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"The oldest `asOf` among the ready windows, else the ranking time of `all`, else `null`."},"nextUpdateAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When the first figure from our data provider falls due to be read again: its `asOf` plus its refresh interval. The first call after that time reads it again. Earlier than now when `stale` is `true`. `null` unless `status` is `ready`."},"stale":{"type":"boolean","description":"`true` when at least one figure from our data provider is past its refresh interval and this call could not read it again: the read failed, did not finish within the 8 second wait, or this month's provider budget is spent. A later call can carry newer figures. The computed `all` window does not count. `false` unless `status` is `ready`."},"boards":{"type":"array","items":{"type":"object","properties":{"platform":{"description":"The platform that publishes the board.","$ref":"#/components/schemas/Platform"},"board":{"type":"string","description":"The board, as `GET /v3/leaderboards` lists it."},"window":{"description":"The window of the board this standing is on. `null` on a board without windows.","type":["string","null"]},"rank":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The rank the platform gives the account on that capture."},"measures":{"type":"object","propertyNames":{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"]},"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/Amount"},{"type":"number"}]},"description":"Figures of the entry keyed by metric. Money is an `Amount`; ratios and counts are numbers. A metric the source did not store is absent."},"capturedAt":{"description":"When we captured the board.","$ref":"#/components/schemas/Time"}},"required":["platform","board","window","rank","measures","capturedAt"]},"description":"Where the accounts keyed by these wallets stand on the newest capture of each platform board that ranks accounts, as the platform shows it, for reference. The platform computes these itself; they need not match the windows above. Empty when no board lists them."}},"required":["wallet","wallets","status","retryAfterSeconds","windows","unrealized","asOf","nextUpdateAt","stale","boards"],"description":"The profit and loss of one wallet, per window. Names no owner."},"WalletPnlBulk":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"wallet":{"type":"string","description":"The `wal_` id of the wallet you sent, normalized."},"found":{"type":"boolean","description":"`false` when we never saw this wallet."},"pnl":{"anyOf":[{"$ref":"#/components/schemas/WalletPnlDocument"},{"type":"null"}],"description":"The wallet PnL document, or `null` when not found."}},"required":["wallet","found","pnl"]},"description":"One item per distinct wallet you sent, in your order."}},"required":["items"],"description":"The PnL of several wallets, one item per wallet."},"MeDocument":{"type":"object","properties":{"key":{"type":"object","properties":{"prefix":{"type":"string","description":"The first characters of the key, safe to log."},"name":{"type":"string","description":"The name given to the key."},"environment":{"type":"string","enum":["live","sandbox"],"description":"`live` or `sandbox`."}},"required":["prefix","name","environment"],"description":"The key that made this call."},"plan":{"type":"string","description":"The plan of the key."},"scopes":{"type":"array","items":{"type":"string"},"description":"What the key may call."},"api":{"type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-\\d{2}$","description":"The billing month, `YYYY-MM` in UTC. Counters start at zero each month."},"monthlyUnits":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Credits the plan grants each month."},"additionalUnits":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Credits bought on top for this month."},"unitsUsed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Credits spent this month, REST and the stream together, read from the stored counter. The newest calls can be missing from it."},"unitsRemaining":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Credits left this month, never below 0. `null` for an unmetered key."},"unmetered":{"type":"boolean","description":"`true` when the key is counted and never refused for credit."},"ratePerMinute":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Requests per minute the key may make. 0 means no limit."},"monthlyReveals":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Reveals the key may take each month. `null` means no cap."},"revealsUsed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Reveals taken this month."},"revealsRemaining":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Reveals left this month. `null` with no cap or for an unmetered key."}},"required":["period","monthlyUnits","additionalUnits","unitsUsed","unitsRemaining","unmetered","ratePerMinute","monthlyReveals","revealsUsed","revealsRemaining"],"description":"Credits and reveals of REST calls and the stream."},"websocket":{"type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-\\d{2}$","description":"The billing month, `YYYY-MM` in UTC. Counters start at zero each month."},"minutesUsed":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Always `null`: stream minutes are credits and count in `api.unitsUsed`."},"minutesIncluded":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Always `null`: stream minutes are credits and count in `api.unitsUsed`."},"unlimited":{"type":"boolean","description":"`true` for an unmetered key."}},"required":["period","minutesUsed","minutesIncluded","unlimited"],"description":"The stream counter. Stream minutes bill as credits on `api`."}},"required":["key","plan","scopes","api","websocket"],"description":"The calling key, its plan, and what it used this month."},"CapabilitiesDocument":{"type":"object","properties":{"kinds":{"type":"object","propertyNames":{"type":"string","enum":["trader","wallet","post","trade","token","group"]},"additionalProperties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"platforms":{"type":"array","items":{"$ref":"#/components/schemas/Platform"},"description":"The platforms that provide the block, sorted."},"unfilled":{"type":"object","propertyNames":{"$ref":"#/components/schemas/Platform"},"additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Per platform, the fields of the block that platform never fills. They are always `null` there."}},"required":["platforms","unfilled"]}},"required":["trader","wallet","post","trade","token","group"],"description":"Per kind, per block name: which platforms provide the block. A block a platform does not provide never appears under that platform in `sources`."},"leaderboards":{"type":"array","items":{"type":"object","properties":{"platform":{"description":"The platform that publishes the board.","$ref":"#/components/schemas/Platform"},"board":{"type":"string","description":"The board name, unique within its platform."},"category":{"type":"string","enum":["perp_trading","spot_trading","prediction","content","impressions","social","referrals","tokens","groups"],"description":"What the board or ranking ranks."},"metric":{"anyOf":[{"type":"string","enum":["pnl","net_flow","portfolio_value","price","liquidity","roi","volume","trade_count","win_rate","impressions","views","likes","followers","holders","market_cap","members","points","realized_pnl","unrealized_pnl"]},{"type":"null"}],"description":"The metric the board sorts by, or `null` when the platform does not say."},"windows":{"type":"array","items":{"type":"string","enum":["24h","7d","30d","90d","all"]},"description":"The windows the board takes as `window`. Empty for a board without windows."},"defaultWindow":{"anyOf":[{"type":"string","enum":["24h","7d","30d","90d","all"]},{"type":"null"}],"description":"The window you get without `window`, or `null` for a board without windows."},"subjectType":{"type":"string","enum":["trader","token","group"],"description":"The kind of every entry subject."}},"required":["platform","board","category","metric","windows","defaultWindow","subjectType"]},"description":"Every leaderboard we capture, by platform and board."}},"required":["kinds","leaderboards"],"description":"Which platform provides which block and which boards, from the registry the API serves from."},"FollowListDocument":{"type":"object","properties":{"trader":{"type":"string","description":"The `tdr_` id of the trader, after merges."},"direction":{"type":"string","enum":["followers","following"],"description":"`followers`: who follows the trader. `following`: whom the trader follows."},"counts":{"type":"object","propertyNames":{"$ref":"#/components/schemas/Platform"},"additionalProperties":{"type":"object","properties":{"reported":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"The platform's own count, as `followGraph` shows it. `null` without a reading."},"stored":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Edges we hold on this platform: the rows this list pages through."},"observedAt":{"anyOf":[{"$ref":"#/components/schemas/Time"},{"type":"null"}],"description":"When we read `reported`. `null` without a reading."}},"required":["reported","stored","observedAt"]},"description":"One entry per platform the list covers. `stored` against `reported` says how much of the platform list we hold."},"items":{"type":"array","items":{"type":"object","properties":{"subject":{"description":"The other trader of the edge, as its envelope.","$ref":"#/components/schemas/TraderEnvelope"},"platform":{"description":"The platform the edge is on.","$ref":"#/components/schemas/Platform"},"observedAt":{"description":"When a crawl last saw the edge.","$ref":"#/components/schemas/Time"}},"required":["subject","platform","observedAt"]},"description":"The edges of this page, newest `observedAt` first."},"hasMore":{"type":"boolean","description":"`true` when another page follows this one."},"nextCursor":{"description":"The cursor of the next page (`c_…`), or `null` on the last page. Treat it as opaque: send it back as `cursor`, never parse or build it.","type":["string","null"]}},"required":["trader","direction","counts","items","hasMore","nextCursor"],"description":"One page of a trader's followers or following, with the counts per platform."},"ErrorBody":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication","quota","permission","rate_limit","internal","overloaded"],"description":"The group of the error. Each `code` belongs to one type."},"code":{"type":"string","enum":["INVALID_ARGUMENT","UNAUTHENTICATED","QUOTA_EXCEEDED","REVEAL_LIMIT_REACHED","PERMISSION_DENIED","PLAN_REQUIRED","NOT_FOUND","RATE_LIMITED","INTERNAL","OVERLOADED"],"description":"What went wrong, from a closed list. Act on this field."},"message":{"type":"string","description":"A sentence for people. It can change; never parse it."},"requestId":{"type":"string","description":"The id of the request, equal to `X-Request-Id`. Quote it when you write to us."}},"required":["type","code","message","requestId"],"description":"The error."}},"required":["error"],"description":"The body of every error answer."},"StreamSubscription":{"type":"object","properties":{"topic":{"type":"string","enum":["posts"]},"platforms":{"anyOf":[{"minItems":1,"type":"array","items":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},{"type":"null"}]},"tokens":{"anyOf":[{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["topic","platforms","tokens"]},"StreamSubscribeFrame":{"type":"object","properties":{"type":{"type":"string","const":"subscribe"},"topic":{"type":"string","enum":["posts"]},"platforms":{"minItems":1,"type":"array","items":{"type":"string","enum":["fomo","pump","hyperliquid","markets","polymarket","legend","risex"]}},"tokens":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string"}},"since":{"type":"string","pattern":"^s_[A-Za-z0-9_-]+$"}},"required":["type","topic"],"additionalProperties":false},"StreamUnsubscribeFrame":{"type":"object","properties":{"type":{"type":"string","const":"unsubscribe"}},"required":["type"],"additionalProperties":false},"StreamClientFrame":{"oneOf":[{"$ref":"#/components/schemas/StreamSubscribeFrame"},{"$ref":"#/components/schemas/StreamUnsubscribeFrame"}]},"StreamReadyFrame":{"type":"object","properties":{"type":{"type":"string","const":"ready"},"connectionId":{"type":"string"}},"required":["type","connectionId"]},"StreamSubscribedFrame":{"type":"object","properties":{"type":{"type":"string","const":"subscribed"},"subscription":{"$ref":"#/components/schemas/StreamSubscription"},"replaced":{"anyOf":[{"$ref":"#/components/schemas/StreamSubscription"},{"type":"null"}]}},"required":["type","subscription","replaced"]},"StreamUnsubscribedFrame":{"type":"object","properties":{"type":{"type":"string","const":"unsubscribed"},"replaced":{"anyOf":[{"$ref":"#/components/schemas/StreamSubscription"},{"type":"null"}]}},"required":["type","replaced"]},"StreamPostFrame":{"type":"object","properties":{"type":{"type":"string","const":"post"},"cursor":{"type":"string","pattern":"^s_[A-Za-z0-9_-]+$"},"item":{"$ref":"#/components/schemas/PostEnvelope"}},"required":["type","cursor","item"]},"StreamReplayDoneFrame":{"type":"object","properties":{"type":{"type":"string","const":"replay_done"},"cursor":{"type":"string","pattern":"^s_[A-Za-z0-9_-]+$"}},"required":["type","cursor"]},"StreamErrorFrame":{"type":"object","properties":{"type":{"type":"string","const":"error"},"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication","quota","permission","rate_limit","internal","overloaded"],"description":"The group of the error. Each `code` belongs to one type."},"code":{"type":"string","enum":["INVALID_ARGUMENT","UNAUTHENTICATED","QUOTA_EXCEEDED","REVEAL_LIMIT_REACHED","PERMISSION_DENIED","PLAN_REQUIRED","NOT_FOUND","RATE_LIMITED","INTERNAL","OVERLOADED"],"description":"What went wrong, from a closed list. Act on this field."},"message":{"type":"string","description":"A sentence for people. It can change; never parse it."},"requestId":{"type":"string","description":"The id of the request, equal to `X-Request-Id`. Quote it when you write to us."}},"required":["type","code","message","requestId"],"description":"The error."}},"required":["type","error"]},"StreamServerFrame":{"oneOf":[{"$ref":"#/components/schemas/StreamReadyFrame"},{"$ref":"#/components/schemas/StreamSubscribedFrame"},{"$ref":"#/components/schemas/StreamUnsubscribedFrame"},{"$ref":"#/components/schemas/StreamPostFrame"},{"$ref":"#/components/schemas/StreamReplayDoneFrame"},{"$ref":"#/components/schemas/StreamErrorFrame"}]}}},"tags":[{"name":"Traders"},{"name":"Wallets"},{"name":"Posts"},{"name":"Tokens"},{"name":"Leaderboards"},{"name":"Rankings"},{"name":"Account"},{"name":"Trades"},{"name":"WebSocket","description":"The live stream: one socket for every platform, platform and token filters, and a replay of the last 5 minutes."}]}