/api/v1/markets
List markets tracked by Q
Every active Q-tracked prediction market with either an in-window forecast or a Q signal, returned in one complete response with venue_quote provenance. Polymarket International and Kalshi expose a verified live quote or null; Polymarket US and Limitless expose a graph snapshot marked stale. Event tags and categories support discovery; use exact topic filtering or /markets/search to narrow the response.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| topic | query | string | Case-insensitive exact Event/market tag or category filter. Direct tags do not need a Category assignment. |
| venue | query | "polymarket" | "polymarket_us" | "kalshi" | "limitless" | Optional prediction-market venue filter. Omit it on catalog/feed routes to include every covered venue. On legacy slug or condition-ID lookups, omission retains the Polymarket namespace; prefer marketKey for collision-safe cross-venue lookup. |
| max_forecast_age | query | integer | Maximum forecast age in hours. Windows forecast_count and latest_forecast_at — only forecasts created within this window are counted. Markets with no in-window forecast are still included if they have signals. Default: 48 Default: 48; Minimum: 1 |
| changed_within | query | integer | Only markets whose latest forecast was created within this many hours — 'recently updated by Q'. Evaluated against the unwindowed latest forecast, independent of max_forecast_age. Minimum: 1; Maximum: 168 |
| sort | query | "updated_desc" | "volume_desc" | "signal_count_desc" | Sort order. Default: updated_desc |
Responses
200: List of markets with forecast data
| Field | Type | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| markets required | MarketListItem[] | markets fields
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| venue_facets required | object[] | venue_facets fields
|
401: Unauthorized
| Field | Type | Description |
|---|---|---|
| error required | string | Error code |
| message required | string | Human-readable message |
| retry_after | integer | Seconds to wait (only on 429) |
| retryAfter | integer | Seconds to wait for owner-scoped forecast-request quota errors. |
| limit_scope | string | Quota scope that rejected the request, such as standard or x_research. |
| quotaScope | string | Stable forecast-request quota scope, such as venue_market_daily. |
| limit | integer | Configured bound for the forecast-request quota that was exceeded. |
402: Payment Required
| Field | Type | Description |
|---|---|---|
| error required | string | Error code |
| message required | string | Human-readable message |
| retry_after | integer | Seconds to wait (only on 429) |
| retryAfter | integer | Seconds to wait for owner-scoped forecast-request quota errors. |
| limit_scope | string | Quota scope that rejected the request, such as standard or x_research. |
| quotaScope | string | Stable forecast-request quota scope, such as venue_market_daily. |
| limit | integer | Configured bound for the forecast-request quota that was exceeded. |
403: Insufficient credits for the requested route
| Field | Type | Description |
|---|---|---|
| error required | string | Error code |
| message required | string | Human-readable message |
| retry_after | integer | Seconds to wait (only on 429) |
| retryAfter | integer | Seconds to wait for owner-scoped forecast-request quota errors. |
| limit_scope | string | Quota scope that rejected the request, such as standard or x_research. |
| quotaScope | string | Stable forecast-request quota scope, such as venue_market_daily. |
| limit | integer | Configured bound for the forecast-request quota that was exceeded. |
422: Invalid request parameters
| Field | Type | Description |
|---|---|---|
| error required | string | Error code |
| message required | string | Human-readable message |
| retry_after | integer | Seconds to wait (only on 429) |
| retryAfter | integer | Seconds to wait for owner-scoped forecast-request quota errors. |
| limit_scope | string | Quota scope that rejected the request, such as standard or x_research. |
| quotaScope | string | Stable forecast-request quota scope, such as venue_market_daily. |
| limit | integer | Configured bound for the forecast-request quota that was exceeded. |
429: The caller exceeded a per-second, per-minute, daily, or concurrency limit. No credits are debited and no x402 payment is settled for this response.
| Field | Type | Description |
|---|---|---|
| error required | string | Error code |
| message required | string | Human-readable message |
| retry_after | integer | Seconds to wait (only on 429) |
| retryAfter | integer | Seconds to wait for owner-scoped forecast-request quota errors. |
| limit_scope | string | Quota scope that rejected the request, such as standard or x_research. |
| quotaScope | string | Stable forecast-request quota scope, such as venue_market_daily. |
| limit | integer | Configured bound for the forecast-request quota that was exceeded. |
Set QUOTIENT_API_KEY in your shell and replace example identifiers with returned IDs before running a request.
curl --request GET \
--header "x-quotient-api-key: $QUOTIENT_API_KEY" \
'https://quotient-api-gateway.onrender.com/api/v1/markets'{
"markets": [
{
"venue": "kalshi",
"nativeMarketId": "KXGOLD-26AUG-T2500",
"nativeEventId": "KXGOLD-26AUG",
"seriesTicker": "KXGOLD",
"marketKey": "kalshi:KXGOLD-26AUG-T2500",
"quotientMarketId": "kalshi:KXGOLD-26AUG-T2500",
"slug": null,
"marketUrl": null,
"sourceUrl": null,
"question": "Will gold settle above $2,500 in August?",
"event": {
"id": "KXGOLD-26AUG",
"title": "Gold price in August",
"slug": null
},
"tags": [
"Commodities",
"Metals",
"Gold"
],
"categories": [
"Commodities"
],
"end_date": "2026-08-31T20:00:00Z",
"market_odds": 0.46,
"venue_quote": {
"schema_version": "1",
"venue": "kalshi",
"market_id": "KXGOLD-26AUG-T2500",
"yes_bid": 0.46,
"yes_ask": 0.46,
"yes_last": null,
"selected_probability": 0.46,
"quote_method": "midpoint",
"venue_timestamp": "2026-08-31T12:00:00Z",
"observed_at": "2026-08-31T12:00:00Z",
"freshness": "verified"
},
"inDispute": false,
"clarifications": null,
"volume_24h": null,
"signal_count": 0,
"forecast_count": 1,
"latest_forecast_at": "2026-08-08T14:30:00Z",
"market_updated_at": "2026-08-08T15:02:11Z",
"latest_forecast_delta": 0.03,
"latest_forecast_refresh_reason": "price_move",
"quotientUrl": "https://quotient.social/markets/kalshi%3AKXGOLD-26AUG-T2500",
"polymarketUrl": null
}
],
"venue_facets": [
{
"venue": "kalshi",
"count": 1
}
]
}