/v2/positions/combosList combo positions
Combo positions for a user, in the standard `{ data, pagination }` envelope. Sorts: `FIRST_ENTRY` (default) | `ENTRY_COST` (+ `CURRENT_VALUE` alias) | `UPDATED`, each with `sort_direction`. `FIRST_ENTRY DESC` pages by the two-state keyset anchor `(first_entry_at_micros, combo_condition_id, outcome_index)` (NULL micros = the NULL tail); `UPDATED ASC` by the single-state `(updated_at_micros, …)` anchor; every other…
- Base URL
- https://data-api.polymarket.com
- Auth
- Public, no key
- Rate limit
- 200 req / 10s (20 per second)
- Limit applies to
- /v2/positions, /v2/positions/combos
Things to know
Every v2 response wraps its payload in a data field. Paginated reads return an opaque cursor in pagination and do not accept offset. Under load the API answers 429 with a Retry-After header.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| user | query | stringnull | yes | The wallet to anchor on. Required; combo positions are user-anchored. |
| limit | query | integernull | no | First-page size. Ignored when `cursor` is supplied (the cursor's size wins). |
| cursor | query | stringnull | no | Opaque pagination cursor from a prior response's `next_cursor`. |
| condition | query | stringnull | no | Combo condition id(s), comma-separated (at most 20 distinct values). `condition_id` / `conditionId` are accepted aliases. |
| status | query | stringnull | no | One of `OPEN`, `REDEEMABLE`, `PARTIAL`, `RESOLVED_WIN`, `RESOLVED_LOSS`, `RESOLVED_PARTIAL`; default (absent) is the held-visibility listing. Aligned with `/v2/positions`: `OPEN` is the superset; it includes still-held redeemable positions; and `REDEEMABLE` narrows to exactly the rows whose… |
| sort_by | query | stringnull | no | `FIRST_ENTRY` (default, except under `status=REDEEMABLE`, which defaults to `ENTRY_COST` so the largest claims lead) | `ENTRY_COST` | `CURRENT_VALUE` (alias of `ENTRY_COST`) | `UPDATED`. `FIRST_ENTRY DESC` and `UPDATED ASC` page by keyset; every other combination pages by an offset-shaped cursor. |
| sort_direction | query | stringnull | no | `ASC` or `DESC` (default `DESC`). |
| updated_after | query | integernull | no | Incremental-sync watermark: INCLUSIVE lower bound on `updated_at`, epoch seconds. Without a `status` filter, either watermark serves the sync view; every live row (mirror-complete), not only the held listing; a `status` filter keeps its own row visibility. |
| updated_before | query | integernull | no | Incremental-sync watermark: INCLUSIVE upper bound on `updated_at`, epoch seconds; must not precede `updated_after`. See `updated_after` for the sync-view and ceiling semantics. |
user is listed as optional in Polymarket's OpenAPI spec, but the API returns 400 without it (checked 2026-10-04).
Example
curl -X GET "https://data-api.polymarket.com/v2/positions/combos?user=<user>"Returns a list of objects with these fields
| Field | Type | Description |
|---|---|---|
| combo_condition_id | string | On-chain combo condition id (structural, `0x03`-prefixed). |
| combo_position_id | string | Token id of the combo position. |
| current_size | number | Current holding in shares. |
| entry_avg_price_usdc | number | Weighted-average entry price per share, in USDC. |
| entry_cost_usdc | number | Entry cost basis in USDC (rounded weighted-average form). |
| entry_fees_usdc | number | Attributed BUY-fee portion of `gross_entry_cost_usdc`, 6-decimal grain. SELL fees are exit costs and are excluded. |
| first_entry_at | string | First acquisition time, RFC3339. |
| first_entry_at_micros | integernull | Epoch-micros of `first_entry_at`; `null`/absent on the NULL tail. |
| gross_entry_cost_usdc | number | Exact fee-inclusive entry basis at 6-decimal grain; formatting to 6 dp recovers the stored value. Do NOT reconstruct it as `entry_cost_usdc + entry_fees_usdc`; `entry_cost_usdc` is rounded WAC; the… |
| legs | object[] | The combo's legs, in leg order, with market and event enrichment. |
| legs_pending | integer | Legs still awaiting resolution. |
| legs_resolved | integer | Legs whose markets have resolved. |
| legs_total | integer | Number of legs in the combo. |
| outcome_index | integer | Index of the combo outcome held; `999` means unlabelable. |
| outcome_label | string | Label of the combo outcome held. |
| proxy_wallet | string | The holder's wallet. `proxy_wallet` on every /v2 response; `user` is the REQUEST param vocabulary, never a response field (2026-08-19). |
| realized_payout_usdc | number | Gross redemption payout received so far in USDC; turnover, not profit; net result = payout minus `gross_entry_cost_usdc`. |
| redeemable | boolean | Whether the combo can be redeemed now. |
| resolved_at | stringnull | When the combo fully resolved, RFC3339; `null` while any leg is open. |
| status | string | Lifecycle state of the position (OPEN, REDEEMABLE, RESOLVED_WIN, RESOLVED_LOSS, RESOLVED_PARTIAL). |
| updated_at | string | Last event touching the position, RFC3339. |
| updated_at_micros | integer | Epoch-micros of `updated_at`. |
Responses
| Status | Meaning |
|---|---|
| 200 | A page of combo positions |
| 400 | Invalid query params or cursor, an invalid sync watermark (negative, or an inverted window), a malformed 'condition' combo id, or a 'user' that is a known protocol contract address |
| 429 | Service is at heavy-query capacity; retry after `Retry-After` |
| 500 | Internal server error |
| 503 | Timed out (the request deadline, the datastore statement timeout, or the connection pool's acquire budget) or a serving dependency is unavailable; retry after `Retry-After` |
Related endpoints
- GET /v2/positions Data API v2
From Polymarket's published OpenAPI spec and rate-limit tables, synced 2026-10-04.