# GET /v1/ohlc/daily

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

Canonical: https://novigapi.com/docs/endpoints/ohlc-daily
Facts checked: 2026-11-12

GET /v1/ohlc/daily returns one candle per Novig market per Eastern day: open, high, low, close, daily volume and open interest, with names joined. Days come from Novig's markets.csv, published about 5 a.m. ET; its index on 12 Nov 2026 listed markets files from 4 Aug 2026. (Source: [Novig docs: Markets CSV](https://docs.novig.com/public-data/markets.md))

## What it returns

Novig's markets.csv already holds a daily open, high, low and close per market, quoted in cents to one decimal. We convert those to probabilities, attach the market description, player and league, and serve them by market or by date.

The current day has no row until Novig publishes its file the next morning. For today's movement, use [line history](https://novigapi.com/docs/endpoints/line-history).

## Parameters

Query and path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| market_id | string | No | One market, every day it traded. Send this or `date`. |
| date | string (YYYY-MM-DD) | No | One Eastern trading day, every market. Free reads only the last 7 days. |
| limit | integer | No | Rows per page, 1 to 1,000. Default 100. Free returns at most 100. |
| cursor | string | No | `meta.next_cursor` from the previous page. |


## Request

```bash
curl -s "https://novigapi.com/api/v1/ohlc/daily?market_id=01a1d075-6cf1-7523-810c-adda6029ddc2" \
  -H "Authorization: Bearer nv_..."
```

## Response

The market id and description are real. The candle values are illustrative: the 12 Nov 2026 capture holds the live market, not its 11 Nov markets.csv row. A daily row is dated the end of its Eastern day, so `observed_at` is 23:59:59 ET and the age counts from there.

```json
{
  "data": [
    {
      "date": "2026-11-11",
      "market_id": "01a1d075-6cf1-7523-810c-adda6029ddc2",
      "description": "Jonathan Taylor 68.5 RUSHING_YARDS",
      "league": "NFL",
      "player_slug": "jonathan-taylor",
      "report_ticker": "NFL-RUSHING_YARDS",
      "open_interest": 9650000,
      "daily_volume": 4120000,
      "open": 0.52,
      "high": 0.56,
      "low": 0.5,
      "close": 0.55,
      "status": "active",
      "observed_at": "2026-11-12T04:59:59.000Z",
      "source_age_seconds": 44637,
      "edge_cached": true
    }
  ],
  "meta": {
    "observed_at": "2026-11-12T04:59:59.000Z",
    "source_age_seconds": 44643,
    "edge_cached": true,
    "next_cursor": null,
    "limit": 100,
    "count": 1,
    "plan": "developer",
    "credits_charged": 3,
    "credits_remaining": 9874,
    "credit_policy": "credits_v1"
  }
}
```

## Fields

Response fields

| Field | Type | Description |
| --- | --- | --- |
| date | string | Eastern trading day, midnight to midnight. |
| market_id | string | Novig market id. |
| description | string or null | Novig's market label, joined from our catalog. Null for a market that closed before our collector first listed it. |
| league | string or null | League code, from our catalog or else the first part of `report_ticker`. |
| player_slug | string or null | Player slug on props. Novig's CSV has no names; we join them from the catalog. |
| report_ticker | string | Novig's product family from the CSV, such as `MLB-SPREAD`. |
| open, high, low, close | number | Daily prices as probabilities. Novig's file has cents, so 47.5 becomes 0.475. |
| daily_volume | integer | Contracts traded that day, in API contracts of $0.01 (the file counts $1 contracts; we multiply by 100). |
| open_interest | integer | Contracts outstanding at the end of the day, in the same unit. |
| status | string | `active` or `finalized`. |
| observed_at | string (ISO 8601) or null | When our collector last read this row from Novig. |
| source_age_seconds | integer or null | Seconds between that read and our answer. |
| edge_cached | boolean | True when the value came through Novig's public CDN, which may serve a copy up to its cache time (5 to 10 seconds) older. |
| meta.next_cursor | string or null | Pass as `cursor` to get the next page. Null on the last page. |
| meta.limit, meta.count | integer | The page size used and the rows on this page. |
| meta.observed_at | string (ISO 8601) | When our collector read the oldest row in this answer from Novig's public catalog. Each row also carries its own `observed_at`. |
| meta.source_age_seconds | integer | Seconds between that read and our response. On paid plans this stays at about 10 or less. |
| meta.edge_cached | boolean | True when Novig's edge cache served any of the reads, so the source copy may itself be a few seconds old. |
| meta.plan, credits_charged, credits_remaining, credit_policy | string, integer | Your plan, what this call cost, the credits left this month and the credit rules version. |


## Credit cost

Weighted 3x: 3 credits per call per 100 rows requested (the `limit` you send, default 100, maximum 1,000; Free pages hold at most 100 rows). A default page costs 3 credits. Every market on one date can be thousands of rows; page with `limit` and `cursor`. Errors and 304 Not Modified cost 0; the `X-Credits-Cost` header and `meta.credits_charged` state the price of every call.

## Python

```python
import os
import requests

KEY = os.environ["NOVIGAPI_API_KEY"]  # nv_...
HEADERS = {"Authorization": f"Bearer {KEY}"}

mid = "01a1d075-6cf1-7523-810c-adda6029ddc2"
rows = requests.get("https://novigapi.com/api/v1/ohlc/daily", params={"market_id": mid}, headers=HEADERS, timeout=10).json()["data"]
for d in rows:
    print(d["date"], d["open"], d["high"], d["low"], d["close"], d["daily_volume"])
```

## JavaScript

```javascript
const KEY = process.env.NOVIGAPI_API_KEY; // nv_...
const headers = { Authorization: "Bearer " + KEY };

const res = await fetch("https://novigapi.com/api/v1/ohlc/daily?date=2026-11-11&limit=1000", { headers });
const { data } = await res.json();
const movers = data
  .filter((d) => d.league === "NFL")
  .map((d) => ({ market: d.description, move: Math.round((d.close - d.open) * 1000) / 10 }))
  .sort((a, b) => Math.abs(b.move) - Math.abs(a.move))
  .slice(0, 10);
console.table(movers);
```

## Notes and edge cases

- Novig's markets file starts on 4 Aug 2026 and its trades file on 3 Aug 2026, per index.json checked 12 Nov 2026.
- Past files do not change except for corrections Novig announces. If Novig withholds a trades file that fails validation, the markets file is still published.
- Novig may add CSV columns; we read the header row, so new columns do not break this endpoint.
- On 11 Nov 2026 markets.csv held about 118,860 market rows, most of them parlay (COMBO) rows; this endpoint serves the straight markets only.
- With `market_id`, days come newest first. With `date`, the day's markets come in market id order; page with `cursor`.

## Sources

- [Novig docs: Markets CSV](https://docs.novig.com/public-data/markets.md)
- [Novig docs: Exchange Data](https://docs.novig.com/public-data/overview.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.
