API reference
Bulk prices
Latest quotes for up to 100 contracts in one request. Ids TPM does not track come back in unresolved instead of failing the call.
When to use it
- Refresh a watchlist or portfolio every minute or so.
- Get
streamids for many contracts at once before opening the WebSocket.
For prices that change all the time, subscribe on the WebSocket instead of polling.
GET
/api/public/v1/pricesAPI key requiredGet latest quotes
Each row has the same quote, freshness and stream ids as event detail.
Parameters
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
| ids | query | string | Yes | — | Comma-separated venue:contract_id pairs, up to 100. Kalshi: market ticker. Polymarket: condition id. |
Request
Request
curl -s 'https://api.thepredictionmarkets.com/api/public/v1/prices?ids=kalshi:KXPRESNOMD-28-GN,polymarket:0x0f49db97f71c68b1e42a6d16e3de93d85dbf7d4148e3f018eb79e88554be9f75,kalshi:KXNOTREAL-99' \
-H 'X-API-Key: tpm_demo_key_authorized_2026'Response
Example 200 response. Values are illustrative and change over time.
200 OK
{
"data": [
{
"id": "kalshi:KXPRESNOMD-28-GN",
"venue": "kalshi",
"contract_id": "KXPRESNOMD-28-GN",
"title": "Gavin Newsom",
"market_id": "KXPRESNOMD-28",
"event_slug": "democratic-presidential-nominee-2028",
"quote": {
"probability": 0.16,
"best_bid": 0.16,
"best_ask": 0.17,
"spread": 0.01,
"source": "live",
"observed_at": "2026-10-21T08:38:56Z",
"age_seconds": 3,
"freshness": "live"
},
"stream": {
"provider": "kalshi",
"market_id": "KXPRESNOMD-28-GN",
"outcome_id": "yes"
}
},
{
"id": "polymarket:0x0f49db97f71c68b1e42a6d16e3de93d85dbf7d4148e3f018eb79e88554be9f75",
"venue": "polymarket",
"contract_id": "0x0f49db97f71c68b1e42a6d16e3de93d85dbf7d4148e3f018eb79e88554be9f75",
"title": "Gavin Newsom",
"market_id": "democratic-presidential-nominee-2028",
"event_slug": "democratic-presidential-nominee-2028",
"quote": {
"probability": 0.1635,
"best_bid": 0.163,
"best_ask": 0.164,
"spread": 0.001,
"source": "snapshot",
"observed_at": "2026-10-21T08:37:22Z",
"age_seconds": 94,
"freshness": "fresh"
},
"stream": {
"provider": "polymarket",
"market_id": "0x0f49db97f71c68b1e42a6d16e3de93d85dbf7d4148e3f018eb79e88554be9f75",
"outcome_id": "54533043819946592547517511176940999955633860128497669742211153063842200957669"
}
}
],
"unresolved": [
"kalshi:KXNOTREAL-99"
]
}Response fields
| Field | Type | Description |
|---|---|---|
| data[].id | string | The id you asked for, venue:contract_id. |
| data[].venue, contract_id | string | Venue and contract. |
| data[].title | string | The outcome title. |
| data[].market_id | string | The venue listing the contract belongs to. |
| data[].event_slug | string | null | The TPM event. |
| data[].quote.probability | number | null | The displayed price as a probability from 0 to 1, using the venue's own display rule. 0.16 means a 16% implied chance. |
| data[].quote.best_bid | number | null | Highest price someone will pay for Yes right now. |
| data[].quote.best_ask | number | null | Lowest price someone will sell Yes for right now. |
| data[].quote.spread | number | null | best_ask - best_bid on this venue (not the cross-venue gap). |
| data[].quote.source | "live" | "snapshot" | live: from the venue's WebSocket feed. snapshot: from TPM's REST poll of the venue. |
| data[].quote.observed_at | string | null | When this price was last known to be current (UTC). |
| data[].quote.age_seconds | integer | null | Seconds since observed_at. |
| data[].quote.freshness | string | live, fresh, aging, stale or unknown. See freshness. |
| data[].stream | object | null | WebSocket ids {provider, market_id, outcome_id}. |
| unresolved | string[] | Requested ids TPM does not track. |
Errors
| HTTP | Code | When |
|---|---|---|
| 400 | validation.invalid_id | An id is not a venue:contract_id pair. |
| 400 | validation.too_many_ids | More than 100 ids. |
| 400 | validation.invalid_parameter | ids is missing. |
| 401 | auth.missing_key | No X-API-Key header was sent. |
| 401 | auth.invalid_key | The key is wrong or was revoked. |
| 429 | rate_limit.per_second | Too many requests this second. Wait for Retry-After. |
400 validation.invalid_id
{
"error": {
"code": "validation.invalid_id",
"message": "'foo' is not a `venue:contract_id` pair.",
"request_id": "0f8969a6-0968-4d7c-9cbb-de379e8c19c4"
}
}All codes are listed on the errors page.
Try it
Runs a live request from your browser. Pre-filled with the shared demo key (5 requests per second for everyone); paste your own key for steadier results.
HTTP: —Time: —Rows: —Remaining this second: —Request: —
Press Send to run this request.Related
Build with TPM
Get your free API key
One key gives you Kalshi and Polymarket events, prices with freshness, price history, cross-venue gaps and the live quotes WebSocket.