> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dune.com/llms.txt
> Use this file to discover all available pages before exploring further.

# prediction_markets.markets

> Unified market dimension table across Polymarket and Kalshi, one row per binary market with normalized status, category, and resolution fields.

export const TableSample = ({tableName, tableSchema}) => <>
    <div className="hidden dark:block">
      <iframe src={`https://dune.com/embeds/3419983/5785629?table_schema_t6f0df=${tableSchema}&table_name_t6f0df=${tableName}&darkMode=true`} style={{
  width: '100%',
  height: '500px',
  border: 'none',
  marginTop: '10px'
}} />
    </div>
    <div className="dark:hidden">
      <iframe src={`https://dune.com/embeds/3419983/5785629?table_schema_t6f0df=${tableSchema}&table_name_t6f0df=${tableName}`} style={{
  width: '100%',
  height: '500px',
  border: 'none',
  marginTop: '10px'
}} />
    </div>
  </>;

The `prediction_markets.markets` table is the cross-venue market dimension. Grain: one row per binary market — Polymarket `condition_id`, the combo condition ID for Polymarket Combos (multi-leg parlays, `is_parlay = TRUE`), or Kalshi ticker. Every row carries a `venue` column and uses venue-neutral column names so you can query both venues with a single statement. Market names and attributes live here; [`prediction_markets.trades`](/data-catalog/curated/prediction-markets/prediction_markets/trades) and [`prediction_markets.ohlcv_hourly`](/data-catalog/curated/prediction-markets/prediction_markets/ohlcv_hourly) carry facts only and join on `(venue, market_id)`.

Every market is presented from its **Yes side**. On Polymarket, Yes is the token in position 0 (`outcome_index = 0`), the side the venue's settlement resolves against, so `yes_outcome_id`, `resolved_outcome` and `settlement_value_usd` always agree. Kalshi covers every single market the venue has listed, traded or not, plus every parlay with at least one fill.

<Note>
  For markets without a natural Yes (team vs team, candidate vs candidate), Yes is simply whichever side the venue listed first. Check `yes_outcome_name` before reading the Yes side as an affirmative answer.
</Note>

## Table Schema

| Column | Type | Description |
| - | - | - |
| `venue` | `VARCHAR` | Venue identifier (`polymarket` or `kalshi`) |
| `market_id` | `VARCHAR` | Market identifier, unique within a venue: Polymarket `condition_id` in 0x-hex, the combo condition ID for Polymarket Combos, Kalshi ticker. Joins `prediction_markets.trades` and `prediction_markets.ohlcv_hourly` on `(venue, market_id)` |
| `event_id` | `VARCHAR` | Parent event grouping related markets. Always populated on Kalshi; on Polymarket only for markets that belong to a multi-outcome (neg-risk) event. NULL for Combos |
| `series_id` | `VARCHAR` | Recurring series the market was created from. Kalshi only; NULL on Polymarket, which has no series concept |
| `yes_outcome_id` | `VARCHAR` | Identifier of the Yes side: the token at `outcome_index = 0` on Polymarket, the market itself on Kalshi, where both sides trade on one instrument |
| `no_outcome_id` | `VARCHAR` | Identifier of the No side: the token at `outcome_index = 1` on Polymarket. NULL on Kalshi |
| `yes_outcome_name` | `VARCHAR` | Label of the Yes side as the venue shows it, usually `Yes`, `Up` or `Over`. For markets without a natural Yes it is whichever side the venue listed first |
| `no_outcome_name` | `VARCHAR` | Label of the No side as the venue shows it |
| `question` | `VARCHAR` | The market question. For Combos the generated combo name, NULL until every leg is labeled |
| `event_name` | `VARCHAR` | Title of the parent event. NULL for standalone Polymarket markets and Combos |
| `category` | `VARCHAR` | Unified topic category: `sports`, `crypto`, `politics`, `finance`, `technology`, `culture`, `weather`, `world`, `health`, `other`. Parlays take the category of their legs, or `mixed` when the legs span several categories |
| `category_native` | `VARCHAR` | The venue's own classification: Polymarket's comma-separated tags, Kalshi's single coarse category. NULL for Polymarket Combos |
| `link` | `VARCHAR` | URL of the market on the venue's website. NULL for parlays on both venues, which have no public page |
| `status` | `VARCHAR` | Lifecycle state: `active` while open for trading (including Kalshi markets not yet opened), `closed` when trading has stopped or the venue delisted the market without a result, `settled` once resolved |
| `is_resolved` | `BOOLEAN` | TRUE once the market has a final result. A resolved market is always `settled`; a Kalshi market can be `settled` without a published result, in which case this is FALSE |
| `is_parlay` | `BOOLEAN` | TRUE for multi-leg parlays: Kalshi parlays and Polymarket Combos. Filter `is_parlay = FALSE` for like-for-like single-market comparisons |
| `leg_count` | `INTEGER` | Number of legs in a parlay. NULL for single markets |
| `legs` | `VARCHAR` | The parlay's legs as a JSON array. On Kalshi each leg names its event, market and required side; on Polymarket each leg is a `question: outcome` label. NULL for single markets |
| `is_mutually_exclusive_event` | `BOOLEAN` | TRUE when at most one market in the parent event can resolve Yes, such as a multi-candidate election (Kalshi mutually exclusive events, Polymarket neg-risk events). FALSE when unknown |
| `frequency` | `VARCHAR` | How often the market's series recurs: `fifteen_min`, `hourly`, `daily`, `weekly`, `monthly`, `quarterly`, `annual`, `one_off` or `custom`. Kalshi only; NULL on Polymarket. Useful for excluding high-frequency series from cross-venue aggregates |
| `market_start_time` | `TIMESTAMP` | When trading opened. For Combos, when the combo was registered on-chain |
| `market_end_time` | `TIMESTAMP` | Scheduled close of trading. On Kalshi this reflects later changes to the close date. On Polymarket it is the venue's published end date, which is often inaccurate; use `settlement_ts` and `status` for the actual lifecycle. NULL for Combos |
| `settlement_ts` | `TIMESTAMP` | When the market settled. NULL until resolved |
| `resolved_outcome` | `VARCHAR` | How the market resolved: `yes`, `no`, `void` for a refund, or `scalar` for a fractional payout (Kalshi scalar markets, Polymarket Combos with a voided leg). NULL while unresolved |
| `settlement_value_usd` | `DOUBLE` | Payout per Yes contract at settlement: `1.0` when Yes won, `0.0` when No won, `0.5` for a void, a fraction for scalar settlements. NULL while unresolved |
| `strike_type` | `VARCHAR` | Structure of a Kalshi threshold or range market (`greater`, `less`, `between`, and so on). NULL on Polymarket |
| `floor_strike` | `DOUBLE` | Lower strike of a Kalshi threshold or range market. NULL on Polymarket |
| `cap_strike` | `DOUBLE` | Upper strike of a Kalshi range market. NULL on Polymarket |
| `rules` | `VARCHAR` | Resolution rules as published by the venue. NULL for Polymarket Combos, whose outcome follows from their legs |
| `source_updated_at` | `TIMESTAMP` | When the market record last changed at the venue; for Polymarket Combos, when Dune last recomputed the combo from its legs. Safe to use as a sync watermark |
| `_updated_at` | `TIMESTAMP` | When this row was last written by the pipeline. Unchanged rows keep their stamp |

## Table sample

<TableSample tableSchema="prediction_markets" tableName="markets" />

## Example queries

```sql theme={null}
-- Active single markets by category across both venues
SELECT
  venue,
  category,
  COUNT(*) AS active_markets
FROM prediction_markets.markets
WHERE status = 'active'
  AND is_parlay = FALSE
GROUP BY 1, 2
ORDER BY 3 DESC
```

```sql theme={null}
-- Markets settled in the last 7 days with their Yes-side payout
SELECT
  venue,
  market_id,
  question,
  yes_outcome_name,
  resolved_outcome,
  settlement_value_usd,
  settlement_ts
FROM prediction_markets.markets
WHERE is_resolved
  AND settlement_ts >= NOW() - INTERVAL '7' DAY
ORDER BY settlement_ts DESC
LIMIT 50
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.