Skip to main content
Largest holders of each outcome token for one or more markets. Use it to render a holder leaderboard beside a market. Full parameter reference and a live tester: API Reference.

Base URL

Authentication

x-kairos-auth: api-key. Send the API-key triple (X-Client-Id, X-Api-Key, X-Api-Secret), a first-party session JWT, or an X-Admin-Secret. Sending no credentials returns 401 Authentication required (JWT token / API key / admin secret). No API-key scope is required — any active credential can read holders. Session-JWT callers additionally pass the invite gate (403 Invite required if they haven’t); API-key and admin-secret callers bypass it. Rate-limited by the heavy group at 10 requests/minute (keyed by authenticated user id when a JWT session is present, otherwise by trusted client IP). Live upstream reads share this budget with /search-traders and /trader-stats/*. An API key with a per-credential data override is also checked against that absolute ceiling. Examples below read credentials from KAIROS_CLIENT_ID, KAIROS_API_KEY, and KAIROS_API_SECRET in your shell.

Top holders

Returns the largest holders per outcome token for the markets you name. Auth: API key, JWT, or X-Admin-Secret (no scope). Rate limit: heavy group, 10 requests/minute. This is a live upstream read (e.g. Polymarket’s data-api holders endpoint) — no local cache sits in front of it.

Request

market accepts up to 50 comma-separated IDs, 128 characters each — an empty value, more than 50 IDs, or an oversized ID all return 400. Omitting market entirely is a schema failure, so that returns 422, not 400.
Gotcha: an empty market and a missing market fail differently. market= is 400; leaving the parameter off entirely is 422.
For polymarket, non-0x IDs are first resolved to condition IDs via the market metadata cache and ClickHouse. IDs that don’t resolve are skipped silently; if none resolve the response is an empty array with 200, not a 404.
Gotcha: unresolvable IDs are dropped without any signal. Compare the token values you get back against the ids you sent — a short array does not mean a short holder list, it may mean ids were skipped, and an all-unresolvable request is an empty 200.
provider is validated against the registered venue list, but only venues with a top-holders client (polymarket, opinion, predictfun) can actually be served — any other registered venue returns 400 Invalid top holders request parameters.

Response

The body is a bare array, one entry per requested market/token combination the provider returned — not wrapped in an object.
Gotcha: amount is shares, not dollars. Multiply by the outcome token’s price to get a USD figure.

Errors

Errors are returned as { "detail": "<message>" }, except the local rate limiter’s 429, which uses { "error": "Rate limit exceeded: <limit>" }. The Code column holds the exact detail string where this endpoint documents one, otherwise —.