# GET /v1/markets/{id}

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

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

GET /v1/markets/{id} returns one Novig market with each outcome's best bid, ask, last trade and fair price, plus volume, open interest and fees. On paid plans it is at most about 10 seconds old. On 12 Nov 2026 Novig's public catalog cached single-market reads at the edge for 10 seconds. (Source: [Novig API reference: Get a market](https://docs.novig.com/api-reference/catalog/get-a-market.md))

## What it returns

The same object as a row of [GET /v1/markets](https://novigapi.com/docs/endpoints/markets), for one id. Use it to refresh a market you already track, or to resolve an id you got from a [webhook](https://novigapi.com/docs/endpoints/webhooks) or the [stream](https://novigapi.com/docs/endpoints/stream).

## Parameters

Query and path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| id | string (path) | Yes | Novig market id. |


## Request

```bash
curl -s "https://novigapi.com/api/v1/markets/01a1d001-e383-76c1-b24d-9646dcacfee6" \
  -H "Authorization: Bearer nv_..."
```

## Response

A real first-half total from 12 Nov 2026. Bids of 0.48 (Over) and 0.49 (Under) give an Over ask of 0.51 and a fair price of 0.495. It is a game market, so `player_slug`, `team_slug` and `stat_slug` are null, and it has not settled, so `result` is null.

```json
{
  "data": {
    "market_id": "01a1d001-e383-76c1-b24d-9646dcacfee6",
    "event_id": "01a1ca90-4a76-7503-acc5-4d5bfbf1c1d5",
    "league": "NBA",
    "market_type": "TOTAL_1H",
    "description": "TOR @ PHI t107.5 1H",
    "strike": 107.5,
    "status": "OPEN",
    "player_slug": null,
    "team_slug": null,
    "stat_slug": null,
    "starts_at": "2026-11-13T00:05:00.000Z",
    "fee_coefficient": 0.06,
    "fee_charged": "WHEN_LIVE",
    "maker_credit": 0.25,
    "volume": 100000,
    "open_interest": 100000,
    "first_seen": "2026-11-12T17:29:44.454Z",
    "closed_at": null,
    "event_description": "Toronto Raptors @ Philadelphia 76ers",
    "event_status": "OPEN_PREGAME",
    "outcomes": [
      {
        "outcome_id": "01a1d001-e383-76c1-b24d-965e2b994493",
        "name": "Over 107.5",
        "status": "PENDING",
        "bid": 0.48,
        "bid_qty": 60000,
        "ask": 0.51,
        "fair": 0.495,
        "last": 0.5,
        "spread_pp": 3,
        "american": 102,
        "decimal": 2.0202
      },
      {
        "outcome_id": "01a1d001-e383-76c1-b24d-9668ba7561ab",
        "name": "Under 107.5",
        "status": "PENDING",
        "bid": 0.49,
        "bid_qty": 50000,
        "ask": 0.52,
        "fair": 0.505,
        "last": 0.5,
        "spread_pp": 3,
        "american": -102,
        "decimal": 1.9802
      }
    ],
    "observed_at": "2026-11-12T17:23:56.000Z",
    "source_age_seconds": 6,
    "edge_cached": true,
    "result": null
  },
  "meta": {
    "observed_at": "2026-11-12T17:23:56.000Z",
    "source_age_seconds": 6,
    "edge_cached": true,
    "plan": "developer",
    "credits_charged": 1,
    "credits_remaining": 9874,
    "credit_policy": "credits_v1"
  }
}
```

## Fields

Response fields

| Field | Type | Description |
| --- | --- | --- |
| market_id | string | Novig market id (UUID). |
| event_id | string | The game or event the market belongs to. |
| league | string | League code, such as `NBA` or `NFL`. |
| market_type | string | Novig market type, such as `STEALS`, `SPREAD` or `RECEIVING_YARDS_PROTECTED`. |
| description | string | Novig's own label, such as `Cooper Flagg 1.5 STEALS`. |
| strike | number or null | The line. Novig serves it as a string; we return a number. |
| status | string | `OPEN` while listed, `CLOSED` once it leaves Novig's catalog. |
| player_slug | string or null | Player slug resolved from the description, such as `cooper-flagg`. Null on game and team markets. |
| team_slug | string or null | Team slug on team markets such as team totals. Null on game lines, whose sides are the outcomes. |
| stat_slug | string or null | Stat slug on player props, without the `_PROTECTED` suffix, such as `steals`. |
| starts_at | string (ISO 8601) | Scheduled start in UTC, converted from Novig's `startsTs` in milliseconds. |
| fee_coefficient | number | Novig's `market.fee.coefficient`, 0.06 on every schedule checked 12 Nov 2026. |
| fee_charged | string or null | Novig's `market.fee.charged`: `WHEN_LIVE` (taker pays only while the event is `OPEN_INGAME`) or `ALWAYS` (major US league futures). Null until our collector has stored it for the market. |
| maker_credit | number or null | Novig's `market.fee.makerCredit`: the maker's share of the taker fee, 0.25 on game markets and 0.5 on futures since 22 Oct 2026. |
| volume | integer | Contracts traded, all time. One Novig API contract pays $0.01 if it wins. |
| open_interest | integer | Contracts outstanding, netted per wallet by Novig. |
| first_seen, closed_at | string or null | When our collector first listed the market, and when it left Novig's catalog (null while open). |
| event_description, event_status | string or null | The event's label, such as `Dallas Mavericks @ Minnesota Timberwolves`, and its status, such as `OPEN_PREGAME`. |
| outcomes[].outcome_id | string | Novig outcome id. |
| outcomes[].name | string | Outcome label, such as `Over 1.5` or `PHX +13.5`. |
| outcomes[].status | string or null | `PENDING` until the outcome is graded (Novig's to-be-decided status), then Novig's grade. |
| outcomes[].bid | number or null | Best resting bid, as a probability from 0 to 1. Null when nobody is bidding. |
| outcomes[].bid_qty | integer or null | Contracts resting at the best bid. One contract pays $0.01. |
| outcomes[].ask | number or null | Price to buy now: 1 minus the best bid on the other outcome. Novig's book holds bids only. Two-outcome markets only. |
| outcomes[].fair | number or null | Fair price: (bid + (1 - other bid)) / 2. Null unless both outcomes have a bid. |
| outcomes[].last | number or null | Last traded price. |
| outcomes[].spread_pp | number or null | Ask minus bid, in percentage points. |
| outcomes[].american, outcomes[].decimal | number or null | The fair price (or the last price when there is no fair) as American and decimal odds. |
| 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. |
| result | object or null | Once the market has a result: the same row as [GET /v1/results](https://novigapi.com/docs/endpoints/results). Null before. |
| 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

1 credit per call, whatever the size of the answer. A 404 for an unknown id costs 0. 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}"}

market_id = "01a1d001-e383-76c1-b24d-9646dcacfee6"
r = requests.get(f"https://novigapi.com/api/v1/markets/{market_id}", headers=HEADERS, timeout=10)
if r.status_code == 404:
    print("market closed or unknown")
else:
    m = r.json()["data"]
    for o in m["outcomes"]:
        print(o["name"], "bid", o["bid"], "ask", o["ask"], "fair", o["fair"])
```

## JavaScript

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

const id = "01a1d001-e383-76c1-b24d-9646dcacfee6";
const res = await fetch("https://novigapi.com/api/v1/markets/" + id, { headers });
if (res.status === 404) throw new Error("market closed or unknown");
const { data: m, meta } = await res.json();
console.log(m.description, m.outcomes.map((o) => o.name + " " + o.fair), "as of " + meta.observed_at);
```

## Notes and edge cases

- Novig removes markets from its public catalog when they close. We keep the last state we saw, with `status: CLOSED` and `closed_at` set, and the grade once known in `result`.
- `last` can sit outside the bid and ask: it is the last fill, which may be minutes old on a quiet market.
- Fees are not in the price. Novig's taker fee is fee = 0.06 x P x (1 - P) x contracts x $0.01 (P is the fill price as a probability; one contract pays $0.01), so 0.06 x P x (1 - P) per $1 of payout. Game markets charge it only while the event is live (`fee_charged: WHEN_LIVE`); futures in NFL, NCAAF, NCAAB, NCAAWB, MLB, NBA, WNBA and NHL charge it in every phase (`ALWAYS`); golf, tennis, UFC, F1 and NASCAR futures and series winners never do. Makers never pay it (Novig docs, Trading fees, checked 12 Nov 2026).

## Sources

- [Novig API reference: Get a market](https://docs.novig.com/api-reference/catalog/get-a-market.md)
- [Novig API docs](https://docs.novig.com)
- [Novig API docs: Trading fees](https://docs.novig.com/api/concepts/fees.md)

---

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.
