Get the record of one Polymarket wallet
/v1/pm/traders/{wallet}Call this to profile a Polymarket wallet. data holds its activity (fills, markets, volume, first and last trade), lifetime profit and loss in USDC with fees taken off, a skill rating with a calibration curve (skill is empty for a wallet with too few resolved markets), and a wash-trading check with the trades behind any flag. Amounts are objects with raw, decimals, symbol and value, and a loss is negative. Trades after the end of the data are not included, and a market that resolved after it counts as open.
The wallet is 0x and 40 hex digits in any case. The answer carries it in lowercase.
Every answer carries data.coverage, which says the history ends at Polygon block 85,948,288 (2026-04-24 07:43:40 UTC), names the source (Envio's public Polymarket dataset, licence CC BY 4.0) and holds the attribution line and the modified notice. Keep both wherever you show the data. meta.as_of["eip155:137"] repeats the last block, and meta.finality is finalized. Polygon is not a chain Sona serves, so the route has no {chain}.
Other venues. With venue=hyperliquid the record is a pm_trader with a venue field and the figures of the HIP-4 tape: activity, profit and loss and skill, and no wash check, owner or calibration. With venue=levr the record is a pm_levr_trader with the leveraged positions of the wallet. kalshi and polymarket-us publish no trader ids and answer 400 invalid_query ("venue has no trader ids"). A wallet the venue has not recorded answers 404 not_found.
Venues. A venue other than polymarket is read from what Sona's collector recorded, so its answer has no block: meta.finality is none, meta.as_of is empty and no Sona-* header is sent. An answer for Levr Bet would be labelled eip155:143, the chain it runs on, if it ever carried a block. Every venue answer has its own data.coverage object (venue, since, last_ok, mode, wallets, gaps, note) in place of the Polymarket one, and says in note what is not recorded. Answers for a venue are kept for 30 seconds, and a stale one for 5 seconds. An unknown venue, or one the route cannot serve, is pm-api's 400 invalid_query, passed through. While the recorded data cannot be read a venue answer is 503 upstream_unavailable with Retry-After: 1.
Path parameters
| Name | Type | Description |
|---|---|---|
walletRequired | string | The Polymarket wallet: |
Query parameters
| Name | Type | Description |
|---|---|---|
venue | stringDefault polymarket | Which venue to read: |
Response
The answer, wrapped in the {data, meta, links} envelope.
| Field | Type | Description |
|---|---|---|
| activity | object | What the wallet traded, counted on its own side so that nothing is counted twice. |
| coverage | object | What period the Polymarket data covers, where it comes from and the notices that must be shown with it. |
| kind | string | Always |
| owner | string | null | The account that controls the wallet when Polymarket's registry lists it, otherwise |
| owner_kind | string | null | What kind of contract the wallet is, or |
| pnl | object | Lifetime profit and loss in USDC amounts, with settlement of resolved markets and fees taken off. |
| skill | object | null | The skill rating and calibration curve, empty for a wallet below the rating floor. |
| wallet | string | The wallet, in lowercase. |
| wash | object | The wash-trading check, with the trades behind any flag. |
| Field | Type | Description |
|---|---|---|
| activity | object | What the wallet traded, on its own side so that nothing is counted twice. |
| coverage | object | What a recorded venue holds, from when, and how complete it is. It replaces the Polymarket |
| kind | string | Always |
| pnl | object | Profit and loss from the recorded tape only, with fills netted by outcome and settled at the venue's payout. |
| skill | object | Forecasting skill over question-type outcomes only. Recurring price outcomes are not rated. |
| venue | string | Always |
| wallet | string | The wallet, in lowercase. |
| Field | Type | Description |
|---|---|---|
| coverage | object | What a recorded venue holds, from when, and how complete it is. It replaces the Polymarket |
| first_position | string | When its first position opened. |
| kind | string | Always |
| last_position | string | When its last position opened. |
| leverage | number | Size divided by stake across all positions. |
| liquidated | integer | The positions the venue liquidated, each of which loses the whole stake. |
| liquidation_rate | number | Liquidated positions over positions that ended in a win, a loss or a liquidation. |
| lost | integer | The positions that ended with less than the stake. |
| open | integer | The positions not yet closed. |
| positions | integer | The positions it opened since recording started. |
| realized | object | An amount of USDC, exact in |
| size | object | An amount of USDC, exact in |
| stake | object | An amount of USDC, exact in |
| venue | string | Always |
| voided | integer | The positions of cancelled games. The refund is not published, so their result counts as 0. |
| wallet | string | The wallet, in lowercase. |
| win_rate | number | Won positions over positions that ended in a win, a loss or a liquidation. |
| won | integer | The positions redeemed with a profit. |
Cost
1 credit. The time limit is 5 seconds.
Errors
| Status | Code |
|---|---|
| 400 | invalid_idinvalid_query |
| 404 | not_found |
| 429 | rate_limitedcredits_exhausted |
| 500 | internal |
| 503 | upstream_unavailable |
| 504 | deadline_exceeded |
400 invalid_id for a wallet that is not 0x and 40 hex digits, 400 invalid_query for any query key but venue, or for a venue that has no trader ids, 404 not_found when the wallet has no fills in the data, 429 rate_limited or credits_exhausted, 503 upstream_unavailable while the dataset is not loaded, and 504 deadline_exceeded when the budget runs out.