---
title: "Top holders per outcome of an event (Polymarket)"
method: GET
path: "/api/prediction-markets/events/{source}/{slug}/holders"
tags: ["public-pm-data"]
---

# Top holders per outcome of an event (Polymarket)

`GET /api/prediction-markets/events/{source}/{slug}/holders`

## Request

- Base URL: `https://api.coinrithm.com`
- URL: `https://api.coinrithm.com/api/prediction-markets/events/{source}/{slug}/holders`
- Auth: none required

Keyless top holders of each outcome, read from Polymarket's public
holder data on demand and never stored. Top 10 wallets per outcome by
shares held, with average price (a probability 0-1), current value and
realized/unrealized P&L in USD as Polymarket reports them. At most 10
markets per event are covered (live outcomes first, then by
probability); `marketsCovered < marketsTotal` means a partial list.
Cached 10 minutes.

The route takes NO query parameters: any query key answers 400.
Every other venue answers 200 with `available: false` and a `reason`:
`venue_has_no_public_holders` (Kalshi), `venue_not_supported`,
`market_ids_unavailable` (market ids pruned, e.g. some time after
resolution), or the transient `venue_unavailable` / `busy` (retry
later). A single outcome whose venue call failed has
`available: false` while the rest are served.

`walletPagePath` is the unlocalized path of CoinRithm's whale wallet
page (`/prediction-markets/whales/polymarket/<wallet>`), set only when
that page exists; otherwise null.

## Path parameters

- `source` 'polymarket' | 'kalshi' | 'rothera' | 'limitless' | 'smarkets' | 'manifold' | 'metaculus' | 'predictit' | 'futuur' | 'myriad' | 'forecastex' | 'gemini', required
- `slug` string, required

## Response `200`

Holders per outcome, or `available:false` with a reason

- PublicPmEventHoldersResponse
  - `source` string, required
  - `slug` string, required
  - `available` boolean, required
  - `reason` 'venue_has_no_public_holders' | 'venue_not_supported' | 'market_ids_unavailable' | 'venue_unavailable' | 'busy': Present only when `available` is false.
  - `provider` 'polymarket_data_api_v2'
  - `asOf` string, date-time
  - `cacheTtlSeconds` integer
  - `holdersPerOutcome` integer
  - `marketsCovered` integer
  - `marketsTotal` integer
  - `outcomes` object[]
    - `name` string
    - `externalMarketId` string
    - `tokenId` string
    - `available` boolean
    - `holders` PublicPmEventHolder[]
      - `wallet` string, required: Full proxy wallet, lower-case.
      - `walletShort` string, required
      - `name` string, nullable: Public display name; null when hidden or absent.
      - `pseudonym` string, nullable
      - `shares` number, required
      - `avgPrice` number, nullable: Average entry price as a probability 0-1.
      - `currentValueUsd` number, nullable
      - `realizedPnlUsd` number, nullable
      - `unrealizedPnlUsd` number, nullable
      - `walletPagePath` string, nullable: Unlocalized CoinRithm wallet page path, only when that page exists.

## Other responses

- `400`: Invalid or missing parameters. On a route with a query allowlist, an undocumented query parameter returns `{"error": "unsupported_query_parameter", "message": "Unsupported query parameter: <key>. Supported: <keys>."}`.
- `404`: Resource not found. A path the API does not serve at all returns `{"error": "not_found", "message": "not_found"}` with `Cache-Control: no-store`.
- `500`: Server error
- `503`: The route already has its cap of venue requests in flight and refused this one at once (`error: "temporarily_busy"`), without queueing it. Sent with `Retry-After: 5` and `Cache-Control: no-store`; retry after `retryAfterSeconds`. Cached responses are never refused this way.

---

[API](https://skmtc.dev/coinrithm/apis/coinrithm-agent-trading-api.md) · [All operations](https://skmtc.dev/coinrithm/apis/coinrithm-agent-trading-api/llms.txt) · [OpenAPI document](https://skmtc.dev/coinrithm/apis/coinrithm-agent-trading-api/revisions/28fb59f285fe?raw)
