---
title: "Returns the merged odds board for a sport: every event with its moneyline, spread and total prices at each sportsbook, plus per-response freshness."
method: GET
path: "/api/v1/{sport}/odds"
tags: ["Odds"]
---

# Returns the merged odds board for a sport: every event with its moneyline, spread and total prices at each sportsbook, plus per-response freshness.

`GET /api/v1/{sport}/odds`

## Request

- Base URL: `https://api.owlsinsight.com`
- URL: `https://api.owlsinsight.com/api/v1/{sport}/odds`
- Auth: HTTP bearer

Returns the merged odds board for a sport: every event with its moneyline, spread and total prices at each sportsbook, plus per-response freshness.

Kalshi and Polymarket are not in this feed; read them from their v2 source endpoints.

meta.freshness.stale turns true once the board is over 90 seconds old.

meta.market is the market the board was narrowed to (all when none), by the route or by the market parameter.

Query parameters this endpoint does not read are reported in meta.ignored_params rather than rejected; a value the endpoint read but could not apply (an unknown market, a comma list where one value is allowed, a book alias with no valid key) is reported too, with the reason in meta.ignored_reasons.

Unknown book keys inside books are dropped and the applied list is meta.requestedBooks.

home_team and away_team are one canonical string per team across every book for NFL, college football, NBA, NHL, MLB and college basketball: the name as returned is the join key. eventId is {sport}:{away}@{home}-{YYYYMMDD}, built from those names, and is the key the /api/v1/history endpoints use. Soccer and tennis carry each book's own spelling.

/api/v1/normalize maps an outside name (a score feed, a spreadsheet) onto ours; it is not needed for names we return.

home_team_id and away_team_id (homeTeamId and awayTeamId on /api/v1/history/games) are the stable roster id of the team behind each name, the same from every book and spelling. The key is absent, never null, when a name is not on our roster: every tennis name, a soccer or college name we do not carry, and sports without a roster. There is no abbreviation field.

## Path parameters

- `sport` string, required

## Query parameters

- `books` string
- `market` string
- `exclude_exchanges` string
- `alternates` string
- `league` string

## Response `200`

OK

- OddsResponse
  - `data` object: Keyed by sportsbook name (e.g. "pinnacle", "fanduel").
  - `meta` OddsMeta
    - `alternates` boolean
    - `availableBooks` string[]
    - `booksReturned` string[]
    - `freshness` OddsFreshness
      - `ageSeconds` number, double
      - `droppedAsFinished` number, double: Events dropped because the match was confirmed finished (realtime only).
      - `droppedAsStale` number, double: Events dropped because their scheduled start is older than the sport's max plausible live duration — a source-independent staleness guard (realtime only).
      - `stale` boolean
    - `ignored_params` string[]: Query parameters the endpoint did NOT honour, sorted. Present only when something was ignored, so a clean request carries no key at all (never an empty array). A name we do not read, or a filter whose value did not resolve, lands here instead of silently returning the full board.
    - `ignored_reasons` object: Why a name in `ignored_params` was ignored, keyed by that name. Present only for the entries that have a reason: an unknown parameter name has none, so it appears in `ignored_params` alone.
    - `last_odds_change` string
    - `league` string
    - `market` string
    - `requestedBooks` string[]
    - `sport` string
    - `sport_key` string
    - `timestamp` string
  - `success` boolean

---

[API](https://skmtc.dev/owlsinsight/apis/owls-insight-api.md) · [All operations](https://skmtc.dev/owlsinsight/apis/owls-insight-api/llms.txt) · [OpenAPI document](https://skmtc.dev/owlsinsight/apis/owls-insight-api/revisions/76c1ea016ff1?raw)
