> ## 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: October 6 to 11, 2026

> 51 API, SDK, CLI, MCP, OAuth, and feed changes from October 6 to 11, 2026, newest first, each with its effect on clients. Newer ones are on the API changelog.

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

**October 11, 2026**

Max-only Edge Hunter replaces 4 retired sports signals and observations endpoints

[`GET /api/v1/edge-hunter`](https://docs.0xinsider.com/api-reference/endpoint/get-edge-hunter) now returns the ranked board shown on [Edge Hunter](https://0xinsider.com/sports/edge). It requires Max; a Pro credential returns `403 forbidden` with `error.reason: max_plan_required`.

Before this change, sports signals and observations were separate paginated APIs. These 4 paths now return `410 Gone` with `error.code` and `error.reason` set to `endpoint_retired`:

* `/api/v1/sports-edge-signals`
* `/api/v1/sports-edge-observations`
* `/api/v1/sports/pre-game-sides`
* `/api/v1/sports/pre-game-side-observations`

Edge Hunter uses `object: "edge_hunter"` and returns `data.rows`, with up to 30 full rows across all sports. `horizon_hours` defaults to 48 and is clamped to 1 through 48; the grade floor is fixed at `B`, and `data.total` counts matches before the row cap.

The response includes market and participant identities, backed-side analytics, and current quotes when available. It has no cursor, category filter, observation cohort, or observation funnel.

The client packages and official agent instructions use the new API:

* SDK `0.20.0` adds `getEdgeHunter` and `edgeHunter.get()`, and removes the old sports signals and observations helper methods.
* The MCP and CLI runtime `3.0.0` adds `get_edge_hunter`; the 4 old MCP tools are no longer advertised.
* The [official agent plugin's `polymarket-sharp-money` skill](https://github.com/0xinsider/agent-plugin/blob/main/skills/polymarket-sharp-money/SKILL.md), version `1.0.2`, now calls Edge Hunter and requires Max for board requests.

**Breaking** for clients that call any of the retired REST endpoints or MCP tools.

**What to change:** Use `/api/v1/edge-hunter` with a Max credential, or `get_edge_hunter` over MCP. Read `data.rows` and the new board fields, remove unsupported filters and cursors, and update to SDK `0.20.0` or MCP `3.0.0`.

Refresh installed official skills with `npx skills@latest update 0xinsider-api-access polymarket-sharp-money`. Stop retrying `410 endpoint_retired`.

**October 11, 2026**

Market snapshot starts a live book on the first read of a market off the sports boards

[`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) always streams the order book for two groups of markets. The first is every market on the 0xinsider sports boards. The second is every sports market with \$10,000 or more of liquidity, from 15 minutes before kickoff until it resolves. A market in either group whose book has no bid or no ask, such as a finished game waiting to resolve, still reports `cache_miss`.

Any other open market, such as a non-sports market, a futures market, or a sports market long before kickoff, now gets its book when you read it. Before this change the cache also held every other open market with \$10,000 or more of liquidity. The first snapshot of such a market starts a live subscription and reports no book:

* `outcomes[].top_of_book.status` is `unavailable`, with `reason: "cache_miss"`.
* `outcomes[].current_price` is `null`, because it is the midpoint of that book.
* `freshness.top_of_book` and the `trust` expansion report the book unavailable.

A snapshot a few seconds later has the live book. The market keeps its live book while you read it at least once every 5 minutes. When many markets are held at the same time, a read can fail to start a subscription, and the snapshot keeps reporting `cache_miss`.

**Backward compatible.** Each of these values was already possible.

**What to change:** Nothing, if you already handle a missing book. If you get `cache_miss` for an open market, read the snapshot again after a few seconds.

**October 11, 2026**

Tennis headshot images are served at most 128 px wide

The tennis `headshot` URL that [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) returns on a competitor now serves an image at most 128 px wide. The image keeps its aspect ratio and is never enlarged. Before this change the URL served the stored portrait, up to 1024 px wide.

* The URL and its `v` query parameter are unchanged.
* The response is `image/png`. A portrait that was stored as JPEG used to be served as `image/jpeg` and is now PNG too. An image already 128 px or smaller is served as stored, with its stored type.
* The `ETag` is now the image hash followed by `-w128`, for example `"<sha256>-w128"`. A cached copy that holds the old tag (the bare hash) gets a `200` with the new image, not a `304`.

**Backward compatible** for clients that show the headshot at 128 px or smaller.

**What to change:** Nothing, unless you show the headshot larger than 128 px. In that case the image is scaled up by your client.

**October 10, 2026**

Report large trades name Yes and No outcomes instead of null

[`GET /api/v1/reports/daily`](https://docs.0xinsider.com/api-reference/endpoint/get-daily-report-snapshot), [`/weekly`](https://docs.0xinsider.com/api-reference/endpoint/get-weekly-report-snapshot) and [`/monthly`](https://docs.0xinsider.com/api-reference/endpoint/get-monthly-report-snapshot) now send `"Yes"` or `"No"` in `outcome` on `report.top_large_trades[]` and `report.top_whale_trades[]` when the traded market is a Yes/No market. Other markets keep their own labels, such as a team name.

Before this change `outcome` was `null` for many Yes/No markets created since August 2026, because 0xinsider stored their labels as empty. Report snapshots built before this change keep the value they were built with.

**Backward compatible.** `outcome` was already nullable, and it can still be `null` when no label is known.

**What to change:** Nothing. If you replaced a `null` `outcome` with your own "Yes"/"No", you can stop.

**October 10, 2026**

Trader context returns a retryable 503 instead of a 500 when its breakdown read times out

[`GET /api/v1/trader/{address}/context`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-context) and [`GET /api/v1/trader/{address}/context.md`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-context-markdown) now return `503` with `error.reason: "read_model_warming"` and `Retry-After: 2` when the `position_summary` read runs out of time. That read covers every position the wallet has held, so a wallet with a long history can exceed its time limit when its data is not in the database cache. The API tries the read a second time before it answers, and the second try usually completes because the first one already loaded part of the data.

Before this change, the same case returned `500` with `error.code: "internal_error"`. On October 10, a client that retried two seconds after that `500` got a `200` both times it happened.

* `error.code` is `rate_limit_unavailable`, the code every `503` on this API carries. Branch on `error.reason`.
* The context is never returned without its `position_summary` for this reason, and a partial breakdown is never returned.
* Any other database failure still returns `500`.

**Backward compatible** for clients that already retry a `5xx` response.

**What to change:** Retry a `503` with `error.reason: "read_model_warming"` after the `Retry-After` seconds. Do not count it toward a rate-limit backoff.

**October 10, 2026**

Position timeline's trader\_not\_tracked message names the warm tier only

[`GET /api/v1/trader/{address}/position-timeline`](https://docs.0xinsider.com/api-reference/endpoint/get-position-timeline) and [`GET /api/v1/traders/{trader}/position-timeline`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-position-timeline) now end the `trader_not_tracked` message with `only warm-tier traders are tracked`. The warm tier is the set of wallets 0xinsider syncs most often.

Before this change the message ended with `only HOT and WARM traders are tracked`. 0xinsider has moved every former hot-tier wallet to the warm tier and removed the hot tier, so the set of wallets with a timeline did not change.

* `error.code` stays `not_found` and `error.reason` stays `trader_not_tracked`.
* The message still names the trader's own tier, for example `(sync_tier=cold)`.
* The OpenAPI descriptions, the SDK's `TraderNotTrackedError` documentation, and the `get_position_timeline` MCP tool description say the same.

**Backward compatible.**

**What to change:** Nothing, unless you match on the message text. Branch on `error.reason` instead.

**October 10, 2026**

Large trades name the real clock behind the volume data\_quality group

[`GET /api/v1/large-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades) and [`GET /api/v1/large-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades-history) now send `owner: "market_live_stats.volume_request_observed_at"` on the `volume` entry of `data_quality.field_groups`. The deprecated `/api/v1/whale-trades` aliases send the same value.

Before this change the entry named `markets.volume_request_observed_at`. That column is a retired copy. The `as_of` and `status` on the entry always came from `market_live_stats`, the table that holds each market's volume and the time it was read, so only the name changes.

**Backward compatible** for clients that read `as_of` and `status`. The `ETag` of a large-trades page changes once, because `data_quality` is part of it.

**What to change:** Nothing, unless you match the `owner` string. If you do, match `market_live_stats.volume_request_observed_at`.

**October 10, 2026**

Pre-game sides and observations now need Max; Pro keys get 403 max\_plan\_required

[`GET /api/v1/sports/pre-game-sides`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-sides) and [`GET /api/v1/sports/pre-game-side-observations`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-side-observations) now need a credential on the Max plan. A Pro key gets `403` with `code: forbidden`, `reason: max_plan_required`, and a message that links the [pricing page](https://0xinsider.com/pricing).

Before this change, any Pro key could read both routes. They carry the same data as [Edge Hunter](https://0xinsider.com/sports/edge), which the site has shown only to Max since October 8, 2026.

* The deprecated aliases `GET /api/v1/sports-edge-signals` and `GET /api/v1/sports-edge-observations` answer the same way.
* The MCP tools `get_pre_game_sides`, `get_pre_game_side_observations`, `get_sports_edge_signals`, and `get_sports_edge_observations` return the same error to a Pro key.
* `max_plan_required` is a new value of `error.reason`. `error.code` stays `forbidden`.
* The next `@0xinsider/sdk` release adds `MaxPlanRequiredError`, a `ForbiddenError` subclass with an `upgradeUrl`. Earlier versions throw `ForbiddenError` with `reason` set to `max_plan_required`.
* Every other Pro endpoint keeps working with the same key.

**Breaking** for Pro clients that read pre-game sides or their observations.

**What to change:** Upgrade to Max to keep reading these routes. Otherwise stop calling them, and treat `reason: max_plan_required` as a permanent refusal for that route, not as a deleted account.

**October 10, 2026**

Trader context.md prints one market win rate instead of two

[`GET /api/v1/trader/{address}/context.md`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-context-markdown) now prints one `Market win rate` line, in the Performance section. When the position breakdown is present it is `position_summary.resolved_win_rate`, followed by its won and decided counts, for example `- Market win rate: 3.4% (39 won of 1155 decided resolved markets)`. Otherwise it is `trader.stats.win_rate`.

Before this change the document printed two lines for the same rule: `Market win rate` from `trader.stats.win_rate`, and `Resolved-market win rate` in the position breakdown. The stored figure could lag settled markets recorded after the wallet's last full sync, so the two disagreed. On October 7, 34 of 400 ranked wallets differed by more than 0.5 points.

* The `Resolved-market win rate` line is removed from the position breakdown.
* `freshness_note` on [`GET /api/v1/trader/{address}/context`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-context), and the same sentence in the Markdown document, now say that resolved counts and win rate can include settled markets recorded after the last full sync.
* The JSON body is otherwise unchanged. `trader.stats.win_rate` and `position_summary.resolved_win_rate` are both still sent.

**Backward compatible** for clients that read the JSON. **Breaking** for clients that parse the `Resolved-market win rate` line out of the Markdown document.

**What to change:** Read the win rate from the `Market win rate` line, or from `position_summary.resolved_win_rate` in the JSON route.

**October 10, 2026**

Leaderboard realized\_pnl is left out, never another P\&L basis, without a native figure

[`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard) `realized_pnl` is now always the wallet's own realized P\&L, including credited maker and taker rebates. A wallet without that figure omits the field.

Before this change, the documentation said such a wallet would carry an older stored realized P\&L with a different basis. On October 10 every ranked wallet had the figure, so no response changed.

* `realized_pnl` keeps its name, type and cent truncation.
* The field was already optional. Treat its absence as "not available", not as zero.

**Backward compatible.**

**What to change:** Nothing, if your client already handles a missing `realized_pnl`.

**October 10, 2026**

@0xinsider/mcp 2.14.5 states the current tagline and bundles the combo SDK methods

`@0xinsider/mcp` 2.14.5 describes itself on npm and in its README as "Polymarket analytics & infrastructure for sports and esports markets". The SDK copy bundled in the package (`dist/sdk/`) now includes `client.combos.fills`, `client.combos.summary`, and `client.combos.get` for the [combo routes](https://docs.0xinsider.com/api-reference/endpoint/list-combo-fills.md) added on October 8, 2026. Its types follow the response changes listed in the entries since 2.14.4.

Before this change, the npm description and README read "advanced tools for sports and esports markets, powered by Polymarket", and the bundled SDK had no combo methods.

* The 48 MCP tools, the CLI commands, and their output are unchanged. Neither calls the new methods.
* The MCP Registry entry stays at 2.14.4, which serves the same tools.

**Backward compatible.**

**What to change:** Nothing. Upgrading from 2.14.4 is optional.

**October 10, 2026**

Trader pnl.total and leaderboard pnl come from Polymarket's latest leaderboard observation

[`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) `pnl.total` and [`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard) `pnl` now carry Polymarket's all-time leaderboard P\&L from its latest observation of the wallet. When that leaderboard has no current observation ranking the wallet, the field is left out.

Before this change, both fields read a stored copy that only some wallets kept current. For about 63,000 wallets it still held a figure from before Polymarket's current leaderboard data, and both fields served it as current; 853 of the 10,363 leaderboard entries were affected.

* `pnl.total` and `pnl` change value for those wallets, or are left out until Polymarket reports them.
* The trader response's `data_quality` adds a `leaderboard_pnl` group, dated by when Polymarket last reported the wallet. The `sync` group no longer covers `pnl.total`.
* A trader read without a current observation asks Polymarket for one, so the field returns on a later read.

**Backward compatible** for field names and types; both fields were already optional. **Breaking** for clients that assumed `pnl.total` is present whenever `pnl.net_total` is, or that require `data_quality.status` to be `fresh`: a wallet without a current observation now reports `partial`.

**What to change:** Treat `pnl.total` and the leaderboard `pnl` as optional. Use `pnl.net_total` for a wallet's total, and match `data_quality` groups by name, ignoring unknown ones.

**October 10, 2026**

Pick of the Day expands its public market coverage

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) can now include selections from more markets.

Before this change, some of those markets were never considered for a pick. Every publication check still applies, and 15 is the daily maximum, not a promised count. The private scanner feed is unchanged.

**Backward compatible.** Request and response fields are unchanged. Already selected and historical picks keep the rules they were selected under.

**What to change:** Nothing.

**October 9, 2026**

Pick of the Day expands public and private market coverage

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) and the private scanner feed can now include selections from more markets.

Before this change, fewer markets were covered. The response still does not promise a pick count, and 15 is the daily maximum at this release.

**Backward compatible.** Request and response fields are unchanged. Already selected and historical picks keep the rules they were selected under.

**What to change:** Nothing.

**October 9, 2026**

Market snapshot volume\_24h\_usd now carries Polymarket's 24-hour volume, with its read time

[`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) now fills `liquidity.volume_24h_usd` with Polymarket's 24-hour volume for open markets, and adds `liquidity.volume_24h_as_of`, the time 0xinsider read that figure.

Before this change, `liquidity.volume_24h_usd` was `null` for every market, and the field description said so.

* `liquidity.volume_24h_usd` counts the shares takers bought in the 24 hours before `volume_24h_as_of`, each at its \$1 settlement value. It is a share count, not cash, like `liquidity.volume_usd`.
* It stays `null` when Polymarket does not report one, which it does not for closed markets.
* `liquidity.volume_24h_as_of` is an ISO 8601 time, `null` exactly when `volume_24h_usd` is.

**Backward compatible.** `liquidity.volume_24h_as_of` is a new field. `liquidity.volume_24h_usd` keeps its name and type and now carries a number where it was always `null`.

**What to change:** Nothing required. Read `volume_24h_usd` for a market's recent activity, and use `volume_24h_as_of` to judge how current it is.

**October 9, 2026**

Positions drop every position on a market that has resolved

[`GET /api/v1/positions`](https://docs.0xinsider.com/api-reference/endpoint/get-positions) now returns positions on open markets only. A position leaves the feed when Polymarket resolves its market, on every read: the default feed, `category`, `min_grade`, `condition_id`, and `wallet`.

Before this change, the feed also listed positions on resolved markets, often at their last price before resolution. Many of them had already been redeemed or sold. On October 9, 2026, 706 of the 2,000 largest rows were on resolved markets.

* A `condition_id` read of a resolved market now returns an empty list.
* A `wallet` read now returns the wallet's positions on open markets only, so a wallet whose markets have all resolved returns an empty list.
* A void market, settled at 50/50, counts as resolved.

**Backward compatible.** No field, parameter, or type changes. Fewer rows come back.

**What to change:** Nothing, unless you read resolved positions from this route. For a wallet's settled results, use its trader export.

**October 9, 2026**

Position timeline returns fills from July 17, 2026 on; older wrong-side fills are deleted

[`GET /api/v1/trader/{address}/position-timeline`](https://docs.0xinsider.com/api-reference/endpoint/get-position-timeline) and [`GET /api/v1/traders/{trader}/position-timeline`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-position-timeline) now return fills from July 17, 2026 on. Every returned fill is the wallet's own trade.

Before this change, the timelines also returned fills from December 12, 2022 to April 28, 2026. A retired ingester recorded those fills with the other party's side, so each showed the opposite `action`, or the other `outcome_side` at 1 minus the `price`. They were deleted on October 9, 2026, and the warning about them is gone from the `action` description.

**Breaking** for clients that read timeline fills before July 17, 2026: those fills are no longer returned, and `running_amount` and `running_avg_price` no longer include them. No field changes.

**What to change:** Drop cached timeline fills dated before July 17, 2026, and recompute any total built from them.

**October 9, 2026**

copy\_score's loss penalty compares the largest loss with capital deployed

`quant_metrics.copy_score` on [`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) and [`POST /api/v1/traders/batch`](https://docs.0xinsider.com/api-reference/endpoint/batch-get-traders) now subtracts its 10-point loss penalty only when the wallet's largest loss on one settled market is more than 30% of the capital it deployed across all its positions.

Before this change, the penalty compared that loss with the wallet's lifetime profit or loss. A wallet whose lifetime result was near zero or negative crossed the 30% line almost every time: on October 9, 2026, 126,113 of 200,447 wallets carried the penalty, against 13,475 under the new rule. 112,823 wallets gain up to 10 points, and 185 lose up to 10.

The `copy_score` description in the OpenAPI document and the SDK types states the new rule. When the recorded loss on one market is larger than all the capital the wallet deployed, the inputs disagree and no loss penalty applies.

**Backward compatible.** No field, type, or range changes. Each wallet's score moves to the new rule the next time its metrics are computed, within 6 hours of the release.

**What to change:** Nothing. If you stored `copy_score` values, do not compare scores from before this change with later ones.

**October 9, 2026**

Market snapshot and explore volume fields now state their unit and that one is always null

The OpenAPI document and SDK types now describe `liquidity.volume_usd` and `liquidity.volume_24h_usd` on [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot), and `volume` and `rep_volume` on [`GET /api/v1/markets/explore`](https://docs.0xinsider.com/api-reference/endpoint/explore-markets). The values do not change.

Before this change, those four fields had no description, and `volume_usd` and `volume_24h_usd` read as dollar amounts.

* `liquidity.volume_usd`, `volume`, and `rep_volume` are Polymarket's volume figure for the market, as last stored: the total shares bought by takers, each counted at its $1 settlement value. They are share counts, not cash; 100 shares bought at $0.40 add 100, not 40. A stored figure can lag Polymarket's current one.
* `rep_volume` is the `volume` of the group's highest-volume market, `markets[0]`.
* `liquidity.volume_24h_usd` is always `null`. 0xinsider does not store a 24-hour volume.

**Backward compatible.** No field name, type, or value changes.

**What to change:** If you showed `volume_usd`, `volume`, or `rep_volume` as dollars traded, label them as Polymarket's volume figure in shares. Stop reading `volume_24h_usd`; it never carries a value.

**October 9, 2026**

Pre-game volume, timeline action, and positions win\_rate docs match the served values

The OpenAPI document and SDK types now describe `volume` on [`GET /api/v1/sports/pre-game-sides`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-sides), `action` on [`GET /api/v1/trader/{address}/position-timeline`](https://docs.0xinsider.com/api-reference/endpoint/get-position-timeline), and `trader.win_rate` on [`GET /api/v1/positions`](https://docs.0xinsider.com/api-reference/endpoint/get-positions) as the values the API already returns.

Before this change, those three descriptions did not match the served values:

* `volume` on pre-game sides and on [`GET /api/v1/sports/pre-game-side-observations`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-side-observations) was described as USD. It is Polymarket's traded-volume figure: cumulative taker volume in shares, each counted at its $1 settlement value. It is not the cash that changed hands; 100 shares bought at $0.40 add 100, not 40.
* `action` on the position timeline was described as the taker's side. It is the wallet's own side of the fill. Fills dated before April 29, 2026 come from a retired ingester that recorded the other party's side, so treat them as unreliable until they are removed.
* `trader.win_rate` on positions was described as a percentage from 0 to 100. It is a ratio from 0 to 1, the same scale as the trader profile.

**Backward compatible.** No value, field, or type changes.

**What to change:** If you showed `volume` as dollars traded, label it as Polymarket's volume figure in shares. If you showed `trader.win_rate` as a percentage, multiply it by 100 first. If you rely on timeline fills dated before April 29, 2026, do not trust their side.

**October 9, 2026**

The games catalog adds K League 1 coverage

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) now includes K League 1 games in `coverage.leagues` as `kor`, under `sport=Soccer`. Use `sport=Soccer&league=kor` to list them, then [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) for one game's linked markets.

Before this change, K League 1 had no dedicated scope in the games catalog.

Coverage follows Polymarket's published games. K League 2 is a separate league and is not included in this scope. Live status and scores follow the provider; a passed kickoff does not make a game live.

**Backward compatible.** The league coverage is additive. Existing request parameters and response fields are unchanged.

**What to change:** Nothing. Use `league=kor` when you want only K League 1 games.

**October 9, 2026**

Games and pre-game observations add EuroLeague coverage

[`GET /api/v1/games`](https://docs.0xinsider.com/api-reference/endpoint/list-games) now includes EuroLeague games in `coverage.leagues` as `euroleague`, under `sport=Basketball`. Use `sport=Basketball&league=euroleague` to list them, then [`GET /api/v1/games/{event_slug}`](https://docs.0xinsider.com/api-reference/endpoint/get-game) for one game's linked markets.

Before this change, EuroLeague had no dedicated scope in the games catalog or the upcoming basketball supply for pre-game observations.

* [`GET /api/v1/sports/pre-game-side-observations`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-side-observations) includes upcoming EuroLeague games in its basketball supply.
* `funnel.sports[].board_upcoming_unavailable_scopes` can contain `euroleague-basketball` when that upcoming source is unavailable. The OpenAPI enum and generated SDK types include the value.
* EuroLeague live status and scores still follow the provider. The upcoming scope does not infer that a game is live from its kickoff time.

**Backward compatible.** Coverage and the unavailable-scope value are additive.

**What to change:** Nothing unless you validate the unavailable-scope values against a fixed list; add `euroleague-basketball`. Use `league=euroleague` when you want only EuroLeague games.

**October 9, 2026**

OpenAPI nullable enums accept the null values the API already returns

[`GET /api/v1/large-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades) and other responses with nullable enum fields now have OpenAPI 3.1 declarations that accept the `null` values those responses already return.

Before this change, the schemas used `nullable: true` while their type or enum still excluded `null`. Standard response validators could reject valid API responses.

* Large-trade `suspicion_track` and `trader.grade_at_trade` allow `null`.
* Already-nullable `platform` fields in market search, exploration, flow, and reports allow `null`.
* Already-nullable grade, pre-game side, webhook reason and outcome, and account recovery fields allow `null`.
* The unavailable pick response keeps `supersedes_pick_id` restricted to `null`.

**Backward compatible.** API payloads, request parameters, and non-null enum values stay the same. Current SDK types already include these null values.

**What to change:** Refresh your OpenAPI document or regenerate response validators if you validate API responses. Existing API calls and SDK types need no changes.

**October 8, 2026**

Combo fills and details avoid repeated lookups when a response is not cached

[`GET /api/v1/combos/fills`](https://docs.0xinsider.com/api-reference/endpoint/list-combo-fills) and [`GET /api/v1/combos/{condition_id}`](https://docs.0xinsider.com/api-reference/endpoint/get-combo) now avoid repeated lookups when building a response that is not cached.

Before this change, fill selection repeated some checks for the same combo, and detail requests read the same legs more than once.

Responses keep the same fields, exact amounts, result rules, filters, pagination, access requirements, and cache freshness. Database or cache service pauses can still delay a response; this update does not establish that every request completes within 250 milliseconds.

**Backward compatible.** No response field or request parameter changes.

**What to change:** Nothing.

**October 8, 2026**

The REST API adds combo fills, a live-combo count, and individual combo details

[`GET /api/v1/combos/fills`](https://docs.0xinsider.com/api-reference/endpoint/list-combo-fills), [`GET /api/v1/combos/summary`](https://docs.0xinsider.com/api-reference/endpoint/get-combos-summary), and [`GET /api/v1/combos/{condition_id}`](https://docs.0xinsider.com/api-reference/endpoint/get-combo) now return recorded Polymarket combo activity with paid API access.

Before this change, the external REST API had no routes for combos.

* The fill list returns wallets, legs, execution amounts, and combo results. It accepts result, leg count, stake, multiplier, grade, and sport filters, with newest-first or ranked pagination.
* Shares, collateral, fees, and execution prices retain exact decimal strings. The list excludes fills priced above `0.95` and returns full rows without the website's free delay.
* The summary returns only the stored live-combo count and its `computed_at`. An unavailable count is `null`, not `0`.
* One combo's detail returns its legs, totals, latest 100 taker fills, lifecycle amounts when recorded, and data coverage. Combo results describe the YES conjunction, not a wallet's realized P\&L.

**Backward compatible.** These routes are additive, and existing responses are unchanged.

**What to change:** Nothing. Use the new routes when you need combo data.

**October 8, 2026**

potd-trader v0.4.1 sets up Kalshi execution with one interactive command

[`potd-trader` v0.4.1](https://docs.0xinsider.com/guides/auto-buy-the-pick-on-kalshi) adds a one-command installer and `kalshi setup` wizard that asks for credentials, a private key file, spending limits, and reviewed contract mappings in your terminal.

Before this change, Kalshi setup required a release checkout, manual configuration edits, and separate commands for account checks, mapping, and dry runs.

* The installer keeps Python and the trader isolated from your global installation.
* New setups default to demo with orders stopped. Existing stopped setups retain their account, mappings, and ledger.
* The wizard checks the account and picks, guides the existing contract review, and runs a dry run. Enabling orders still requires your environment's explicit confirmation.

**Backward compatible.** Existing commands, mappings, spending limits, and execution guards remain available.

**What to change:** Run the [setup command](https://docs.0xinsider.com/guides/auto-buy-the-pick-on-kalshi.md) instead of editing configuration by hand. Stop existing watchers before upgrading.

**October 8, 2026**

potd-trader v0.4.0 adds demo-first Kalshi execution with reviewed contract mappings

[`potd-trader` v0.4.0](https://docs.0xinsider.com/guides/auto-buy-the-pick-on-kalshi) adds a `kalshi` command group for separate demo and production setups, manually reviewed contract mappings, dry runs, order controls, and reconciliation.

Before this change, the standalone trader submitted orders only on Polymarket. The Pick of the Day signal and API remain Polymarket-backed.

* `kalshi init` creates a separate configuration with demo mode and orders disabled.
* `kalshi map` requires review of both contracts and your own Kalshi price ceiling. Source authorization and slippage limits remain additional price guards; Polymarket modeled returns are not transferred.
* Kalshi orders use whole contracts and immediate-or-cancel submission. Daily reservations include worst-case fees; uncertain submissions stay blocked until reconciled.
* Changed contract PDFs or reported target positions or resting orders prevent new submissions. Use a dedicated account with no concurrent manual or other-tool trading; provider account reads can lag.

**Backward compatible.** The existing Polymarket commands remain available.

**What to change:** Install v0.4.0 and follow the [Kalshi guide](https://docs.0xinsider.com/guides/auto-buy-the-pick-on-kalshi.md) to create a separate setup. Existing Polymarket users need no configuration changes.

**October 8, 2026**

Pre-game sides includes holdings across linked events for the same game

[`GET /api/v1/sports/pre-game-sides`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-sides) and its deprecated alias [`GET /api/v1/sports-edge-signals`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-signals) now include positions across a game's provider-owned parent and companion events when calculating `directional_confidence`, `one_way_holder_count`, `hedged_holder_count`, and `one_way_graded_usd`.

Before this change, separate event slugs could omit opposing or unresolved holdings in the same game and overstate how one-way a wallet's positions were.

**Backward compatible.** Field names, types, and meanings are unchanged.

**What to change:** Nothing.

**October 8, 2026**

Pre-game sides recognizes team direction from named spread outcomes

[`GET /api/v1/sports/pre-game-sides`](https://docs.0xinsider.com/api-reference/endpoint/get-pre-game-sides) and its deprecated alias [`GET /api/v1/sports-edge-signals`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-signals) now identify the team a spread position backs when both outcome labels name distinct teams. `directional_confidence`, `one_way_holder_count`, and `hedged_holder_count` reflect those positions across the game's markets.

Before this change, named spread outcomes were ignored. A position could leave `directional_confidence` as `null`, or make a wallet holding the same team's moneyline and spread appear to back different teams.

Generic `Yes`/`No` answers and unresolved outcomes remain unclassified. Position freshness checks and the safeguards for wallets holding both outcomes still apply.

**Backward compatible.** Field names, types, and meanings are unchanged.

**What to change:** Nothing.

**October 8, 2026**

Pick of the Day removes editorial\_note from the API, SDK, and MCP responses

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day), the TypeScript SDK's `PickOfTheDay` type, and the MCP `get_pick_of_the_day` tool no longer expose `editorial_note`.

Before this change, a pick could include an editorial note. The field and its website display have been removed.

**Breaking** for clients that read `editorial_note`.

**What to change:** Remove `editorial_note` from your response models and displays. Do not require the field in stored responses or future reads.

**October 7, 2026**

Trader export markets describe a settled position by what it bought

The `markets` rows in a JSON or NDJSON file from [`POST /api/v1/trader/{address}/export`](https://docs.0xinsider.com/api-reference/endpoint/submit-trader-export) now describe a settled position by the shares it bought, not by the shares left after the market settled. A new field, `settled_side`, names the outcome a settled position took: `yes`, `no`, or `both` when it bought both outcomes. It is `null` on an open row.

Shares left after settlement cannot tell you a side. A wallet redeems its winning shares and keeps its losing ones, so a settled row usually shows 0 and 0, or only the losing outcome.

* `avg_price` on a settled position that bought both outcomes is now `null`. Before this change it was the Yes entry price, or the entry price of the outcome with shares left, which is usually the one that lost.
* `up_bought` and `dn_bought` on a settled row are now the shares each outcome bought: that outcome's cost divided by its average entry price. They are `null` when a position bought both outcomes and its cost per outcome is not recorded. Before this change they repeated `up_shares` and `dn_shares`, which are 0 and 0 on nearly every settled row.
* Open rows do not change.

**Backward compatible.** `settled_side` is a new field, and no field is removed or renamed. `avg_price`, `up_bought`, and `dn_bought` were already nullable.

**What to change:** Read `settled_side` to tell a position on both outcomes from a one-sided one. If you read `up_bought` and `dn_bought` on settled rows, expect real share counts where you saw zeros.

**October 7, 2026**

Positions trader.pnl and trending all\_time\_pnl\_usd carry the profile's total P\&L

`trader.pnl` on [`GET /api/v1/positions`](https://docs.0xinsider.com/api-reference/endpoint/get-positions) and `all_time_pnl_usd` on [`GET /api/v1/leaderboard/trending`](https://docs.0xinsider.com/api-reference/endpoint/list-trending-wallets) now carry the wallet's total P\&L as its 0xinsider profile shows it: Polymarket's position P\&L, fees included, plus maker and taker rebates. It is the same figure [`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) returns as `pnl.net_total`. The remote MCP tools `get_positions` and `get_trending_wallets` return the same values.

Before this change, both fields carried `pnl.total`, Polymarket's all-time leaderboard figure, which can differ from the profile's total by a wide margin and even in sign.

* Either field is omitted when Polymarket's figure for the wallet is not available. The leaderboard figure is never sent in its place.
* Neither field affects which rows a page holds or their order. `GET /api/v1/positions` still orders by `current_value_usd`, and the trending list still follows Polymarket's order.
* A trending list built before this change keeps its old `all_time_pnl_usd` until it is rebuilt. A request that finds the list at least 2 minutes old starts a rebuild.

**Backward compatible.** No field is added, removed or retyped. Both fields change value for most wallets.

**What to change:** Nothing, if you show these fields as the wallet's total P\&L. If you compared them with `pnl.total` from the trader endpoint, compare them with `pnl.net_total` instead.

**October 7, 2026**

category\_strengths counts markets a wallet bought on both sides

`category_strengths` on [`GET /api/v1/trader/{address}?expand=categories`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) and on `POST /api/v1/traders/batch` now counts every settled position of \$20 or more in each category, including a market the wallet bought on both sides. `n_markets`, `wins`, `losses`, `win_rate`, `total_pnl` and its alias `scaled_total_pnl` change for a wallet that holds such markets. `rank` and `total_in_category` move with them, and a wallet can enter a category it was below the 5-market floor in.

Before this change, a position counted only when it had one side with an entry price between 0 and 1, so a market bought on both sides was left out, and its profit or loss and its result with it. On a 0.2% sample of settled positions of \$20 or more on October 7, 33.8% were bought on both sides.

The edge over the price paid on the category leaderboards still scores only positions with one priced side: a market bought on both sides has no single side to score.

**Backward compatible.** The response shape is unchanged. Values move as each wallet's categories are recomputed over the following days.

**What to change:** Nothing. If you store `category_strengths` values, re-read them once the recompute has reached your wallets.

**October 7, 2026**

Pick of the Day selections can become available earlier

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) can now publish automatic picks earlier in the day. Before this change, automatic picks appeared closer to kickoff. A published pick keeps its market, side, and frozen price.

Read the returned `release_at` rather than calculating it from kickoff. `retry_at` and `Retry-After` on a `404` with `pick_not_released` still give the next time to ask.

**Backward compatible.** Response shapes do not change; picks can appear earlier in the day.

**What to change:** Nothing, if you follow `retry_at`. If you schedule reads from kickoff times, read earlier: a pick can be available hours before its game.

**October 7, 2026**

Trader adds pnl.net\_total, the total P\&L the 0xinsider profile shows

[`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) and [`POST /api/v1/traders/batch`](https://docs.0xinsider.com/api-reference/endpoint/batch-get-traders) now return `pnl.net_total`, the wallet's total P\&L as its 0xinsider profile shows it. It is Polymarket's position P\&L, fees included, plus maker and taker rebates, cut to whole cents, and it is omitted when Polymarket's figure is not available. With `expand=trust`, `trust.net_total_pnl` describes its source, and the remote MCP tools `get_trader` and `batch_get_traders` return the same field.

Before this change, the only total was `pnl.total`, Polymarket's all-time leaderboard figure. It is not realized plus unrealized P\&L, and on October 7, 2026 it differed from the profile's total by more than \$1 for 7,851 of 8,449 ranked wallets.

* `pnl.total` keeps its value and is now documented as Polymarket's leaderboard figure. `pnl` on [`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard) is the same figure, also unchanged.
* The `Total P&L` line of [`GET /api/v1/trader/{address}/context.md`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-context-markdown) now reads `pnl.net_total`, so it matches the profile and the JSON body.
* `trader.pnl` on [`GET /api/v1/large-positions`](https://docs.0xinsider.com/api-reference/endpoint/list-large-positions) now carries the same total as `pnl.net_total`. It was documented as realized P\&L but carried the leaderboard figure, and it is omitted when the wallet has no total.
* The `sync` group in `data_quality` now covers `pnl.net_total`.

**Backward compatible** for `pnl.net_total` and every unchanged field. `trader.pnl` on large positions changes value for most wallets.

**What to change:** Read `pnl.net_total` wherever you show a wallet's total P\&L. If you compared large-positions `trader.pnl` with `pnl.total`, compare it with `pnl.net_total`.

**October 7, 2026**

Large-trade market\_volume\_share now divides shares by shares

[`GET /api/v1/large-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades), [`GET /api/v1/large-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-large-trades-history), their `/api/v1/whale-trades` aliases, and the MCP `get_large_trades` and `get_large_trades_history` tools now compute `market_volume_share` as the trade's share count over the shares its market has traded. Polymarket records market volume in shares, so both sides of the ratio are now in the same unit.

Before this change, the numerator was `size_usd`, so every value read the true share multiplied by the trade's `price`. Over the 30 days to October 7 the old value was a median 1.74 times too small, and about 4.3 times too small for trades priced under 30 cents. `sort=market_volume_share` ranked favourites above longshots of the same size: half of its top 50 changes.

* Every published value is larger, by a factor of `1 / price`. The field still reads between 0 and 1, and its name and type are unchanged.
* `min_market_volume_share` filters and `sort=market_volume_share` ranks by the corrected value, so the same threshold now returns more trades.
* The share is withheld when the recorded market volume is smaller than the trade's share count. Over those 30 days this withheld one trade the old rule had published.
* A `sort=market_volume_share` cursor minted before this change continues against the new values, so a ranking paged across the change can skip trades.

**Breaking** for clients that compare `market_volume_share` with stored values or thresholds tuned to the old numbers. The response shape is unchanged.

**What to change:** Re-read any stored `market_volume_share` values, and restart a `sort=market_volume_share` ranking from its first page. A `min_market_volume_share` threshold tuned to the old values now admits more trades; raise it if you want pages of a similar size.

**October 7, 2026**

OpenAPI quota text and examples state the 500,000 Pro and 2,000,000 Max allowances

The [OpenAPI document](https://0xinsider.com/api/v1/openapi.json) now states the monthly quota the API enforces: 500,000 requests per UTC month on Pro and 2,000,000 on Max, with pay as you go up to 4 times the plan's allowance. The `@0xinsider/mcp` 2.14.4 package README states the same allowances, and 2.14.4 requires `@modelcontextprotocol/sdk` 1.32.1 or later, past advisory [GHSA-6qxp-vccf-f47h](https://github.com/advisories/GHSA-6qxp-vccf-f47h).

Before this change, parts of the document still described the allowance from before October 1, 2026:

* The `429` descriptions of `GET /api/v1/sports/pre-game-sides`, `GET /api/v1/sports/pre-game-side-observations`, `GET /api/v1/pick-of-the-day/ledger/{pick_id}`, `POST /api/v1/webhooks/{id}/verification-attempts`, and `GET /api/v1/webhooks/{id}/verification-attempts/{attempt_id}` said Pro includes 250,000 requests, with a 1,000,000 pay-as-you-go ceiling.
* `X-Monthly-Quota-Limit` and `monthly_quota.limit` described only Pro's allowance and showed `250000`. They now name both plans, and the examples show `500000`.
* `monthly_quota.ceiling` said `limit`, or 1,000,000 with pay as you go on. It now says 4 times `limit`.
* The `monthly_quota_exceeded` error reason now says the account used its plan's included requests, not the requests Pro includes.

The API's behavior, fields, and headers are unchanged.

**Backward compatible.**

**What to change:** Nothing. If you sized a client from the old text, read `X-Monthly-Quota-Limit` or `monthly_quota.limit` instead of a fixed number.

**October 7, 2026**

Pick of the Day groups Wimbledon by ATP/WTA and all cricket as Cricket

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) and the [archive](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive.md) now return `ATP` or `WTA` in `display_category` for tennis with a known tour, including Wimbledon and doubles. Men's and women's cricket competitions return `Cricket`. Tennis with an unknown tour remains `Tennis`.

Before this change, tennis could carry a tournament label such as `Wimbledon`, and cricket could carry a competition label such as `The Hundred Women`.

Historical display labels are corrected too. The response shape, `category`, pick identities, results, prices, and returns remain unchanged.

**Breaking** for clients that match the previous tournament or cricket competition labels.

**What to change:** Accept `ATP`, `WTA`, and `Cricket`, and refresh stored historical `display_category` values before rebuilding grouped statistics. Keep using `category` for the canonical sport bucket.

**October 7, 2026**

The MCP server card is also served at /.well-known/mcp.json

`GET https://0xinsider.com/.well-known/mcp.json` now returns the MCP server card, the same JSON document as `GET https://0xinsider.com/.well-known/mcp`. Some MCP discovery tools and site audits look for the card only at the `.json` path, where they received an error before this change.

`/.well-known/mcp` is unchanged and remains the canonical address. The MCP transport (`POST`) stays on `/.well-known/mcp` and `https://api.0xinsider.com/api/v1/mcp`.

**Backward compatible.**

**What to change:** Nothing.

**October 7, 2026**

Trader grade-at observations report model\_version grading, not grading-v4

[`GET /api/v1/trader/{address}/grade-at`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-grade-at) now returns `observation.model_version` as `grading` where it returned `grading-v4`. The field names the model family that wrote the grade, and 0xinsider has one wallet grading model, so the version suffix is gone. Every stored observation reads the new value, including the ones recorded before this change.

The grade, the timestamps, `model_build_sha`, and every other field are unchanged. `null` still means the model is unknown.

**Breaking** for clients that compare `model_version` with the exact string `grading-v4`.

**What to change:** Accept `grading`. To tell builds of the model apart, read `observation.model_build_sha`.

**October 7, 2026**

Pick of the Day updates daily availability and retry guidance

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) changes when automatic picks first become available for a New York date. Its retry fields now name the next available read time.

Before this change, the next read time could be earlier than the day's first available automatic pick.

* Before a day's first available pick, and after a skipped day, schedule your next read from the `404` `pick_not_released` response's `error.retry_at` or `Retry-After`.
* Read each pick's actual publication time from `published_at`.
* The response fields, `release_at`, and the `404` body shape are unchanged.

**Backward compatible.**

**What to change:** Nothing. If you poll, keep scheduling the next read from `error.retry_at` or `Retry-After`.

**October 6, 2026**

Pick of the Day moves automatic publication closer to kickoff

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) changes automatic publication timing so picks appear closer to their games. Picks still arrive throughout the day, up to the release's limit of 15.

Before this change, automatic picks could appear earlier in the day.

* The response fields, `release_at`, and the `404` `pick_not_released` response are unchanged.
* A scheduled pick still waits for its returned `release_at`.

**Backward compatible.**

**What to change:** Nothing. If you poll, keep scheduling the next read from `error.retry_at` or `Retry-After`.

**October 6, 2026**

Pick of the Day pick\_rank can reach 20 after a cancelled pick; picks stay at 15

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) can now return a `pick_rank` above 15 on a day with a withdrawn pick. A pick withdrawn because its game was cancelled keeps its rank but no longer uses one of the day's 15 picks, so the next pick takes the next free rank, up to 20.

Before this change a cancelled pick held one of the 15 slots, so that day ended with 14 picks.

* `pick_rank` now runs from 1 to 20 in `picks`, `scheduled_picks`, `locked_picks`, `proof_pending_picks`, the archive, and the ledger, and the OpenAPI document and the Pick of the Day MCP tool's output schema say so.
* `pick_count` is still at most 15, and a day still carries at most 15 picks.
* `pick_rank` is deprecated. Use `pick_id` for identity and `publication_order` for order.

**Backward compatible** for clients that read `picks` as a list.

**What to change:** If you validate `pick_rank` against a maximum of 15, or index a fixed 15-slot array by rank, raise the bound to 20 or key by `pick_id`.

**October 6, 2026**

Live-score source\_revision values jump to millisecond scale and stay increasing

[`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) now sends `sports.live_score.source_revision` and `sports.live_score.tennis_points.source_revision` as 13-digit integers, about 1,790,000,000,000 today. Each new revision is still greater than every earlier one for the same group, including after a restart of our cache.

Before this change both values were small counters, about 2,000,000 and 50,000. A cache restart could move them backwards for up to 15 minutes, and a client that kept only strictly newer revisions froze the live score for that time.

* The values are still integers that order updates. They are not timestamps; do not read them as a time.
* Every value fits in a JavaScript safe integer and in a signed 64-bit integer. It does not fit in a 32-bit integer.
* The first update after the change jumps from the small counter to the large value. A "newer than" check accepts it.

**Backward compatible** for clients that compare revisions or store them as 64-bit integers or JavaScript numbers.

**What to change:** If you store `source_revision` in a 32-bit integer column or variable, widen it to 64 bits. Nothing else.

**October 6, 2026**

MCP 2.14.3 cancels HTTP work and bounds documentation resource reads

`@0xinsider/mcp` 2.14.3 now forwards MCP request cancellation to every tool and resource HTTP read. Documentation resources also have a 15-second deadline covering headers and the complete response body.

Before this change, cancelled API reads continued until their existing deadline, and documentation reads had no deadline. Caller cancellation now has the local error code `request_cancelled`; the server's own API deadline retains `request_timeout`.

Cancelling a request stops the local HTTP read. It does not roll back a POST that already committed or guarantee that the remote server stopped its work. Tool names, arguments, results, and automatic retry behavior are unchanged.

**Backward compatible.**

**What to change:** Upgrade the local package to 2.14.3 once it is published. No MCP configuration changes are required.

**October 6, 2026**

TypeScript SDK 0.18.0 types empty picks and withheld identity fields

The generated declarations in `@0xinsider/sdk` 0.18.0 now describe the current API contract. API response bodies and SDK request behavior are unchanged by this release.

Before this change, the published SDK declarations omitted these response cases:

* `getPickOfTheDay` can return `state: "none"` with no entitled picks. Narrow on `state` before reading fields from a full pick.
* Archive and uncommitted-ledger entries can omit `matchup` and `category`. Check whether each field is present before rendering it.
* Sealed ledger entries withhold `kickoff`. Read the recorded kickoff from an opened entry when it becomes available.
* `entry_authorization.policy_version` supports an additional opaque value. Validate it against the versions supported by your client while retaining your authorization checks.
* `MarketSnapshot.sports.live_score.tennis_points`, when present, follows the named `TennisPoints` shape. Custom response objects must use that shape.

The SDK also exports `PickOfTheDayNoEntitledPicks`, `TennisPoints`, and `TennisRanking` by name.

**Breaking** for TypeScript clients that depend on the previous narrower declarations.

**What to change:** Update the affected narrowing, presence checks, and response types before upgrading to 0.18.0. Existing runtime requests remain valid.

**October 6, 2026**

TypeScript SDK optional fields explicitly permit existing undefined values

The TypeScript SDK, `@0xinsider/sdk`, now explicitly permits `undefined` in optional paging progress, parsed stream-frame, and data freshness fields that already return it. This makes the declarations usable with TypeScript's `exactOptionalPropertyTypes` option.

Before this change, those declarations used optional properties without explicitly describing their existing `undefined` values. Callers with the stricter compiler option could therefore reject otherwise valid SDK values.

Return values and API response bodies retain their existing shapes. The SDK also checks indexed access and control flow during development; missing optional request fields are omitted before calling Fetch.

**Backward compatible.** This adds accurate type information without changing valid requests or returned data.

**What to change:** Nothing. Enable `exactOptionalPropertyTypes` in your own project when you are ready to check absent properties separately from explicit `undefined`.

**October 6, 2026**

Referral-only paid API and feed access ends when the earned grant ends

Paid operations in the [REST API](https://docs.0xinsider.com/api-reference/introduction.md), MCP, and the [live event feed](https://docs.0xinsider.com/api-reference/endpoint/get-stream.md) now require an unexpired referral grant when referral rewards are the account's only source of Pro access. A refund removes the unearned portion of that grant. Independently paid subscriptions and separately authorized complimentary access retain their access.

Before this change, an expired referral grant could leave a never-paying account authorized for Pro indefinitely. Already awarded referral access could also survive a refund of the qualifying payment.

The response schema and authentication headers are unchanged. Once temporary paid access ends, paid API operations return the existing subscription-required refusal, and an open paid feed disconnects on its normal authorization recheck.

**Breaking** for clients that depended on referral access continuing beyond its earned period.

**What to change:** Handle the subscription-required response by prompting the account owner to subscribe. Reconnect paid feeds only after the account has valid paid access.

**October 6, 2026**

Soccer games identify home, draw, and away 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 identify each soccer result market and report when the game offers a draw.

For a soccer game with home-win, draw, and away-win markets:

* `markets[].side` identifies each market as `home`, `draw`, or `away`.
* `draw_offered` is `true` when the game offers a draw market.

Before this change, these soccer markets omitted `side`, and the game reported `draw_offered: false` even when a draw market was present. The SDK's `listGames` and `getGame` methods and MCP's `list_games` and `get_game` tools return the same corrected fields.

**Backward compatible.** Existing optional fields now carry the classified values; no field or type migration is required.

**What to change:** Nothing. Use `markets[].side` and `draw_offered` to identify result markets instead of guessing from their labels.

**October 6, 2026**

Pick of the Day archive excludes withdrawn picks and their statistics

[`GET /api/v1/pick-of-the-day/archive`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive) now excludes withdrawn recommendations from `picks`, `days`, `hit_rate`, and the cumulative series. A later market settlement does not return a withdrawn pick to the archive.

Before this change, a withdrawn released pick remained in the archive and could contribute to its statistics after settlement. Withdrawn picks are also excluded from current and dated recommendations.

The [public ledger](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-ledger.md) keeps every published commitment under its original `pick_id`. Its identity and proof bytes remain unchanged, and market settlement still determines the recorded result. Request and response fields are unchanged.

**Breaking** for clients that use the archive as a complete list of published commitments.

**What to change:** Refresh cached archive responses and use the public ledger when you need every published commitment. No field or type migration is required.

**October 6, 2026**

Pick of the Day excludes cancelled games from active recommendations

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) now excludes a pending pick from active recommendations when its game is explicitly cancelled. New selections also check the provider's game status before publication.

Before this change, a cancelled game could be selected or remain in the current day's recommendations.

The [archive](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive.md) and [ledger](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-ledger.md) retain the released pick's identity and publication record. Market settlement still determines its recorded result.

**Backward compatible.** Request and response fields are unchanged. The endpoint can return fewer picks or the existing `404` with `error.reason: "pick_not_released"` when no active pick remains.

**What to change:** Nothing. Keep handling an empty day with `Retry-After` or `error.retry_at`, and store each `pick_id` rather than assuming a fixed pick count.


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