# GET /v1/compare/{market_id}

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

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

GET /v1/compare/{market_id} puts one Novig market beside FanDuel and DK Sportsbook prices on exactly the same line: Novig's bid, ask and fair price per outcome, and for each book the American and decimal odds, implied probability, age and EV% against the fair price. Recomputed every 60 seconds, checked 12 Nov 2026. (Source: [Novig API docs: Trading fees](https://docs.novig.com/api/concepts/fees.md))

## What it returns

Use it when you already hold a Novig market id (from [markets](https://novigapi.com/docs/endpoints/markets), [player props](https://novigapi.com/docs/endpoints/player-props) or a [+EV row](https://novigapi.com/docs/endpoints/ev)) and want every book's price on that exact line.

`books` is empty when no book lists exactly that line right now; Novig lists far more lines than a sportsbook does.

## Parameters

Query and path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| market_id | string | Yes | Novig market id, in the path. |


## Request

```bash
curl -s "https://novigapi.com/api/v1/compare/01a1d1b9-25e9-7a90-bc19-a23602c58aac" \
  -H "Authorization: Bearer nv_..."
```

## Response

```json
{
  "data": {
    "market_id": "01a1d1b9-25e9-7a90-bc19-a23602c58aac",
    "event_id": "01a1ce81-c543-79b2-964e-e530fc5d03b1",
    "league": "NHL",
    "market_type": "SHOTS_ON_GOAL",
    "description": "Gabriel Perreault 1.5 SHOTS_ON_GOAL",
    "line": 1.5,
    "status": "OPEN",
    "starts_at": "2026-11-14T02:00:00.000Z",
    "home": "Vancouver Canucks",
    "away": "New York Rangers",
    "player_slug": "gabriel-perreault",
    "exchange": {
      "name": "Novig",
      "fair_formula": "fair = (bid + (1 - other side's bid)) / 2, before fees",
      "outcomes": [
        {
          "outcome": "Over 1.5",
          "side": "over",
          "bid": 0.55,
          "ask": 0.57,
          "fair_probability": 0.56,
          "fair_american": -127,
          "fair_american_text": "-127",
          "observed_at": "2026-11-13T02:57:19.000Z"
        },
        {
          "outcome": "Under 1.5",
          "side": "under",
          "bid": 0.43,
          "ask": 0.45,
          "fair_probability": 0.44,
          "fair_american": 127,
          "fair_american_text": "+127",
          "observed_at": "2026-11-13T02:57:19.000Z"
        }
      ]
    },
    "books": [
      {
        "book": "fd",
        "book_name": "FanDuel",
        "side": "over",
        "american": -174,
        "american_text": "-174",
        "decimal": 1.5747,
        "implied_probability": 0.635,
        "age_seconds": 43,
        "ev_pct": null
      },
      {
        "book": "fd",
        "book_name": "FanDuel",
        "side": "under",
        "american": 132,
        "american_text": "+132",
        "decimal": 2.32,
        "implied_probability": 0.431,
        "age_seconds": 43,
        "ev_pct": 2.08
      }
    ],
    "matched": true,
    "note": "Book prices are on exactly this line. EV% = fair probability x book decimal odds - 1.",
    "observed_at": "2026-11-13T02:57:19.000Z"
  },
  "meta": {
    "observed_at": "2026-11-13T02:57:19.000Z",
    "source_age_seconds": 0,
    "edge_cached": false,
    "refresh_seconds": 60,
    "plan": "developer",
    "credits_charged": 1,
    "credits_remaining": 9874,
    "credit_policy": "credits_v1"
  }
}
```

## Fields

Response fields

| Field | Type | Description |
| --- | --- | --- |
| exchange.outcomes[] | object[] | Novig bid, ask and fair price per outcome, with fair American odds. |
| books[] | object[] | Each book and side: American and decimal odds, implied probability, age in seconds and EV% when it is at or above -3%. |
| matched | boolean | False when no book lists exactly this line right now. |
| 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. 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}"}

r = requests.get("https://novigapi.com/api/v1/compare/MARKET_ID", headers=HEADERS, timeout=10)
m = r.json()["data"]
for b in m["books"]:
    print(b["book_name"], b["side"], b["american_text"], b["ev_pct"])
```

## JavaScript

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

const res = await fetch("https://novigapi.com/api/v1/compare/MARKET_ID", { headers });
const { data } = await res.json();
console.log(data.exchange.outcomes, data.books);
```

## Notes and edge cases

- Every plan can call it, Free included; Free sees the prices as they are now, one market per call.
- The [no-vig calculator](https://novigapi.com/no-vig-calculator) devigs a book's own two prices if you want its implied fair price instead.

## Sources

- [Novig API docs: Trading fees](https://docs.novig.com/api/concepts/fees.md)
- [Novig API docs](https://docs.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.
