# How to read Novig's public trades.csv and markets.csv

> Independent. Not affiliated with, endorsed by or sponsored by Novig.

Canonical: https://novigapi.com/novig-public-data-csv
Facts checked: 2026-11-12

Novig's public data is two daily CSVs listed in data.novig.com/reporting/trade-data/index.json: trades.csv with every fill and markets.csv with a daily row per market. Stream them line by line; trades.csv was about 209 MB for 11 Nov 2026. They are anonymized and carry no player names, per Novig's docs checked 12 Nov 2026. (Source: [Novig docs: Exchange Data](https://docs.novig.com/public-data/overview.md))

Novig publishes its exchange activity as static files behind a CDN. They are free, need no key, and are the most complete public record of what traded on Novig. Each covers one Eastern day, midnight to midnight, and appears about 5 a.m. ET the next morning.

## Find the files: index.json

Start from the manifest at `https://data.novig.com/reporting/trade-data/index.json`. It lists `dates` (days with a trades file) and `marketDates` (days with a markets file). On 12 Nov 2026 trades ran from 2026-08-03 and markets from 2026-08-04, both through 2026-11-11. Each day's files are at:

```text
https://data.novig.com/reporting/trade-data/<date>/trades.csv
https://data.novig.com/reporting/trade-data/<date>/markets.csv
```

The two lists can differ: if a day's trades fail Novig's validation, Novig withholds that trades file and still publishes the markets file. Always check the manifest before you fetch.

## markets.csv columns

markets.csv, one row per market per day

| Column | Meaning |
| --- | --- |
| date | Eastern trading day. |
| marketId | Novig market id, the same id the live catalog uses. |
| reportTicker | Product family, such as `MLB-SPREAD`. Not a name. |
| openInterest | Contracts outstanding at the end of the day. |
| dailyVolume | Contracts traded that day. |
| open, high, low, close | Daily prices in cents to one decimal: 47.5 means a probability of 0.475. |
| status | `active` or `finalized`. It does not say which side won. |


For 11 Nov 2026 the file was about 11 MB with 118,861 lines, which is 118,860 markets plus the header. About 67,900 of those rows were parlays (COMBO).

## trades.csv columns

trades.csv, one row per side of each trade

| Column | Meaning |
| --- | --- |
| timestamp | When the trade executed. |
| outcomeId | The outcome traded. |
| marketId | Its market. |
| contractSeries | Novig's contract series label. |
| league | League code, such as `NBA`. |
| marketType | Market type, such as `POINTS`. |
| tradeType | Straight or `COMBO` (parlay). |
| legs | Number of legs for combos. |
| cost | What the side paid. Check Novig's Trades page for units before summing. |
| qty | Contracts. |
| side | `TAKER` or `MAKER`. |


Each trade appears twice, once per side, so count only `TAKER` rows (or only `MAKER`) when you add up volume. The file was about 209 MB for 11 Nov 2026: too large to load casually into memory on a small machine, and far too large for a spreadsheet.

## A streaming reader in Python

This uses only the standard library. It streams the file over HTTP, never holds it in memory, reads columns by header name, and totals taker volume per market for straight trades:

```python
import csv, io, json, urllib.request
from collections import Counter

ROOT = "https://data.novig.com/reporting/trade-data"

def manifest():
    with urllib.request.urlopen(ROOT + "/index.json", timeout=30) as r:
        return json.load(r)

def rows(date, name):
    """Yield dict rows from one day's file, streamed."""
    with urllib.request.urlopen(f"{ROOT}/{date}/{name}.csv", timeout=60) as r:
        text = io.TextIOWrapper(r, encoding="utf-8", newline="")
        yield from csv.DictReader(text)  # keyed by header, so new columns are safe

latest = manifest()["dates"][-1]
volume = Counter()
for t in rows(latest, "trades"):
    if t["side"] == "TAKER" and t["tradeType"] != "COMBO":
        volume[(t["league"], t["marketId"])] += int(t["qty"])

for (league, market_id), qty in volume.most_common(10):
    print(latest, league, market_id, qty)
```

Fetch politely: these are static files, so download each day once, store it, and read it locally afterwards. For markets.csv, divide prices by 100 to get probabilities:

```python
def daily(date):
    for m in rows(date, "markets"):
        yield {
            "date": m["date"],
            "market_id": m["marketId"],
            "family": m["reportTicker"],
            "close": float(m["close"]) / 100 if m["close"] else None,
            "volume": int(float(m["dailyVolume"] or 0)),
            "status": m["status"],
        }
```

## Adding names

The files say `marketId`, not "Cooper Flagg 1.5 STEALS". To label rows you need a map from id to description, which you can build by reading Novig's live catalog while a market is open; once it closes, it leaves the catalog. novigapi.com keeps that map for every market it has seen. Its [bulk CSV endpoint](https://novigapi.com/docs/endpoints/bulk-csv) returns a day's OHLC rows (`dataset=ohlc`), trades, line moves or results as a CSV, with prices converted to probabilities and parlays left out, up to 10,000 rows per call.

```bash
curl -s "https://novigapi.com/api/v1/bulk/csv?dataset=ohlc&date=2026-11-11&limit=5000" \
  -H "Authorization: Bearer nv_..." -o ohlc-2026-11-11.csv
```

Raw files versus the bulk endpoint

|  | data.novig.com | novigapi.com bulk CSV |
| --- | --- | --- |
| Price | Free | 10 credits per 100 rows, on plans with bulk export |
| Prices | Cents | Probabilities |
| Parlay rows | Mixed in | Excluded |
| Rows per call | Whole day | Up to 10,000 |


## Questions

### Do I need an account to download Novig's CSVs?

No. The files at data.novig.com are public static files with no key.

### When is each day published?

About 5 a.m. ET the next morning, covering midnight to midnight Eastern.

### Why does trades.csv show each trade twice?

It has one row per side, taker and maker. Count one side when you total volume.

### Can past files change?

Novig's docs say past files do not change except for corrections it announces.

## Sources

- [data.novig.com manifest (index.json)](https://data.novig.com/reporting/trade-data/index.json)
- [Novig docs: Exchange Data](https://docs.novig.com/public-data/overview.md)
- [Novig docs: Markets CSV](https://docs.novig.com/public-data/markets.md)
- [Novig docs: Trades CSV](https://docs.novig.com/public-data/trades.md)
- [Novig exchange data files (data.novig.com)](https://data.novig.com)

---

Get a free API key: https://novigapi.com/sign-up . Docs: https://novigapi.com/docs . MCP: https://novigapi.com/api/mcp . Operated by Stunning Couches LLC. Independent. Not affiliated with, endorsed by or sponsored by Novig.
