> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xinsider.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The Markdown of an API reference page leaves out the OpenAPI schema.
> Every object an endpoint returns or a webhook carries, with each field's type, presence and meaning, is on https://docs.0xinsider.com/api-reference/objects.md.
> The full OpenAPI 3.1 spec names each operation's and each webhook's exact parameters, request body and response schema: https://docs.0xinsider.com/api-reference/openapi.json.

# API changelog: November 4, 2026

> 33 API, SDK, CLI, MCP, OAuth, and feed changes from November 4, 2026, newest first, each with its effect on clients. Newer changes are on the API changelog.

These are the API changelog entries from November 4, 2026, newest first. The newest changes are on the [API changelog](https://docs.0xinsider.com/changelog.md).

**November 4, 2026**

Each market's closing line, and closing line value on every large trade and per wallet

[`GET /api/v1/market/{condition_id}/close`](https://docs.0xinsider.com/api-reference/endpoint/get-market-close) is new. It returns a sports or esports market's closing price on each side, read from Polymarket's price history in the last minute before kickoff, with the interval and source it came from. A market without one says `pending` or `unavailable` with a reason, never `0`.

Every large trade now carries `clv`, its closing line value against that close, on [`GET /api/v1/large-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades), [`/large-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades-history), [`/large-trades/{id}`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trade), and the trades on `/events/feed/since`:

* `status`: `measured`, `in_play` (placed at or after kickoff), `pending` (the close is not stored yet), or `unavailable`, with `unavailable_reason`.
* `clv_cents`: positive when the trade beat the close. On a buy it is the closing price minus the price paid, on a sell the price received minus the closing price, in cents per share and before fees.
* `close_price`, `close_anchor_at`, `pre_kickoff`, and `basis_version` (`clv@v1`).

[`GET /api/v1/trader/{address}/clv`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-clv) is new. It sums a wallet's large trades in a window: average CLV, size-weighted average, the share that beat the close, and a per-market average with a 95% interval.

The remote MCP server adds the tools `get_market_close` and `get_trader_clv`. The stdio MCP server, the CLI (`market close`, `traders clv`) and the TypeScript client (`getMarketClose`, `getTraderClv`) add them in their next release. Both endpoints need a Pro or Max key.

**Backward compatible.** `clv` is a new field on the large trade object; no field changed.

**What to change:** Nothing. If your client refuses unknown fields on a large trade, allow `clv`.

**November 4, 2026**

SDK 0.40.0 and MCP 3.14.0 carry game market settlement, quotes and trading terms

`@0xinsider/sdk` 0.40.0 and `@0xinsider/mcp` 3.14.0 are on npm, and 3.14.0 is in the MCP Registry. They bring the November 4 game market changes listed below to the SDK types, the local MCP server and the CLI.

Before these releases, the local `list_game_markets` tool in 3.13.0 accepted only `"sharp_money"` in `expand` and refused `"quotes"` and `"trading_terms"` with an input validation error. SDK 0.39.0 had no type for `settlement`, `quote` or `trading_terms`. The entries below said the MCP tool and the SDK types describe these fields, which was true of the remote MCP server and not yet of the packages you install.

* SDK: every [`listGameMarkets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) row carries `settlement`, `expand: ["quotes"]` adds each outcome's `quote`, and `expand: ["trading_terms"]` adds each row's `trading_terms`, with `min_order_size_shares`.
* SDK: `getMarketSnapshot` and the `getGame` winner markets carry `settlement`, and `listGames` takes `expand: ["settlement"]`.
* Local MCP: `list_game_markets` takes `"quotes"` and `"trading_terms"` in `expand`, and `list_games` takes `expand` as one value or an array of `"sharp_money"` and `"settlement"`. The `list_game_markets`, `list_games`, `get_game` and `get_market_snapshot` descriptions match the remote server's.
* Both: the `league` description says to spell a league as the list's own `coverage.leagues` does, since [`GET /api/v1/coverage`](https://docs.0xinsider.com/api-reference/endpoint/get-coverage) lists no leagues.

The local server lists the same 69 tools as the remote server. The [CLI](https://docs.0xinsider.com/integrations/cli.md), [MCP](https://docs.0xinsider.com/integrations/mcp.md) and [introduction](https://docs.0xinsider.com/index.md) pages now install `@0xinsider/mcp@3.14.0`.

**Backward compatible.** Every change adds a type, a field or an `expand` value, and one `list_games` `expand` value still works.

**What to change:** Run `npm install @0xinsider/sdk@0.40.0`. For the CLI and the local MCP server, run `npm install --global @0xinsider/mcp@3.14.0`, or change a client's `@0xinsider/mcp@3.13.0` argument to `@0xinsider/mcp@3.14.0`. `0xinsider --version` prints `3.14.0` once the update is in place.

**November 4, 2026**

A team keeps one name before, during and after its game, the name its moneyline outcome uses

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game), and the MCP `list_games` and `get_game` tools, now give a team the same `competitors[].name` in every state: upcoming, live and finished. It is the moneyline outcome that names the team, in the outcome's own text, so a side reads as the label Polymarket prices it under.

Before this change, the name depended on the game's state. Over every upcoming and live game and every game finished since October 28, read on November 4, 573 teams in 43 leagues carried more than one name; with this change, none do. An upcoming NFL game read `Jacksonville Jaguars` while its moneyline, and the same team's finished games, read `Jaguars`. A finished Premier League game read `Villa` while upcoming ones read `Aston Villa FC`.

* NFL upcoming games: the nickname the outcomes use (`Jaguars`, `Ravens`). NHL: `Utah`, not `Mammoth`.
* Tennis, every state: the full name the outcome uses (`Jacopo Vasami`, not `J. Vasami`).
* MLB and other finished games: the outcome's name (`Milwaukee Brewers`, not `Brewers`).
* Soccer, whose win markets read `Yes` and `No`: the club's full name in every state (`Aston Villa FC`).
* Where Polymarket's outcome drops an accent, so does the name (`Fenerbahce`). Where an outcome names a team some other way (`Canada` for `Team Canada`), the team's full name stays.
* Upcoming games' `markets[].outcome_yes` and `outcome_no` carry the same text.
* `provider_id`, `logo`, `side` and price values are unchanged. No team lost a `provider_id` or a paired price.

**Backward compatible.** No field was added, removed or retyped. Only `competitors[].name` values changed, and upcoming games' outcome labels with them.

**What to change:** A client that matched a team by its old name should match by `provider_id`, which is the same in every state, or by the name now served.

**November 4, 2026**

Game markets carry each market's minimum order size in shares on expand=trading\_terms

[`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) with `expand=trading_terms` now carries `trading_terms.min_order_size_shares`: the smallest order Polymarket's order book accepts for the market, in shares. It is Polymarket's `orderMinSize`, read from the same market record as the other terms.

Before this change, `trading_terms` left the minimum order size out. Polymarket's market reference calls the figure USDC and its order guide calls it shares. Polymarket's order book accepts a limit order of exactly that many shares at the smallest price step, worth as little as \$0.05, so the unit is shares.

* `min_order_size_shares`: a number, or `null` when the record carries none or `status` is not `observed`. It was `5` on every open sports market we read on November 4.
* Compare it with an order's share count, not its dollar cost. A buy of 5 shares at $0.40 costs $2.00 and meets a minimum of 5.
* The `list_game_markets` MCP tool, the SDK types and the OpenAPI document describe the same.

**Backward compatible.** The field is new; no field was removed or retyped.

**What to change:** Nothing. To check an order against the minimum, read `min_order_size_shares` instead of a separate order book request.

**November 4, 2026**

Finished soccer games name the home and away side of each team-win market

A finished soccer game in [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) now sends `side` `home` or `away` on its two team-win markets after it leaves the live board, as it did before kickoff. The draw market keeps `side` `draw`.

Before this change, those two markets left out `side`, so only the market slug told a client which team each one priced. On November 4, 2026 that was 2,130 markets of the 1,065 finished soccer games since October 28.

* The team is the one Polymarket's own title for the market names, such as `FC Bayern München`, matched to one of the game's two `competitors`. The first competitor is `home`, the second `away`.
* `side` is still left out when the game's markets store no team pair, when the title names neither competitor or both, when both markets name the same team, or when the market's slug names the other team. It is never taken from the slug or from the order of the markets.
* Other sports, and soccer games still on the live board, are unchanged.

**Backward compatible.** `side` was already documented on these markets and is now sent where it was missing.

**What to change:** Nothing. If you read a finished soccer market's team from its slug, read `side` instead.

**November 4, 2026**

Quotes and snapshots no longer serve a 0 bid or a 1 ask for a side with no orders

[`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) with `expand=quotes` and [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) now serve a book with one side, or with no orders, as that book for as long as we stream it, also after its side moves, flips or empties.

Polymarket's best bid and ask stream sends a side with no orders as a bid of `0` or an ask of `1`. Before this change, we stored that as a price. Such a book read as two-sided, then as missing:

* Its quote carried `best_bid: 0` or `best_ask: 1`, and its snapshot read `top_of_book.status: available`. On November 4 at 11:27 UTC, the junjilopzfx0764 vs. Stronghold Overwatch moneyline (`ow-jun-strong-2026-11-04`) served junjilopzfx0764 at bid 0 / ask 0.97 and Stronghold at bid 0.03 / ask 1, while Polymarket's book held only asks for the first and only bids for the second.
* Once that book went 30 seconds without an update, the outcome read `unavailable` (`cache_miss` on the snapshot). The same market read `cache_miss` from 11:37 to 11:42 UTC while its Polymarket book stayed the same.

Now:

* A served `best_bid` is never `0` and a served `best_ask` is never `1`. A side with no orders is `null` beside a set `book_observed_at`, and the outcome stays `observed` while its book has one side or none.
* The snapshot reads `one_sided_book` or `empty_book` for such a book, never `available`.
* Books with orders on both sides are unchanged.

**Backward compatible.** No field was added, removed or retyped; only values change.

**What to change:** Nothing. A client that treated a `0` bid or a `1` ask as a price can drop that handling.

**November 4, 2026**

Finished games that store no team pair show each side's crest, and its provider\_id where it has one

A finished game in [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) whose markets store no pair of team ids now matches each side to one of the two teams its slug names. Each matched side carries that team's `logo`, and its `provider_id` where the team has one. Most of these are FCS college football games: Polymarket has no team id for many of those schools.

Before this change, such a game served each side's name with no `provider_id` and no `logo`:

* Bryant vs. Brown on October 10 (`cfb-bryant-brwn-2026-10-10`) served neither side's id or logo, though Bryant's id is `231`.
* 63 finished college football games played since October 5 were affected. Of their 126 sides, 30 carried an id and 86 a logo.

Each of these games now serves its two teams:

* How a side is matched: by its outcome name, such as `Brown`, against the two teams the slug's codes name (`bryant`, `brwn`), exactly or by its words, never by position. When a stored final score names neither side's team, the settled moneyline decides: the side with the higher score is the team the winning outcome names.
* `logo` is the team's crest. `provider_id` is the team's id, or absent when the team has none. In the 63 games, 44 sides now carry an id and 125 a logo.
* `coverage.competitors` is `provider_ids` only when both sides carry an id, else `labels`. One Counter-Strike game, maybe vs. Honvéd on November 2, now reads `provider_ids`.
* Games whose markets store a team pair are unchanged.

**Backward compatible.** No field was added, removed or retyped; only values change.

**What to change:** Nothing. A client that cached one of these games can read it again for the crests and ids.

**November 4, 2026**

Quotes and snapshots say when reading again will not bring a market's live book

[`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) with `expand=quotes` adds `book_unavailable_reason` to each outcome's quote, and [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) adds the reason `stream_capacity`.

We always stream Polymarket's order book for the sports boards and for liquid games around kickoff. Any other open market gets a live book when you read it, up to a shared number of markets that API reads can hold at once. Before this change, a read past that number answered like a first read (`unavailable` on a quote, `cache_miss` on a snapshot), so reading again looked as if it would help, and it did not. On November 4, one read of every active market of the 23 live games asked for 359 markets against room for 100, and 31 markets with a two-sided Polymarket book stayed `unavailable`.

* `quote.book_unavailable_reason` is `null` when `book_observed_at` is set. Otherwise it is `cache_miss` (no book held yet; read again after a few seconds), `stream_capacity` (API reads already hold every live book they can open; reading again does not help until fewer markets are read), `no_orderbook` or `missing_provider_token_id`.
* The snapshot's `outcomes[].top_of_book.reason` and `freshness.top_of_book.reason` read `stream_capacity` instead of `cache_miss` in the same case.
* A market we always stream no longer takes one of those places when you read it, so more of the markets you read get a live book.
* The `list_game_markets` MCP tool, the SDK types and the OpenAPI document describe the same.

**Backward compatible.** `book_unavailable_reason` is a new key, and `stream_capacity` is a new value of an existing string field. A client that treats an unknown snapshot reason as "no book" keeps working.

**What to change:** If you poll many markets, read `book_unavailable_reason`: on `stream_capacity`, read fewer markets, or that one less often, instead of retrying it.

**November 4, 2026**

Quotes and snapshots serve a book with one side or no orders, not unavailable

[`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) with `expand=quotes` now serves an outcome whose Polymarket order book holds orders on one side only, or none, as `observed`: the side with orders carries its best price, an empty side is `null`, and `book_observed_at` is set. [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) names the same books in `top_of_book.reason`.

Before this change, such an outcome read `unavailable` with every figure `null`, and the snapshot read `cache_miss`, for as long as the book stayed that way; a later read did not fill it. On November 4 that was about 260 empty and 60 one-sided books across the live games.

* `quote.status` is `observed` with `book_observed_at` set and a `null` `best_bid` (no bids) or `best_ask` (no asks), or both `null` for an empty book. `price` is unchanged.
* The snapshot's `top_of_book.status` stays `available` only for a book with both sides. A book with one side is `unavailable` with `reason` `one_sided_book` and carries that side's `best_bid` or `best_ask`, with no spread or depth; an empty book is `unavailable` with `reason` `empty_book`.
* `freshness.top_of_book.reason` takes the same values: `one_sided_book` when either outcome's book has one side, then `empty_book`, then `cache_miss`.
* The `list_game_markets` MCP tool and the OpenAPI document describe the same.

**Backward compatible** for a client that reads `status` and `reason` first. A client that took a present snapshot `best_bid` or `best_ask` to mean a two-sided book now also sees one beside `unavailable`.

**What to change:** Nothing, unless you read snapshot prices without checking `top_of_book.status`; then check it. To tell an empty side from a missing figure on a quote, read `book_observed_at`.

**November 4, 2026**

Finished tennis doubles games from October 17 to 31 name both pairs as the two sides

A finished ATP or WTA doubles game in [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) now names each side by its pair, such as `Bolelli/Vavassori`, with the pair's `provider_id` and `logo`. This applies to doubles games whose stored live score was written before October 31, 2026.

Before this change, such a game named one player on each side, often the two partners of one pair, and the other pair was missing:

* Bolelli/Vavassori vs. Andreozzi/Guinard on October 30 served `Simone Bolelli` (no `provider_id`) against `A. Vavassori`, with his singles id `625505`, the Italian flag and a `record`.
* 272 doubles games played October 17 to 31 were affected, 201 ATP and 71 WTA. In 234 of them `coverage.competitors` was `labels`. The other 38 carried singles players' ids.

Each of these games now serves its two pairs:

* How a side is matched: by the pair code in the game's slug (`bolevav`, `andrgui`), in the slug's order, as for doubles games stored since October 31. This applies only while both sides' scores are `0`, the placeholder Polymarket sends for doubles games. A side with a real score keeps its stored name.
* `name`, `provider_id`, `logo`: the pair's, as on other doubles games. `record` is `null`: the stored record was the player's.
* `coverage.competitors`: `provider_ids` when both pairs are found.
* Doubles games whose stored score already names the pairs are unchanged.

**Backward compatible.** No field was added, removed or retyped; only values change.

**What to change:** Nothing. A client that cached one of these games can read it again for the corrected sides.

**November 4, 2026**

Finished games whose stored score names a side by an unknown code, or as the wrong team, name each side's team

A finished game in [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) now names each side by the team the game's moneyline names, with its `provider_id` and `logo`. This applies when the stored live score names the side by a code no team carries, or carries another team's identity.

Before this change, such a side kept what the stored score said:

* Air Force vs. Wyoming on October 23 served the codes `AFA` and `WYO`, with `provider_id` and `logo` set to `null` and `coverage.competitors` set to `labels`. So did 132 other college football games, two NHL games and one CS2 game.
* Two South Dakota State games served that side as San Diego State: its name, id `212`, logo and record.
* A CS2 side was named `GODS PLAN` (id `139465`) beside Joga de terno's logo.

Each of these games now serves both teams of its moneyline:

* How a side is matched: by its code or name against the two teams of the game's stored team pair, or as the one team left once the other side is named. When neither side names a team, the settled moneyline decides: in a final score by points, the side with the higher score is the team that won. A side is never given a team by its position.
* When it applies: only when the moneyline's two outcomes name the pair's two teams, one each. A game whose stored pair disagrees with its outcomes is unchanged.
* `name`, `provider_id`, `logo`: the matched team's, as on other finished games. In college football `name` is the school (`Air Force`), not the mascot.
* `record`: `null` where the stored score carried another team's record. Elsewhere it stays the record stored at the game.
* `coverage.competitors`: `provider_ids` when both sides carry a team.
* Tennis doubles games that showed one pair's two partners as the two sides have their own entry.

**Backward compatible.** No field was added, removed or retyped; only values change.

**What to change:** Nothing. A client that cached one of these games can read it again for the corrected sides.

**November 4, 2026**

Game markets carry each market's fees, liquidity rewards, order delay and tick with expand=trading\_terms

[`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) takes `expand=trading_terms`, which adds `trading_terms` to every row: the market's fee schedule, liquidity reward settings and allocations, order delay and tick, as Polymarket's market record states them, with the time it was read.

Before this change, a client that quotes a game's lines had to read each market from Polymarket's Gamma or CLOB API to learn what it pays and how long a marketable order waits.

* `status`: `observed`, `not_listed` (Polymarket's market list returned no record for the market) or `unavailable` (no read yet; every figure is `null`, and a read a few seconds later usually answers).
* `fees_enabled` and `fee_schedule`: `rate`, `exponent`, `taker_only` and `rebate_rate`, the fraction of taker fees rebated to the resting maker.
* `rewards_min_size` (shares), `rewards_max_spread` (cents from the midpoint) and `reward_allocations`, each with `rewards_amount`, `rewards_daily_rate`, `start_date` and `end_date`.
* `seconds_delay`: how many seconds a newly placed marketable order waits before it can match. Polymarket sets it on sports markets around live play.
* `tick_size` and `observed_at`. Each market's read is refreshed about once a minute.
* It works on every plan and adds 1 to the request cost: 3 with `trading_terms`, 4 with `quotes` too.
* The `list_game_markets` MCP tool takes `"trading_terms"` in its `expand` array. The OpenAPI document and the SDK types describe the block.

**Backward compatible.** `trading_terms` appears only when you send `expand=trading_terms`, and every key in it is always present; `null` means unknown. Without the expand, the response is unchanged.

**What to change:** Nothing. To read a game's fees, rewards and order delay in one request, send `expand=trading_terms`.

**November 4, 2026**

Finished games filtered by a small league reach the end in a few pages

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) with `status=ended`, `cancelled` or `postponed` and a `league` filter now reads only the games that league can hold, so a small league inside a large sport no longer spends each page on the sport's other games.

Before this change, the `league` filter ran after a page's read budget, which counted every game of the league's sport. `league=ukr1` read through all of Soccer, and most of its pages came back empty with `has_more: true`. Paging kickoffs from October 21 to November 4 with `limit=100`, on a copy of production data, before and after:

* `league=ukr1`: 21 pages (15 empty) before, 8 pages (4 empty) after, the same 13 games.
* `league=enl`: 16 pages (7 empty) before, 5 pages (none empty) after, the same 34 games.
* `league=taipei`: 24 pages (19 empty) before, 5 pages (2 empty) after, the same 39 games.
* `league=cfb`, `league=epl` and `sport=Football` return the same games in the same pages or fewer.

**Backward compatible.** Rows, their order and the cursor format are unchanged; only where a page ends moves. A page can still be short, or empty, while `has_more` is `true`.

**What to change:** Nothing. Keep following `next_cursor` until `has_more` is `false`.

**November 4, 2026**

Game markets carry each outcome's price, best bid and best ask with expand=quotes

[`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) takes `expand=quotes`, which adds a `quote` to every outcome on the page: the price Polymarket shows, and the best bid and best ask, each with the time it was observed.

Before this change, a game's spreads, totals and props carried no price, so a client had to call Polymarket's CLOB, or read [Market snapshot](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot.md) once per market.

* `status`: `observed` (we hold the price, the book or both; a `null` figure beside it is one we do not hold), `no_orderbook` (Polymarket confirmed the outcome has no order book and we hold no price) or `unavailable` (we hold nothing for it yet; every figure is `null`, and a read a few seconds later usually answers, because the request starts covering the page's open markets).
* `price`, from 0 to 1, with `price_basis`: `midpoint` when the best bid and ask are at most \$0.10 apart, otherwise `last_trade`. `price_observed_at` is when the quote and trades behind it were observed. These are the figures Market snapshot serves as `current_price`, at full precision.
* `best_bid` and `best_ask`, from 0 to 1, with `book_observed_at`, when Polymarket's book update behind them was observed.
* It works on every plan and adds 1 to the request cost: 3 with `quotes`, 6 with `sharp_money` too.
* The `list_game_markets` MCP tool takes `"quotes"` in its `expand` array. The OpenAPI document and the SDK types describe the block.

**Backward compatible.** `quote` appears only when you send `expand=quotes`, and every key in it is always present; `null` means unknown. Without the expand, the response is unchanged.

**What to change:** Nothing. To price a game's lines in one request, send `expand=quotes`, and read again a few seconds later for an outcome that reads `unavailable`.

**November 4, 2026**

Finished tennis games keep their tournament as league in /api/v1/games

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) now give a finished game the `league` the live board gave it: the provider event's own league, which in tennis is the tournament (`taipei`, `pan pacific open`). Esports and cricket games outside a league scope (`cs2`, `lol` and the other scope leagues keep theirs) read their event's league the same way.

Before this change, a finished game read from its stored rows took the tour instead (`atp`, `wta`, `itf` or `challenger`), so a game changed `league` when it left the board, and `league=taipei&status=ended` found none of a tournament's finished games. A few ended tennis games still on the board also read `challenger`.

**Breaking** for clients that read or filter finished tennis games by a tour code: `league=wta&status=ended` no longer matches a game whose event names its tournament.

**What to change:** Filter finished games by the tournament, as you do for upcoming and live ones, and use `sport=Tennis` to read every tour.

**November 4, 2026**

Games, the game detail and the market snapshot carry each market's settlement

[`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) now carry `settlement`, the block [List game markets](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets.md) returns, and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) carries it with `expand=settlement`.

Before this change, only the game markets route said how Polymarket's oracle settled a market, so a client reading games or a snapshot had to make a second call to learn which side paid or whether a market settled 50-50.

* `GET /api/v1/games/{event_slug}`: every winner market carries `settlement`, also for a finished game read after it leaves the live board. The request cost stays 2.
* `GET /api/v1/games`: `expand=settlement` adds it to every winner market on the page, on every plan, and adds 2 to the request cost. It combines with `expand=sharp_money`. Without it, markets carry no `settlement` key.
* `GET /api/v1/market/{condition_id}/snapshot` and its Markdown twin: a top-level `settlement`, read from the market's event, or from its game for a market Polymarket files under a child event. `market.market_result` stays `null`.
* None of these reads waits for Polymarket. A game no read has asked about lately reads `status` `unavailable`, and its read starts at once, so a read a second or two later carries the block.
* The `list_games`, `get_game` and `get_market_snapshot` MCP tools, the OpenAPI document, the SDK types and the sandbox describe the field. The `list_games` tool's `expand` now also takes an array, `["sharp_money", "settlement"]`, for both blocks in one call; one value works as before.

**Backward compatible.** `settlement` is a new field, `expand=settlement` is a new value, and a single `expand` value is still accepted.

**What to change:** Nothing. To settle a position from a game or a snapshot read, read `settlement.result` and `settlement.payouts`, and treat `unavailable` as "ask again shortly", never as unsettled.

**November 4, 2026**

Upcoming college football games name each side by its school, not its mascot

An upcoming college football game in [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game), and in the MCP `list_games` and `get_game` tools, now names each side by its school.

Before this change, such a game named its sides by mascot until kickoff, and by school once it was live or finished. Ball State vs. UMass on November 4 read `Cardinals` and `Minutemen` in `competitors[].name` and `outcome_yes`, while the same response's `title` (`Ball State vs. UMass`), its `prices.provider` labels and Polymarket's moneyline outcomes read `Ball State` and `UMass`. Several schools share a mascot, so a mascot alone can name the wrong team: `Eagles` is Eastern Michigan, Boston College and Georgia Southern.

* `competitors[].name`, `markets[].outcome_yes` and `markets[].outcome_no`: the school (`Ball State`), as the moneyline outcomes name it. A team keeps one name before kickoff, in play and after the game ends.
* `markets[].prices.provider.binding_provenance`: `exact_labels` for a game Polymarket lists without team ids, where it read `elimination` or `null`. Prices are unchanged, except that a pair refused as `invalid` with `final_identity_mismatch` because its names disagreed is now `paired` at Polymarket's prices (Morehead State vs. Marist on November 7).
* `provider_id`, `logo`, `record` and `side` are unchanged.
* Every other league is unchanged, college basketball included: its names already carry the school (`Southern Indiana Screaming Eagles`).

**Backward compatible.** No field was added, removed or retyped. Only values changed for upcoming college football games: their side names and, for a game without team ids, the recorded way its prices were matched.

**What to change:** A client that matched an upcoming college football side by its mascot should match by `provider_id`, or by the school name now served.

**November 4, 2026**

Finished games with no stored score carry each side's team id and logo

A finished game in [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) that has no stored live score now carries `provider_id` and `logo` for each side its moneyline names, when the game's stored team pair includes that team.

Before this change, such a game named its `competitors` from the moneyline's two outcomes only, with `provider_id` and `logo` set to `null` and `coverage.competitors` set to `labels`. Western Kentucky vs. Sam Houston on October 14 is one example. The change reaches every sport: in a read of ten leagues on November 4, 468 of 1,586 finished games moved from `labels` to `provider_ids`, most of them table tennis (306) and tennis singles (102).

* `name`: unchanged. It stays the outcome's name, which in college football is the school (`Western Kentucky`), not the mascot.
* `provider_id` and `logo`: set when the outcome names one team of the game's team pair, by its exact name, alias or code, or by its words. A side is never given a team by its position. For a tennis or table tennis player, `logo` is the player's country flag, as on games with a stored score.
* `coverage.competitors`: `provider_ids` when both sides carry a team, else `labels`.
* A game whose legs store no team pair, such as Columbia vs. Penn on October 16, is unchanged.

**Backward compatible.** No field was added, removed or retyped; only values that were `null` are now set.

**What to change:** Nothing. A client that matches finished games to teams by name can use `provider_id` for these games too.

**November 4, 2026**

Finished games filtered by sport or league reach the end in far fewer pages

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) with `status=ended`, `cancelled` or `postponed` and a `sport` or `league` filter now spends each page's read on the filtered sport's games, so a page reaches several days of kickoffs instead of under one.

Before this change, a page's read budget counted every sport's games, and the filter dropped the others afterwards. A filtered walk of two weeks came back as dozens of pages, most of them empty with `has_more: true`. Paging kickoffs from October 21 to November 4 with `limit=100`, before and after:

* `league=cfb`: 51 pages (37 empty) before, 4 pages (none empty) after, the same 225 games.
* `league=nba`: 51 pages (29 empty) before, 5 pages (none empty) after, the same 104 games.
* `sport=Football`: 12 pages before, 5 after, the same 259 games.
* `league=ukr1`: 51 pages (42 empty) before, 18 pages (12 empty) after, the same 13 games. A small league inside a large sport still takes several short pages.

**Backward compatible.** Rows, their order and the cursor format are unchanged; only where a page ends moves. A page can still be short, or empty, while `has_more` is `true`.

**What to change:** Nothing. Keep following `next_cursor` until `has_more` is `false`. A league with no game on the live board reads every sport, as before: pass `sport` beside it (`sport=Esports&league=iem`) to narrow the read.

**November 4, 2026**

Finished games in /api/v1/games name each side and serve its current crest

A finished game in [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) and [`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) now names its `competitors` through the same team binding a live game uses, so `name`, `provider_id` and `logo` match the live board.

Before this change, a game the board had dropped served its sides exactly as the last live score stored them. Penn carried Polymarket's generic ESPN college football image, and Duke, Virginia and Yale an older crest file.

* `logo`: generic provider artwork is dropped, and a team with a current college or supplemental crest serves it.
* `provider_id` and `name`: a side whose score-feed code names its team, or the one side left once the other is named, carries that team's id and name. `coverage.competitors` can change from `labels` to `provider_ids`.
* `score` and `record` are unchanged: they stay the final score and the record stored at the game.
* A game whose two sides both carry codes that name no team, such as `AFA` and `WYO`, still serves those codes with no logo.

**Backward compatible.** No field was added, removed or retyped; only values change.

**What to change:** Nothing. A client that cached a finished game's `logo` or `provider_id` can read the game again for the corrected values.

**November 4, 2026**

Game markets carry each market's settlement: oracle status, payouts and 50-50

Every row of [`GET /api/v1/games/{event_slug}/markets`](https://docs.0xinsider.com/api-reference/endpoint/list-game-markets) now carries `settlement`: how Polymarket's oracle settled, or is settling, the market, from Polymarket's `/v2/resolutions`.

Before this change, a row said only `active` or `closed`, so a client had to call Polymarket to learn which side paid, whether a market settled 50-50, or whether a proposal was disputed.

* `status`: `observed` (Polymarket's resolution row is below), `not_posed` (no oracle request yet; `settled` is `false`) or `unavailable` (no read in hand; every other field is `null`, and a read a moment later may answer).
* `oracle_status`: Polymarket's lifecycle state as Polymarket writes it, such as `proposed`, `disputed` or `resolved`. `settled` is `true` when it is `resolved`.
* `payouts`: what one share of each outcome pays, in micro-USDC (`1000000` is \$1), in outcome index order. It is set only on a resolved row that carries payouts.
* `result`: `outcome` (one side paid in full; `winning_outcome_index` names it) or `split` (Polymarket's 50-50), read off `payouts` only.
* `was_disputed`, `resolved_at`, and for a pending market `expected_settlement_time` with `settlement_time_basis`: Polymarket's estimate of the earliest settlement, not a deadline.
* `proposed_answer`: `outcome_0`, `outcome_1`, `split` or `too_early`, the newest proposal of a pending round. A proposal is not a result.
* `observed_at`: when Polymarket answered. A settled read is refreshed every 10 minutes, any other every minute.
* The `list_game_markets` MCP tool, the OpenAPI document, the SDK types and the sandbox describe the block. The request cost stays 2.

**Backward compatible.** `settlement` is a new field, and every key in it is always present; `null` means unknown.

**What to change:** Nothing. To settle a position without calling Polymarket, read `settlement.result` and `settlement.payouts`, and treat `unavailable` as "ask again shortly", never as unsettled.

**November 4, 2026**

SDK 0.39.0 sends the stream's min\_grade\_at\_trade filter

`@0xinsider/sdk` 0.39.0 adds `min_grade_at_trade` to `StreamFilters`, so `streamFeed`, `streamFeedResilient` and `consumeStreamCheckpointed` can send the [`GET /api/v1/stream`](https://docs.0xinsider.com/api-reference/endpoint/get-stream) filter of the same name.

Before this release, the SDK's only grade filter on the stream was `min_grade`, which reads the wallet's grade when the trade was published, hours after the fill for a backfilled trade. A client that caught up on [`GET /api/v1/large-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades-history) with `min_grade_at_trade` could not stream on the same basis through the SDK.

* `min_grade_at_trade` keeps a `LargeTradeInsertedV2` frame only when its `grade_at_trade` is at or above the value and its `grade_at_trade_status` is `graded`. With it set, every other frame type is excluded.
* Sending it beside `min_grade` is refused with `400` `bad_request` and `param` `min_grade_at_trade`. The resilient consumers do not retry it.
* The same release types `min_grade_at_trade` on `listLargeTrades`, `listLargeTradeHistory`, `getEventReplaySince` and webhook `trade_filters`, and `grade_at_trade` and `grade_at_trade_status` on `LargeTradeInsertedV2Data`.
* It also types `scores_freshness` and `scores_age_seconds` on games.

**Backward compatible.** The filters and fields are new, and no existing one changed.

**What to change:** Upgrade to 0.39.0. To catch up on large trades and then stream on one basis, send `min_grade_at_trade` instead of `min_grade` on both.

**November 4, 2026**

Games scores\_freshness reads stale for esports, college basketball and NHL games

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) now judge `freshness.scores_freshness` for esports, college basketball and NHL games, and read `not_applicable` in a break between periods. The `list_games` and `get_game` MCP tools carry the same values.

Before this change, only a running soccer half could read `fresh` or `stale`. Every other live game read `unknown`, including an NHL game in an intermission.

Each bound is about twice the longest gap between frames that we measured on November 4, 2026:

* Esports (`league` `cs2` or `lol`): `stale` after 120 seconds with no frame while the series is in progress. The provider resends each running series about every 20 seconds, also while the map score does not move.
* Men's and women's college basketball (`cbb`, `cwbb`) and NHL hockey (`nhl`): `stale` after 600 seconds with no frame while a period's clock is running. These feeds send no frame while the clock is stopped for a timeout or review.
* Breaks: a period of `HT` or `End ...` (for example `End P2` or `End Q2`) reads `not_applicable`. In women's college basketball, `End OT` is the end of the third quarter and the provider sends no frame for the fourth, so it reads `unknown`.
* Still `unknown`: tennis, college football, the NBA, the NFL, other esports titles, and every other league with no measured bound.

`scores_age_seconds` is the time since the game's last frame. For esports that is the last resend, not the last change in the score.

**Backward compatible.** No field is added or removed. Some live games that read `unknown` now read `fresh`, `stale` or `not_applicable`.

**What to change:** Nothing, if you already show a live score as delayed when `scores_freshness` is `stale`.

**November 4, 2026**

@0xinsider/mcp 3.13.0 is published; local large-trade tools filter on the grade at the fill

`@0xinsider/mcp` 3.13.0 is on npm and in the MCP Registry. It brings the November 4 changes listed below to the local MCP server and the CLI.

* `get_large_trades`, `get_large_trades_history`, `get_event_replay_since` and the deprecated aliases `get_whale_trades` and `get_whale_trades_history` take `min_grade_at_trade`, the grade the trader held when the trade filled. Sending it with `min_grade` returns `bad_request`.
* `0xinsider api list` names `min_grade_at_trade` for `listLargeTrades`, `listLargeTradeHistory` and `getEventReplaySince`. The entry "Large trades, the stream and webhooks can filter on the grade a trade filled under" said it would name it for `getStream` too, but `api list` and `api call` leave out the stream, which you read from `GET /api/v1/stream` directly.
* The `get_pick_of_the_day` description says a `pick_id` call returns the pick once, in `picks[0]`, as the API already did.
* The bundled SDK types describe every sport leaderboard field.

The local server lists the same 69 tools as the remote server. The [CLI](https://docs.0xinsider.com/integrations/cli.md), [MCP](https://docs.0xinsider.com/integrations/mcp.md) and [introduction](https://docs.0xinsider.com/index.md) pages now install `@0xinsider/mcp@3.13.0`.

**Backward compatible.** Every change adds a parameter, a section or a description; no tool, default or field changed.

**What to change:** Run `npm install --global @0xinsider/mcp@3.13.0`, or change a client's `@0xinsider/mcp@3.12.0` argument to `@0xinsider/mcp@3.13.0`. `0xinsider --version` prints `3.13.0` once the update is in place.

**November 4, 2026**

Games add scores\_freshness and scores\_age\_seconds, so a frozen live score no longer reads fresh

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) now send `freshness.scores_freshness` on every game, plus `freshness.scores_age_seconds` when a Sports WebSocket frame dates the score. `scores_age_seconds` is the time since that game's last frame, which is how long its score, period and clock have gone unchanged. The `list_games` and `get_game` MCP tools and the TypeScript types carry both.

Before this change, `source_freshness` was the only freshness value. It dates the board as a whole, so it read `fresh` while one live game's clock and score were 14 minutes old.

`scores_freshness` is judged on the game clock:

* `stale`: a soccer half's clock is running and no new frame has arrived for more than 180 seconds. The provider sends a frame each match minute.
* `fresh`: a running soccer half's clock had a frame within that bound.
* `not_applicable`: the game is not in play (scheduled, final, postponed or cancelled), or it is at halftime.
* `unknown`: no frame dates the score, the game is in stoppage time, or the game's sport has no measured bound. Basketball and hockey clocks stop for timeouts and reviews, so those sports read `unknown`.

**Backward compatible.** Both fields are additive.

**What to change:** If you show a live score, show it as delayed when `scores_freshness` is `stale`. Treat `unknown` as unverified, never as current.

**November 4, 2026**

Scheduled games and live soccer games now carry sports\_market\_type and side on their markets

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) now send `sports_market_type` (the provider's own value, for example `moneyline`) and `side` on the markets of a game that has not started, and on soccer markets while the game is live.

Before this change, those markets left out both fields. A client that picked a game's moneyline by `sports_market_type` found no market on any scheduled game. Measured on November 4, 2026: 0 of 100 scheduled esports markets carried the field.

`side` is still left out when the provider does not identify the competitors (no provider ids, as on many ITF tennis matches). The live markets work the same way.

**Backward compatible.** Both fields were already documented and are now sent where they were missing.

**What to change:** Nothing. If you fall back to the only listed market when `sports_market_type` is missing, you can now select by `sports_market_type === "moneyline"` instead.

**November 4, 2026**

Large-trade history and the event replay can filter on the grade a trade filled under

[`GET /api/v1/large-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades-history) and [`GET /api/v1/events/feed/since`](https://docs.0xinsider.com/api-reference/endpoint/get-event-replay-since) accept `min_grade_at_trade`. It keeps a trade only when the grade its trader held when the trade filled is at or above the value, the rule `GET /api/v1/large-trades`, `GET /api/v1/stream` and webhook `trade_filters` already apply.

Before this change, both routes offered only `min_grade`, which reads the wallet's grade when the page is read. A client that caught up through one of them and then streamed with `min_grade_at_trade` could get a different set of trades.

* Only a trade whose grade at the fill is `graded` matches. A trade before September 19, 2026, 23:00 UTC is `unknown` and never matches.
* On the history route it works with both sorts and beside `condition_id`, `event_slug`, `trader`, `from` and `to`.
* On the event replay it is bound to the cursor like the other filters: a cursor minted under `min_grade` and presented with `min_grade_at_trade`, or the reverse, returns `400` with `error.reason` `cursor_expired`. `meta.replay.filters` echoes it.
* Sending `min_grade` and `min_grade_at_trade` together returns `400` with `param` `min_grade_at_trade`.
* The remote MCP tools `get_large_trades_history`, its deprecated alias `get_whale_trades_history`, and `get_event_replay_since` take `min_grade_at_trade` now. The next `@0xinsider/mcp` release adds it to the local MCP tools, and `0xinsider api list` will name it for `listLargeTradeHistory` and `getEventReplaySince`.
* The next SDK release adds `min_grade_at_trade` to `StreamFilters`, sent as the `min_grade_at_trade` query parameter of `GET /api/v1/stream`.
* `min_grade` keeps its meaning on every surface.

**Backward compatible.** The parameter is new, and every cursor minted before it continues unchanged.

**What to change:** Nothing. To catch up and stream on one basis, send `min_grade_at_trade` instead of `min_grade` on the history or replay read and on the stream.

**November 4, 2026**

@0xinsider/mcp 3.12.0 is published; Pick of the Day tools default to the summary view

`@0xinsider/mcp` 3.12.0 is on npm and in the MCP Registry. It brings the November 3 changes listed below to the local MCP server and the CLI. Before this release, the local server ran 3.11.0, whose Pick of the Day tools sent no view and returned the whole record: 198,807 bytes for one day's 14 picks.

* `get_pick_of_the_day`, `get_pick_of_the_day_archive` and `get_pick_of_the_day_stats` send `view=summary` unless you name a view. They take `pick_id`, the archive's `limit` and `cursor`, and the stats `sections`.
* `get_leaderboard` describes the board `summary` (`ranked_total`, `by_grade`, `active_30d`, `as_of`), sent on a page with no category or strategy.
* `get_edge_hunter` reads `category: "sports"`, in any casing, as `kind: "sports"` in every view. `explore_markets` and `get_leaderboard` take `sports` for every sport but Esports, and the market and trade tools that reject the word say to omit `category` instead.
* `get_trader` takes `expand: ["breakdowns"]` and describes `price_edge`, the edge over the price paid that the profile badge shows.
* Each `get_game_holders` item's data carries `stale`.
* The package's MCP Registry description reads "Polymarket sports and esports data: wallet grades on settled P\&L, large trades, markets."

The local server lists the same 69 tools as the remote server. The [CLI](https://docs.0xinsider.com/integrations/cli.md), [MCP](https://docs.0xinsider.com/integrations/mcp.md) and [introduction](https://docs.0xinsider.com/index.md) pages now install `@0xinsider/mcp@3.12.0`. The November 4 `pick_id` change to Pick of the Day needs no package update: the local `get_pick_of_the_day` passes the API body through, so a `pick_id` call returns the pick once, in `picks[0]`.

**Breaking** for local MCP clients that read Pick of the Day fields the summary leaves out, such as `display_holders` or `entry_authorization`. The other changes add parameters, fields and descriptions.

**What to change:** Run `npm install --global @0xinsider/mcp@3.12.0`, or change a client's `@0xinsider/mcp@3.11.0` argument to `@0xinsider/mcp@3.12.0`. For the full Pick of the Day body, send `view: "full"`, or call `get_pick_of_the_day` with `pick_id` for one pick in full. `0xinsider --version` prints `3.12.0` once the update is in place.

**November 4, 2026**

Sandbox leaderboard lists S, A and B only, with a ranked edge for each grade

In the [sandbox](https://docs.0xinsider.com/sandbox.md), [`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard) now returns 5 rows graded `S`, `A` and `B`, the grades the live leaderboard lists. Each of the 3 grades has a `price_edge` with `status: "ranked"` and no `hold`, the edges `sort=edge` ranks.

Before this change, the sandbox leaderboard returned 7 rows graded `S` to `D`. Every `price_edge` had `status: "ranked"`, `hold: "record_incomplete"` and `edge: 1`, so a client that keeps only ranked edges with no hold found none.

* One `A` edge keeps `hold: "record_incomplete"`, and one `B` edge has `status: "sample_mismatch"`.
* `price_edge.edge` is `hit_rate` minus `avg_price`, as the field is defined. `hold` is omitted when nothing holds the edge, as in the live API.
* In [`POST /api/v1/traders/batch`](https://docs.0xinsider.com/api-reference/endpoint/batch-get-traders), a sandbox wallet's `price_edge` has the same figures, with `shrunk_edge` and `field_average` only when the edge ranks.
* The sandbox leaderboard's `total` is 5, so a `limit=3` walk ends on its second page.

**Backward compatible.** Response shapes are unchanged. Sandbox values now match what the live API can return.

**What to change:** Nothing. A sandbox client that expected 7 leaderboard rows, or a `C` or `D` row, now gets 5 rows graded `S`, `A` and `B`.

**November 4, 2026**

OpenAPI describes every sport leaderboard field: grade is all-time, P\&L is in-sport

The OpenAPI schemas for the [sport leaderboard](https://docs.0xinsider.com/api-reference/endpoint/get-sport-leaderboard.md) and [leaderboard leagues](https://docs.0xinsider.com/api-reference/endpoint/list-leaderboard-leagues.md) now describe every field, including each row field and each `price_edge` field.

Before this change, both schemas listed field types only. A reader could not tell from the schema that a row's `grade` is the wallet's all-time grade while its other figures are in the sport or league. On the esports board sorted by P\&L on November 4, the top wallet had \$3,692,604 in esports P\&L and an `F` grade.

* `grade`: the all-time grade, led by realized profit across all of the wallet's sports and esports markets, not this sport's.
* `pnl`, `cost`, `roi`, `wins`, `losses`, `win_rate`, `price_edge`, `edge_skill`: the wallet's record in this sport or league. `roi` and `win_rate` are fractions: `0.12` is 12%.
* `volume`: the wallet's volume across all sports and esports on a sport board, as `volume_scope` says, and `null` on every league board row.
* `total_traders`: wallets with at least `min_resolved` settled markets here and a trade in the last 180 days.

**Backward compatible.** Only descriptions change. Field names, types, required fields and responses are unchanged.

**What to change:** Nothing. Refresh cached OpenAPI documentation or generated clients to pick up the descriptions.

**November 4, 2026**

Large trades, the stream and webhooks can filter on the grade a trade filled under

[`GET /api/v1/large-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades), [`GET /api/v1/stream`](https://docs.0xinsider.com/api-reference/endpoint/get-stream) and webhook `trade_filters` on [`POST /api/v1/webhooks`](https://docs.0xinsider.com/api-reference/endpoint/create-webhook) accept `min_grade_at_trade`. It keeps a trade only when the grade its trader held when the trade filled is at or above the value, by the same rule on all three.

Before this change, each `min_grade` read a different grade: the list read the wallet's grade now, and the stream and webhooks read its grade when the trade was published. A client that caught up on the list and then streamed got two answers: over 16 hours on November 3 the list added 2 trades and dropped 3 against the stream. Publication can also come hours after the fill: in the 7 days to November 3, 14 of 3,892 trades were published under a different grade than they filled under.

* The `LargeTradeInsertedV2` stream frame and the `large_trade_inserted_v2` webhook `data` add `grade_at_trade` and `grade_at_trade_status`, the same facts as `trader.grade_at_trade` and `trader.grade_at_trade_status` on the list. `grade` is unchanged.
* Only a trade whose `grade_at_trade_status` is `graded` matches. A trade before September 19, 2026, 23:00 UTC is `unknown` and never matches, and neither does an event published before this change. Such an event, redelivered, carries neither field, so read both as optional.
* On the list, `min_grade_at_trade` works with `since`, `sort=market_volume_share`, `condition_id` and `event_slug`.
* On the stream, `min_grade_at_trade` passes only `LargeTradeInsertedV2` frames. `min_grade` also passes `wallet_grade_changed` frames.
* Sending `min_grade` and `min_grade_at_trade` together returns `400` with `param` `min_grade_at_trade` (`trade_filters.min_grade_at_trade` on webhooks).
* The remote MCP tool `get_large_trades` and its deprecated alias `get_whale_trades` take `min_grade_at_trade` now. The next `@0xinsider/mcp` release adds it to the local MCP tools, and `0xinsider api list` will name it for `listLargeTrades` and `getStream`.
* `min_grade` keeps its meaning on every surface.

**Backward compatible.** The parameter and the two payload fields are new.

**What to change:** Nothing. To get the same trades from the list, the stream and webhooks, send `min_grade_at_trade` instead of `min_grade` on each. A stream client that also reads `wallet_grade_changed` frames gets them only on a connection without `min_grade_at_trade`.

**November 4, 2026**

Games reports a cancelled or postponed upcoming game as cancelled or postponed

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) and [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) now report `status.state` `cancelled` or `postponed` when Polymarket marks an upcoming game that way. `window=now` leaves those games out, as it already did for every cancelled and postponed game.

Before this change, a game that Polymarket marked only on its event, with no live-score update, read `scheduled`. On November 3, 2026, Paine at Jacksonville (`cbb-pain-jax-2026-11-02`) was cancelled and still read `scheduled` 23 hours after its listed tip-off.

An upcoming game whose provider period this API does not recognize now reads `unknown`, not `scheduled`. No game read that way on November 3, 2026.

**Backward compatible.** Both values were already in the `status.state` enum, and no field is added or removed.

**What to change:** Nothing. If you list upcoming games and treat every game that is not `live` as still to be played, check for `cancelled` and `postponed` too.

**November 4, 2026**

Pick of the Day with pick\_id returns the pick once, in picks\[0]

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) with `pick_id` now returns that pick once, as `picks[0]`, beside `state`, `pick_date` and `pick_count`. The remote MCP tool `get_pick_of_the_day` with `pick_id` returns the same body.

Before this change, the `pick_id` body also copied the pick's fields to the top level, the way a whole-day read repeats its first pick. That doubled the body. On November 2, 2026, the largest pick was 42,388 characters, and 7 of the 14 picks were over 25,000. Without the copy the largest is about 21,150.

**Breaking** only for clients that read pick fields, such as `entry_authorization` or `display_holders`, from the top level of a `pick_id` body. `pick_id` was added on November 3, 2026. A request without `pick_id` returns the same body and ETag as before.

**What to change:** Read the pick from `picks[0]`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.