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

# Prediction markets deep-dive

> Compare venues, track share and take rate month by month, and split volume by category

## Venue comparison

```bash theme={null}
curl -s "https://data-svc.artemisxyz.com/v2/data/SPOT_VOLUME,OPEN_INTEREST?symbols=kalshi,polymarket,nadex,opinion,predict,gemini,limitless,rothera,forecastex,cme,hip4&startDate=2026-07-25&endDate=2026-08-01&summarize=true&APIKey=$ARTEMIS_API_KEY"
```

| Venue         | Volume          | Open interest   |
| ------------- | --------------- | --------------- |
| Kalshi        | \$1,383.7M      | \$700.3M        |
| Polymarket    | \$300.3M        | \$402.3M        |
| Nadex         | 37.5M contracts | 17.0M contracts |
| Opinion       | \$25.8M         | \$3.7M          |
| Predictdotfun | \$10.2M         | \$11.2M         |
| Gemini        | \$10.2M         | n/a             |
| Limitless     | \$5.6M          | \$0.4M          |
| Rothera       | \$4.6M          | \$10.4M         |
| HIP-4         | \$0.8M          | n/a             |
| ForecastEx    | \$0.7M          | \$8.1M          |
| CME           | 0.1M contracts  | 0.0M contracts  |

Kalshi and Polymarket together are \~95% of tracked volume. See the [\$1-face and notional caveats](/docs/artemis-api/metrics/prediction-markets) before comparing Nadex or CME with the rest.

## Who is taking share, and at what take rate

`granularity=MONTH` rolls each metric up by its own aggregation type, so `SPOT_VOLUME` and `FEES` come back as true monthly totals. Volume gives share, fees over volume gives the implied take rate.

```python theme={null}
import os
import requests
from collections import defaultdict

VENUES = "kalshi,polymarket,rothera,gemini,opinion,limitless,predict,hip4,forecastex"

resp = requests.get(
    "https://data-svc.artemisxyz.com/v2/data/SPOT_VOLUME,FEES",
    params={
        "symbols": VENUES,
        "startDate": "2026-05-01",
        "endDate": "2026-07-31",
        "granularity": "MONTH",
        "APIKey": os.environ["ARTEMIS_API_KEY"],
    },
    timeout=120,
)
resp.raise_for_status()

months = defaultdict(lambda: defaultdict(dict))
for s in resp.json()["series"]:
    if not isinstance(s["data"], list):
        continue  # not every venue publishes FEES
    for ts, value in s["data"]:
        months[ts][s["display_name"]][s["metric"]] = value

for ts in sorted(months):
    venues = months[ts]
    total = sum(m.get("SPOT_VOLUME") or 0 for m in venues.values())
    ranked = sorted(venues.items(), key=lambda kv: -(kv[1].get("SPOT_VOLUME") or 0))
    for name, m in ranked[:2]:
        vol, fees = m.get("SPOT_VOLUME") or 0, m.get("FEES")
        take = f"{100 * fees / vol:.2f}%" if fees else "n/a"
        print(f"{name:12} ${vol/1e9:6,.2f}B  {100*vol/total:5.1f}% share  {take:>5} take")
```

| Month   | Venue      | Volume   | Share | Fees     | Take rate |
| ------- | ---------- | -------- | ----- | -------- | --------- |
| 2026-05 | Kalshi     | \$17.91B | 58.6% | \$193.5M | 1.08%     |
|         | Polymarket | \$8.84B  | 28.9% | \$42.0M  | 0.47%     |
| 2026-06 | Kalshi     | \$33.00B | 61.8% | \$312.0M | 0.95%     |
|         | Polymarket | \$14.64B | 27.4% | \$73.7M  | 0.50%     |
| 2026-07 | Kalshi     | \$41.05B | 70.2% | \$377.3M | 0.92%     |
|         | Polymarket | \$12.79B | 21.9% | \$80.9M  | 0.63%     |

* **Share is consolidating.** Kalshi went 58.6% to 70.2% in three months. Polymarket went 28.9% to 21.9% on volume that peaked in June.
* **Take rates are converging from opposite ends.** Kalshi's compressed from 1.08% to 0.92% while Polymarket's expanded from 0.48% to 0.63%.
* **July fees annualize to roughly \$4.5B for Kalshi** against \$1.0B for Polymarket, at a flat run rate.

Share is measured against the USD-denominated venues only. Nadex and CME quote in contracts whose face value varies by product, so they are excluded from the denominator rather than converted. See the [notional caveats](/docs/artemis-api/metrics/prediction-markets).

## Which categories are driving the growth

Volume growth is only as durable as the categories behind it. `dimensionType=CATEGORY` composes with `granularity=MONTH`, turning the same call into a mix shift over time:

```bash theme={null}
curl -s "https://data-svc.artemisxyz.com/v2/data/SPOT_VOLUME?symbols=kalshi&startDate=2026-05-01&endDate=2026-07-31&dimensionType=CATEGORY&granularity=MONTH&APIKey=$ARTEMIS_API_KEY"
```

Kalshi's top three of 17 categories:

| Month   | Sports         | Exotics        | Crypto        | Total    |
| ------- | -------------- | -------------- | ------------- | -------- |
| 2026-05 | \$10.43B (58%) | \$4.88B (27%)  | \$2.02B (11%) | \$17.91B |
| 2026-06 | \$14.75B (45%) | \$11.90B (36%) | \$4.02B (12%) | \$33.00B |
| 2026-07 | \$17.91B (44%) | \$15.00B (37%) | \$6.33B (15%) | \$41.05B |

Sports is the largest book but a shrinking share of it: 58% to 44% while total volume more than doubled. Exotics and crypto absorbed the difference. Each month's categories sum exactly to that month's undifferentiated `SPOT_VOLUME`, so this is a clean partition you can build a mix model on.

<Warning>
  `granularity` respects each metric's `aggregation_type`. `SPOT_VOLUME` and `FEES` are `SUM`, so a month bucket is a genuine monthly total. `OPEN_INTEREST` is `LAST`, so its bucket is the month-end snapshot and must never be added across months. `summarize=true` behaves differently again: it returns the `endDate` day for every metric. See [Core concepts](/docs/artemis-api/core-concepts).
</Warning>

<Note>
  Metrics have their own inception dates. `ACTIVE_MARKETS` for Kalshi begins on 2026-07-17, so it covers part of this window rather than all of it. Divide by the number of populated points rather than the row count, since the response returns a row per period either way.
</Note>
