> ## 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: March 25 to September 21, 2026

> 57 API, SDK, CLI, MCP, OAuth, and feed changes from March 25 to September 21, 2026, each with its effect on clients. Newer changes are on the API changelog.

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

**September 21, 2026**

Pro includes 250,000 API requests a month; pay as you go covers the rest

Every authenticated `/api/v1` request now counts against a monthly quota. Pro includes 250,000 requests per UTC calendar month, whatever your billing interval. Every authenticated response carries three new headers: `X-Monthly-Quota-Limit`, `X-Monthly-Quota-Remaining`, and `X-Monthly-Quota-Reset` (Unix seconds, the first instant of the next month).

[`GET /api/v1/usage`](https://docs.0xinsider.com/api-reference/endpoint/get-usage) adds `monthly_quota`, with `used`, `limit`, `remaining`, `reset_at`, `enforced_from`, `binding`, and `pay_as_you_go`. Reading it spends nothing.

From October 1, 2026, request 250,001 in a month answers `429` with `error.code` `rate_limited` and the new `error.reason` `monthly_quota_exceeded`, carrying `Retry-After` and `error.retry_at` set to the month's reset. A refused request is not counted. The counter runs from September 21, and nothing is refused before October 1.

Switch pay as you go on at [0xinsider.com/developers](https://0xinsider.com/developers) and requests over the quota keep answering. The excess bills at \$0.20 per 1,000 requests on a monthly invoice to the card on the subscription, and `binding` reads `false` for that account.

**Backward compatible.** A client that branches on `error.code` needs no change.

**What to change:** If you retry on `429`, read `Retry-After` first, because the monthly reset is days away rather than seconds. An email on September 21 announced 100,000 requests from November 1; the served contract is the one above.

**September 21, 2026**

OAuth registration caps at 10 per IP every 10 minutes, and metadata documents at 64 KiB

`POST /oauth/register` now has its own per-IP budget: 10 registrations per 600 seconds, checked after the shared OAuth cap of 60 a minute. The eleventh answers `429` with `error` `temporarily_unavailable` and `Retry-After: 600`. Every other OAuth `temporarily_unavailable` keeps `Retry-After: 60`.

A client ID metadata document (an https `client_id` with a path) is now limited to 64 KiB of decoded body, checked while it downloads, and a document over the limit is refused and never cached. At most 8 uncached documents are fetched at once per backend process.

Past that capacity, device authorization answers `429` with `Retry-After: 30`. The browser consent preview and decision keep their `200` `ok: false` shape with `error` `temporarily_unavailable`. A registered client or a cached document does not use that capacity.

**Backward compatible.** Open registration is unchanged and by design: RFC 7591, public clients only, PKCE S256 required, and an exact `redirect_uri` match at authorize and at the token endpoint.

**What to change:** Nothing. A client registers once and keeps its `client_id`, so no working client meets the cap.

**September 21, 2026**

List every graded holder of a market

Added [`GET /api/v1/market/{condition_id}/holders`](https://docs.0xinsider.com/api-reference/endpoint/get-market-holders): the graded holder roster of any Polymarket market, the same list a Pick of the Day shows for its market. It returns every S, A, or B wallet with open shares on either outcome, taken from a complete provider holder scan, ordered by `current_value_usd` descending. A wallet holding both outcomes is listed once, on its net side.

Each holder carries `shares`, Polymarket's own `current_value_usd` for that outcome, `grade`, `category_win_rate` and `category_win_record` in the market's category, badges, and `last_traded_at`.

* Filters: `outcome` (`yes`, `no`, `all`), `min_grade` (`S`, `A`, or `B`, while `C`, `D`, and `F` answer `400`), `limit`, and `cursor` (`mh_` prefix).
* The envelope carries `market`, `scan` (`source`, `complete`, and `wallet_count`, which counts every wallet the scan saw, graded or not), `totals` by side and grade, and an exact `total`.
* The route takes the raw `condition_id` or the `mkt_` id, and supports `ETag` and `If-None-Match`.
* An incomplete or failed scan answers `503` with `error.reason` `read_model_warming` and `Retry-After`. You never get a short list instead.

The roster is rebuilt at most once a minute per market and shared by every caller, so a page is cheap and a cursor survives the rebuild. Until now [`GET /api/v1/positions`](https://docs.0xinsider.com/api-reference/endpoint/get-positions) ignored `condition_id`, and [`GET /api/v1/large-positions`](https://docs.0xinsider.com/api-reference/endpoint/list-large-positions) is a change feed with a \$50,000 floor, so neither could answer this.

**Backward compatible.** No existing route changes.

**What to change:** Nothing.

**September 21, 2026**

Get a wallet's win record in every category, and in every esports game

Added [`GET /api/v1/trader/{address}/categories`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-category-records): one wallet's record in every canonical category it has a settled market in, busiest first. These are the counts behind the Pick of the Day holder chips.

* Each record carries `category`, `wins`, `decided`, `win_rate`, and `status` (`measured` or `not_enough_data`).
* The envelope carries `basis` (`settled_markets_all_sizes`), `min_decided_for_win_rate` (5), and `computed_at`.
* A record under that floor keeps its counts, with `win_rate` set to `null`.
* A category with no settled market is left out, never returned as a 0% record.
* A resolved trader with no record returns `records: []` with `200`. An unknown address returns `404`.
* `?category=` filters to one bucket through the same category rollup the rest of the API uses: `soccer`, `EPL`, and `champions league` all reach Soccer, and `football` is American football.

The same day, the `Esports` record gained `games[]`: the wallet's record per esports title (`LoL`, `CS2`, `Dota 2`, `Valorant`, and 7 more), each with `game`, `series_slug`, `wins`, `decided`, `win_rate`, and `status` under the same floor. The titles are named as the holder entries name them.

`games` is absent on every other category and on an Esports record with no title history, and the Esports row keeps the whole bucket's counts.

Game records fill in from the first daily rebuild on September 22.

This record differs from `category_strengths` on [`GET /api/v1/trader/{address}?expand=categories`](https://docs.0xinsider.com/api-reference/endpoint/get-trader), which uses a different measured sample for ranking context. Both field descriptions identify the different bases; use this endpoint for the plain settled record.

**Backward compatible.** No existing route changes.

**What to change:** Nothing.

**September 21, 2026**

Esports holder entries name the game their win rate was measured in

Holder entries on [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) and [`GET /api/v1/market/{condition_id}/holders`](https://docs.0xinsider.com/api-reference/endpoint/get-market-holders) add `category_win_rate_game` on an esports market. It names the game that `category_win_rate` and `category_win_record` were measured in: `LoL`, `CS2`, `Dota 2`, `Valorant`, `Call of Duty`, `Honor of Kings`, `Mobile Legends: Bang Bang`, `Overwatch`, `Rainbow Six Siege`, `Rocket League`, or `StarCraft II`.

* It is present when the wallet has at least 5 resolved markets in that game. The rate and record are then that game's rather than the whole `Esports` bucket's.
* It is absent when the rate is the wallet's whole Esports record, on every non-esports pick, and beside every status that is not `measured`.
* The payload-level `category` stays `Esports` either way.

Game records fill in from the first daily rebuild on September 22. Until then every esports entry carries the bucket record, as before.

**Backward compatible.** The field is new and optional, so existing clients are unaffected.

**What to change:** Label the rate with `category_win_rate_game` when it is present, and with `category` when it is not.

**September 21, 2026**

Pick of the Day archive publishes the price behind return\_per\_100 and both CLV operands

[`GET /api/v1/pick-of-the-day/archive`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive) rows add `backed_price` on exactly the rows that carry `return_per_100`, and `clv_entry_price` and `clv_close_price` on exactly the rows that carry `clv_pct`. On a win, `100 / backed_price` equals `return_per_100`. A pending pick, and any pick whose backed side is withheld, still carries none of them, so no gate moved.

`clv_explanation` on a measured row now names the entry before the close: `Entry 0.635, close 0.705: CLV = (0.705 / 0.635 - 1) x 100 = +11.0%.` The previous form printed the close first, and the arithmetic is unchanged.

What `backed_price` means is now stated everywhere it appears: the Polymarket CLOB order book midpoint at release, written once at publication and never changed, not an executed fill. A buyer pays the ask rather than the midpoint, so an executed stake usually returns a little less than `return_per_100`.

An API subscriber's audit had concluded the return was computed off the close; it is not, and both operands now sit next to the result.

**What to change:** If you parse `clv_explanation`, take the first number as the entry price.

**September 21, 2026**

The commitment ledger carries the payload of settled pre-sealing picks

[`GET /api/v1/pick-of-the-day/ledger`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-ledger) now returns `payload` on a settled `uncommitted` entry: the market, side, and price of a pick published before sealing began, in the same 8 fields and the same key order as an opened payload. It is not hashed, and the entry stays `pre_commitment: true`.

Before this change, an `uncommitted` entry carried no `payload` at all. 248 of the 250 picks published by September 21 predate sealing, so without their payloads a mirror could only take them on trust.

`payload` is `null` while the pick is pending, and on a settled pick whose stored row is missing one of those columns.

**Backward compatible.** Sealed and opened entries are unchanged.

**What to change:** Nothing.

**September 21, 2026**

Positions accept condition\_id, and a deep page returns as fast as the first

[`GET /api/v1/positions`](https://docs.0xinsider.com/api-reference/endpoint/get-positions) now honors `condition_id`, raw or as the `mkt_` id, to scope the feed to one market. Combine it with `min_size=0` for every reconciled position in that market. An unknown id returns `[]`.

Before this change, the parameter was parsed and then silently ignored. The `get_positions` MCP tool takes the same parameter.

A deep cursor page now returns as fast as the first. Page 11 of `category=Baseball` at `limit=100` took 3,707 ms and often timed out at 30 s; it now takes 866 ms. Rows and cursors are unchanged.

**September 21, 2026**

Remote MCP and @0xinsider/mcp 2.1.0 add get\_sports\_edge\_observations

[`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) and the stdio package `@0xinsider/mcp` 2.1.0 add `get_sports_edge_observations`, which calls [`GET /api/v1/sports-edge-observations`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-observations). `tools/list` now returns 35 tools.

* `cohort` is required: `wider_holder`, `in_play`, or `emerging_pile`.
* `category`, `limit` (1 to 100, default 20), and `cursor` are optional.
* The result carries the route's `snapshot_as_of`, `degraded`, and `funnel` next to `data`, `has_more`, and `next_cursor`. `degraded: true` marks a page you should not read as healthy evidence.

**Backward compatible.** Existing tools are unchanged.

**What to change:** Nothing.

**September 21, 2026**

Pick of the Day expands coverage to later games

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) can now include later games on the New York calendar date.

Before this change, daily coverage could omit those games. A day can still have no published selection.

**Backward compatible.** No field changed, and `scheduled_picks` and the archive keep their shape.

**What to change:** Schedule your next request from the `404 pick_not_released` response's `error.retry_at` instead of assuming the day has ended at a fixed UTC hour.

**September 20, 2026**

New endpoint: every Pick of the Day's pre-game commitment, opened once it settles

Added [`GET /api/v1/pick-of-the-day/ledger`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-ledger): one entry per published `(pick_date, pick_rank)`, ascending, in one of three states. The route needs an API key on a Pro account.

* `sealed` is a live pick. It carries `commitment_hash`, `commitment_algo` (`sha256(canonical_json(payload)||nonce)`), `sealed_at`, `kickoff`, and `permalink`, and nothing that states a side or a price.
* `opened` is a settled pick. It carries those fields plus `commitment_nonce`, the canonical `payload` the hash was taken over (market, side, `backed_price` as a decimal string, kickoff, date, rank), `outcome`, `resolved_at`, `matchup`, and `category`.
* `uncommitted` is a pick with no commitment, either published before the scheme existed or reaching kickoff unsealed. It is named rather than left out, and carries `pre_commitment: true`.

To check an opened entry yourself, take the bytes of `payload` exactly as you received them, append `commitment_nonce` decoded from hex, and sha256 the result. It equals `commitment_hash`, because the payload is served byte for byte as it was hashed.

A commitment is never written after kickoff, and never rewritten by an outcome correction.

**Backward compatible.** The pick and archive routes are unchanged.

**What to change:** Nothing.

**September 20, 2026**

Large positions report each outcome on its own and list every holding

On [`GET /api/v1/large-positions`](https://docs.0xinsider.com/api-reference/endpoint/list-large-positions), `total_size_usd` and `position_unrealized_pnl` are now the provider's value and unrealized P\&L for the one outcome named by `outcome_label` and `token_id`. `null` means the provider supplied no value, not zero. `event_total_value_usd` is now `null` when the value of any other outcome in the same market is unknown.

Before this change, a wallet holding both outcomes of a market had both outcomes' combined value and P\&L labelled as one outcome.

Four fields are added, two of them required:

* `combined_value_usd` and `combined_unrealized_pnl` are the wallet's whole-market totals. They equal the per-outcome fields unless `is_two_sided` is `true`, and the feed ranks by the combined value.
* `is_two_sided` is `true` when the wallet holds both outcomes.
* `holdings[]` lists every outcome the wallet holds, each with `outcome_index`, `outcome_label`, `token_id`, `share_count`, `avg_entry_price`, `current_price`, `value_usd`, and `unrealized_pnl`. `holdings[0]` restates the top-level per-outcome fields.

**What to change:** If you read `total_size_usd` as the wallet's exposure in a two-sided market, read `combined_value_usd` instead.

**September 20, 2026**

Volume fields are USD cash volume, never Polymarket leaderboard shares

Three `/api/v1` fields had been carrying Polymarket's share counts as dollars, and they now report USD cash volume. Polymarket's v2 leaderboard reports `volume` in both-sides shares, and its own schema says the figure is never USD.

On [`GET /api/v1/leaderboard/trending`](https://docs.0xinsider.com/api-reference/endpoint/list-trending-wallets):

* `window_volume_usd` is now both-sides cash volume in USD, taken from Polymarket's user-volume read, and it leaves the `required` set. It is omitted when Polymarket served no volume for that wallet, never returned as zero.
* `window_volume_shares` is added and carries the leaderboard's share figure.
* Polymarket tracks volume in whole UTC days, so the USD window is the whole-day span that covers the window you asked for.
* The default `min_volume_usd=5000` floor now compares dollars.

[`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) `stats.total_volume`, [`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard) `volume`, and the trader export's `provider_lifetime_volume` are now full-history both-sides USD cash volume from a verified observation, and are omitted or `null` without one. A wallet's figure is typically lower than before, because the previous number was a share count.

**What to change:** If you treated `window_volume_usd` as always present, handle its absence. Field names and types are unchanged.

**September 20, 2026**

Grades weigh the last 90 days, and counterparty participants carry last\_traded\_at

The wallet `grade` that every `/api/v1` response carries now weighs the wallet's last 90 days beside its lifetime record. A wallet with no trade for 30 days holds no better than B, and no better than C past 120 days.

Before this change, the only recency rule was a 365-day cliff, and the median B-graded wallet had last traded 56 days earlier.

[`GET /api/v1/whale-trades/{id}/counterparties/executions`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trade-counterparty-executions) and [`.../makers`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trade-counterparty-makers) add `last_traded_at` on the taker and on each maker: the latest recorded trade time, across all markets, for the tracked trader whose grade is shown. It is omitted when that time is unavailable.

**Backward compatible.** The `grade` field and its values are unchanged, and `last_traded_at` is new and optional.

**What to change:** Nothing, but a client that filters on grade will see some wallets move down.

**September 20, 2026**

OAuth registration now stores and enforces grant\_types

`POST /oauth/register` now stores `grant_types` and enforces it. Omitting the field registers `["authorization_code", "refresh_token"]`. Using a grant the client did not register answers `unauthorized_client` (`400`) at consent, at `POST /oauth/device/code`, and at `POST /oauth/token`.

Before this change, the registration response echoed a `grant_types` the server neither stored nor checked.

* The list must name `authorization_code` or `urn:ietf:params:oauth:grant-type:device_code`.
* It may not be empty, and it may hold nothing outside `grant_types_supported`. Each failure answers `invalid_client_metadata`.
* The response reports the stored list. `response_types` is `["code"]` only when the client holds `authorization_code` and registered a redirect URI, and `[]` otherwise.
* A client without `refresh_token` gets a token response with no `refresh_token` field, and repeats its flow after the hour.

Two authorizations completed at once for the same user and client now leave one live grant. A race could previously leave two.

**Backward compatible.** Clients registered before this change, and every client ID metadata document, carry every supported grant.

**What to change:** Register the grants a new client will use, because a grant it did not register is refused.

**September 20, 2026**

Pick of the Day holders carry the counts behind the category win rate

Holder entries on [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) add `category_win_record`, the two counts that `category_win_rate` is the ratio of. It is present only when `category_win_rate_status` is `measured`, and absent from payloads created before the field shipped.

* `wins`: resolved markets in the pick's category that the wallet closed with a profit.
* `decided`: markets the wallet closed with a profit or a loss. A market that resolved at zero realized P\&L counts in neither.

The same day, the basis widened. The rate and the record now count every resolved Polymarket market the wallet traded in the category, at any position size, and both are rebuilt daily. Until this change only positions of \$20 or more counted, so a wallet's rate can move.

The floor of 5 resolved markets is unchanged.

**Backward compatible.** The field is optional.

**What to change:** Nothing.

**September 19, 2026**

@0xinsider/mcp 2.0.0 adds a product CLI with browser login

`@0xinsider/mcp` 2.0.0 turns the existing executable into a product CLI. It adds `login` (approved in a browser, through the device authorization flow in the entry below), `whoami`, `refresh`, and `logout`, plus read commands backed by the SDK. The [CLI page](https://docs.0xinsider.com/integrations/cli.md) lists every command.

The read commands paginate JSON up to a bound, keep the full response envelope, and exit nonzero when the result is incomplete. 2.0.1, released the same day, refreshes an expired or rotated access token between pages, so a long paginated read no longer fails partway.

* 2.x needs Node 22 or newer.
* Stored sessions need macOS or Linux.

**Backward compatible.** Both binary names, the default stdio MCP server, `serve`, and `init` keep their behavior.

**What to change:** Nothing. If you upgrade to 2.x, check that you are on Node 22 or newer.

**September 19, 2026**

Typed category evidence on the trader route and on Pick of the Day holders

[`GET /api/v1/trader/{address}?expand=categories`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) adds `category_records[]` and `category_skill_model` beside the existing `category_strengths`. Each record holds forward-only evidence for one category, built from observed Polymarket taker fills.

A record carries:

* `status`: `live`, `insufficient`, `stale`, `unknown`, or `degraded`.
* `canonical_category` and `as_of`.
* `independent_event_count` and `resolved_condition_count`.
* `edge_mean`, `edge_sd`, `edge_se`, `edge_lower_95`, and `brier_event_avg`.
* `model_version` and `taxonomy_version`.

A row whose `status` is `insufficient`, `stale`, `unknown`, or `degraded` is still returned, and it withholds the scores. The absence of a category is not proof of skill. `status` is category eligibility, not a letter grade, and the wallet's global `grade` is unchanged.

`category_skill_model` reports how ready the model is overall, read from the same snapshot.

Holder entries on [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) also gained optional category context in this release. Internal selection evidence was later removed from customer pick responses; refer to the current endpoint for the supported holder fields.

**Backward compatible.** The new fields are optional, and the trader route omits them unless you ask for `expand=categories`.

**What to change:** Nothing.

**September 19, 2026**

Pick of the Day holders carry wallet badges

Holder entries on [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) add 5 badge fields. They are stamped at serve time from the wallet's current trader record, so they are never frozen with the pick.

* `wallet_age_days`: the wallet's age in days.
* `is_new_wallet`: `true` when the wallet's first trade was under 30 days ago.
* `markets_traded`: how many distinct markets the wallet has traded.
* `is_bot`: `true` at 10,000 or more distinct markets traded. That is a breadth rule, not proof of automation.
* `x_username`: the X handle on the wallet's Polymarket profile, without the `@`.

All 5 are present together, and only for a wallet that carries at least one badge. All 5 absent means the wallet has no badge, or the body was cached before the fields shipped.

**Backward compatible.** The fields are optional.

**What to change:** Nothing.

**September 19, 2026**

GET /api/v1/me returns the account and credential a request authenticated as

Added [`GET /api/v1/me`](https://docs.0xinsider.com/api-reference/endpoint/get-account-identity). It returns the account the request authenticated as, in an account envelope: the account ID, the credential ID, the credential kind, and the approved scopes. A developer key reports `null` scopes.

The response carries no email address and no token. The route uses the same paid-access check, `read` scope, usage accounting, and rate limits as every other read. The product CLI's `whoami` command reads it.

**Backward compatible.** It is a new endpoint.

**What to change:** Nothing.

**September 19, 2026**

OAuth adds the device authorization grant (RFC 8628)

OAuth now supports the device authorization grant, so an agent with no browser and no redirect receiver can hold a scoped, revocable 1-hour token instead of a pasted long-lived API key. Discovery at `/.well-known/oauth-authorization-server` now lists `device_authorization_endpoint` as `https://api.0xinsider.com/oauth/device/code`, and adds `urn:ietf:params:oauth:grant-type:device_code` to `grant_types_supported`.

`POST /oauth/device/code` takes the form fields `client_id`, optional `scope` (default `read`), and optional `resource`. It returns `device_code`, `user_code`, `verification_uri`, `expires_in: 600`, and `interval: 5`.

* The person opens `verification_uri`, signs in, enters the `user_code`, reviews the account and the scopes, then approves or denies. Only an active Pro account can approve.
* Your client polls `POST /oauth/token` with `grant_type`, `client_id`, and `device_code`.
* `authorization_pending`, `slow_down`, `access_denied`, and `expired_token` all come back as `400`. Each poll that arrives early adds 5 seconds to the interval, and a `device_code` that has already been used answers `invalid_grant`.
* The exchange gives the same scoped grant, refresh, and per-client revocation as the authorization-code flow.
* A device-only client can register at `POST /oauth/register` without `redirect_uris`, and asks for `response_types: []`.

**Backward compatible.** The authorization-code flow is unchanged.

**What to change:** Nothing.

**September 19, 2026**

Remote MCP adds get\_sports\_edge\_signals, plus a Markdown document per market

[`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) and the stdio package add `get_sports_edge_signals`, which dispatches to [`GET /api/v1/sports-edge-signals`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-signals). `tools/list` now returns 34 tools, and `@0xinsider/mcp` 1.3.1 serves the same catalog.

The stdio `get_trending_wallets` now caps `limit` at 50 and keeps the gaps in the daily P\&L curve, which matches V1 and the remote tool. Before this change it advertised a limit of 100 and filled those gaps with zeros.

Added [`GET /api/v1/market/{condition_id}/context.md`](https://docs.0xinsider.com/api-reference/endpoint/get-market-context-markdown), a self-contained `text/markdown` evidence document for one market. It needs an API key, and it is rendered from the same typed data as the [market snapshot](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot.md), including that snapshot's trust fields.

* It carries the market's identity, the outcome labels and tokens, cached quotes, liquidity, live sports, and per-source freshness or the reason a source is unavailable.
* Text that came from a provider is encoded as indented JSON, so it stays inert.
* The path accepts a raw `condition_id` or an `mkt_` id. An unknown market returns `404`.
* There is no `ETag`. Use the snapshot route for conditional reads.

**Backward compatible.** Existing tools and routes are unchanged.

**What to change:** Nothing.

**September 17, 2026**

An API key in a ?token= query parameter is refused on every route

An API key sent as a `?token=` query parameter is now refused on every route, with `401 invalid_api_key` and the new `error.reason` `api_key_in_query`. Before this change, [`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) and its GET event stream still accepted a key that way.

The reason: a live key does not expire, and a URL is written to access logs, proxies, shell and browser history, and client config dumps.

* When a request carries both the header and `?token=`, the header is used and the request succeeds.
* `initialize`, `ping`, and `tools/list` still need no credential. A request that puts a key in the URL is refused before it reaches them.
* No working integration used the query form. Between September 4 and September 17, 2026 it recorded no accepted request.

**Breaking** for a client that sends its key in the URL. The `invalid_api_key` code is unchanged, so a client that branches on `error.code` needs no change.

**What to change:** Send the key as `Authorization: Bearer <key>`. A client that can only take a URL can run the `@0xinsider/mcp` stdio package with the key in its environment instead.

**September 17, 2026**

Refused requests report the per-IP rate-limit budget

A request that `/api/v1` refuses before it checks the key's own limit now carries the per-IP bucket's `RateLimit-*` and `X-RateLimit-*` headers. Before this change those responses carried no budget, so a client retrying a rejected key could not see how close it was to the per-IP limit.

The responses that now carry the headers:

* `401 invalid_api_key`.
* `402 subscription_required`.
* `403` for a deleted account, and `403 insufficient_scope`.
* `423` for a locked account.
* The authentication layer's own `500` and `503` responses.
* The MCP handshake, which needs no credential.

The numbers are always the per-IP bucket, the only budget a failed authentication spends. A caller refused because its IP is banned still gets no headers, and neither does a request whose client IP could not be resolved.

The OpenAPI spec now documents these headers on every operation that sends them.

**Backward compatible.** Existing clients are unaffected.

**What to change:** Nothing.

**September 17, 2026**

Pick of the Day's CLV average is reported in percentage points

[`GET /api/v1/pick-of-the-day/archive`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive) adds `hit_rate.clv_avg_pp` and `hit_rate.clv_avg_pp_display`. Both hold the mean closing-line move in percentage points, `(close - entry) * 100`, for example `"-0.1 pp"`.

The existing `clv_avg_pct` is the mean of per-pick ratios, `(close / entry - 1) * 100`. A cheap entry moves that mean more than a favorite does. A pick at $0.05 that closes at $0.10 counts as +100%, while a pick at $0.90 that closes at $0.95 counts as +5.6%.

The percentage-point average counts every pick on the same scale, and it is now the headline figure on 0xinsider.com.

Both averages cover the same measured picks, and both are omitted until at least 5 of them exist. `clv_avg_pct` and `clv_avg_display` are unchanged.

**Backward compatible.** The new fields are optional.

**What to change:** Nothing. Read `clv_avg_pp` if you want the figure 0xinsider.com shows.

**September 16, 2026**

Large trades carry their share of the market's volume

[`GET /api/v1/whale-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades), [`GET /api/v1/whale-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades-history), and [`GET /api/v1/whale-trades/{id}`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trade) add the optional field `market_volume_share`. It is the fill's `size_usd` divided by its market's volume at the moment the trade was recorded.

`size_usd` on its own cannot tell a large bet in a thin market from a routine one in a deep market. A $10,000 fill is 0.00005 of a $200M market and 0.125 of an \$80,000 one.

* The value is not capped at `1`, because a fill larger than the market's stored trailing volume is the case that matters most.
* It is absent when the market carried no volume figure, and on trades recorded before September 16, 2026.
* It is never `0` as a stand-in for a missing value.

**Backward compatible.** The field is optional.

**What to change:** Nothing.

**September 8, 2026**

A second venue removed: the API serves Polymarket only

0xinsider retired its second venue on September 8, 2026. Every V1 endpoint now serves Polymarket data only, and responses no longer contain that venue's markets, trades, positions, or P\&L.

* [`GET /api/v1/platforms`](https://docs.0xinsider.com/api-reference/endpoint/get-platforms) returns `platforms.polymarket` only. The retired venue's key is gone.
* `platform` on [`GET /api/v1/whale-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades-history), [`GET /api/v1/markets/sharp-money-flows`](https://docs.0xinsider.com/api-reference/endpoint/sharp-money-flows), and [`GET /api/v1/markets/smart-money-flows`](https://docs.0xinsider.com/api-reference/endpoint/smart-money-flows) accepts `polymarket` or `all`, and both return Polymarket rows. Every other value returns `400 bad_request` with `error.param="platform"`.
* [`GET /api/v1/markets/explore`](https://docs.0xinsider.com/api-reference/endpoint/explore-markets) still accepts `platform` for backward compatibility, and returns Polymarket markets for every value.
* [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot) returns `market.provider` as `polymarket`, and `liquidity.last_price` is always `null`.

**Breaking** for a client that sends any `platform` value other than `polymarket` or `all`.

**What to change:** Drop the `platform` parameter, or send `polymarket`. Earlier entries in this changelog describe the API as it shipped on their date.

**August 29, 2026**

Pick of the Day serves every ready pick while another pick's proof is pending

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) now answers `200` when at least one published pick has readable smart-money proof. `picks` carries the picks whose proof is readable, and the new `proof_pending_picks` array lists the rest with `pick_rank`, `release_at`, `kickoff`, and `retry_at`.

Before this change, one published pick whose proof was not readable yet turned the whole day into `503 read_model_warming`. On August 29 one pick's holder snapshot lagged its publish, and the API withheld three fully proven picks for 14 minutes. The `503` now remains only when no published pick has readable proof.

**Backward compatible.** The field is additive.

**What to change:** Nothing. To fetch a pending pick, read again at its `retry_at`.

**August 29, 2026**

Remote MCP adds two Pick of the Day tools

[`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) adds 2 tools, and both take no arguments. `get_pick_of_the_day` dispatches to [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day), and `get_pick_of_the_day_archive` to [`GET /api/v1/pick-of-the-day/archive`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive). `tools/list` now returns 33 tools.

A tool error from any remote tool now carries the V1 `error.code`, `error.reason`, and `error.retry_at` when the handler set them. Before the day's pick is released, `get_pick_of_the_day` therefore reads `404 Not Found (not_found/pick_not_released): ... Not available before <retry_at>.`, so an agent can schedule the next call instead of polling.

The stdio package `@0xinsider/mcp` 1.2.0 serves the same 33 tools.

**Backward compatible.** Existing tools and REST routes are unchanged.

**What to change:** Nothing.

**August 29, 2026**

Pick of the Day's 404 retry\_at accounts for newly available selections

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) now sets `error.retry_at` and `Retry-After` on a `404 pick_not_released` to account for newly available selections as well as scheduled releases.

Before this change, the value was the earliest scheduled slot's `release_at`. A newly available pick could release earlier, so a client honoring the old value could miss its release.

Until a pick releases, keep scheduling requests from the returned retry time.

**Backward compatible.** The response shape is unchanged.

**What to change:** Nothing. A client that schedules from `retry_at` keeps working.

**August 19, 2026**

Pick of the Day lists the day's picks that have not released yet

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) adds `scheduled_picks`: the day's selected picks that have not released yet, in `pick_rank` order.

Each slot carries exactly 3 fields: `pick_rank`, `release_at`, and `kickoff`. The shape holds no matchup, category, side, price, or holder data before release, so the schedule can be shown without revealing a pick early.

The field is present only while at least one unreleased slot remains, so its absence means the day is fully released.

**Backward compatible.** The field is optional.

**What to change:** Nothing. To plan your next read, request once at the earliest `release_at` instead of polling.

**August 16, 2026**

@0xinsider/mcp 1.0.9 serves 29 tools locally, up from 6

[`@0xinsider/mcp`](https://docs.0xinsider.com/integrations/mcp) 1.0.9 is on npm, the first release since 1.0.2 on April 14. The local stdio server goes from 6 tools to 29, the same set the hosted endpoint serves.

* New tools: positions, position timeline (by wallet or by id), large positions, trending wallets, trader P\&L, market explore, sharp-money flows, market snapshots, whale-trade history and single-trade lookup, batch trader and market-intel lookups, daily, weekly and monthly report snapshots, trader exports, webhook reads, and event replay.
* `get_smart_money_flows` still works.
* Whale-trade tools return `recorded_signal_score`.
* `init` hides the API key as you type it, and prints a placeholder where a configuration to paste by hand would have shown the key.

The hosted [`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) serves the same tools plus `get_report` and `search_content`, 31 in all.

**Backward compatible.** The release adds tools.

**What to change:** Nothing. Run `npx -y @0xinsider/mcp init` to set up or update. If an earlier `init` printed your key into output that was recorded or shared, rotate the key from [Developers](https://0xinsider.com/developers).

**August 3, 2026**

Large trades carry the signal score captured when the trade was recorded

[`GET /api/v1/whale-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades), [`GET /api/v1/whale-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades-history), and [`GET /api/v1/whale-trades/{id}`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trade) now return the optional field `recorded_signal_score` next to the existing `signal_score`.

* `signal_score` is the current score.
* `recorded_signal_score` is the score captured with the trade record. Use it in alerts, audits, and historical comparisons.
* The recorded score exists only for trades recorded after this release. Older trades return `null`.

**Backward compatible.** The field is optional.

**What to change:** Nothing.

**July 26, 2026**

Pick of the Day reports the availability of stored trader context

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) added optional metadata describing whether stored trader context was available to read. Before this change, missing context did not distinguish an absent record from an unavailable one.

The metadata described recorded context, rather than live trader statistics or entry permission. This release also documented the existing trader context and display category.

**Backward compatible at release.** The metadata was optional. Internal selection diagnostics were later removed from customer responses; use the currently documented pick fields.

**What to change:** Read the current endpoint reference for the customer response contract.

**July 14, 2026**

New observation-only endpoint for wider-holder and in-play sports markets

Added [`GET /api/v1/sports-edge-observations`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-observations), an Insider-tier endpoint that reports evidence on sports opportunities that do not enter the funded Sports Edge slate. Every row carries `observation_only: true`, provider and holder freshness fields, and an explicit directional status.

Pick one `cohort`, which is required:

* `wider_holder` measures pre-game markets where the graded holders currently agree, even when no recent graded whale flow exists.
* `in_play` measures only games the provider confirms are live, and only when the holder and directional evidence is fresh.

Use the returned provider state, freshness, and directional status to interpret each row. Every response carries a per-sport funnel that records emitted observations and the reasons other rows are unavailable.

`capacity_limited` describes a bounded response. It does not by itself mean that the snapshot is degraded.

Omit `category` to evaluate all 14 observation sports. That registry includes Table Tennis and Pickleball, classified from provider-confirmed tags and kept separate from Tennis. The `table-tennis`, `table tennis`, and `pickleball` filters all resolve through the canonical taxonomy, and neither sport is in the 12-sport funded projection.

Reading the response:

* Every `200` carries a required top-level `degraded: boolean`, the verdict for the whole snapshot. It covers both operational trouble and unknown completeness.
* A healthy `wider_holder` request can reuse a snapshot for about 180 seconds. `in_play` never serves one older than about 30 seconds.
* Conditional reads use a weak semantic `ETag` over the stable part of the page, which includes `next_cursor` and excludes the request-specific `meta`.
* A malformed typed query value returns the standard JSON `400 bad_request` envelope.
* `503` with `error.reason: "read_model_warming"` means the route ran out of time before it had the data it needs. A later failure shows up instead as a degraded `200`, with the funnel filled in where possible.
* The API's outer 30-second transport timeout still returns a `408` with an empty body, so check the status before you parse JSON.

These groups remain observations only and do not authorize entries or contribute to published picks.

**Backward compatible.** It is a new endpoint, and it does not change or feed [`GET /api/v1/sports-edge-signals`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-signals), Pick of the Day, or any order executor.

**What to change:** Nothing.

**July 13, 2026**

Sports Edge covers Golf, Formula 1, NBA Summer League, CFL, and Boxing

[`GET /api/v1/sports-edge-signals`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-signals) and [`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) can now return eligible markets for Golf, Formula 1 and NASCAR, NBA Summer League, CFL, and Boxing.

Polymarket sends only generic sports metadata for some of these markets. 0xinsider uses the provider tags to identify their sports categories. `Racing` and `Boxing` are now supported canonical buckets.

**Correction:** an earlier version of this entry also named Table Tennis and Pickleball. The funded release did not admit either sport. Both are registered for observation-only evaluation through the endpoint added on July 14, and neither feeds funded signals or Pick of the Day.

For the funded taxonomy changes in this release, an open market can adopt the corrected category on a provider refresh. Historical rows need a controlled refold, so they are not implied to have reclassified on their own.

**Backward compatible.** No request or response shape changed, and no existing category was renamed.

**What to change:** Nothing.

**July 6, 2026**

New endpoint: ranked pre-game sports markets with graded money on one side

Added [`GET /api/v1/sports-edge-signals`](https://docs.0xinsider.com/api-reference/endpoint/get-sports-edge-signals), a ranked list of upcoming pre-game sports markets (moneyline and props) where graded S, A, and B smart money sits on one side. The server computes the whole list in one call.

Each signal returns:

* The side the graded money is on, and its CLOB `token_id`.
* The grade distribution on that side: `s_count`, `a_count`, and `b_count`.
* The dollar concentration: `sharp_pct` and `backed_sharp_usd`.
* The market's `game_start_time`, which is kickoff.
* A calculated backing score, `conviction_score`.

Follow the returned order when presenting the markets, and read the measured backing alongside the scores.

The route needs a bearer token and an Insider tier account. Its `200` carries an `ETag`, and it is cursor-paginated with the cursor fixed to one snapshot.

**Backward compatible.** It is a new endpoint.

**What to change:** Nothing.

**July 5, 2026**

Pick of the Day returns 404 outside today's pick, and adds game\_started

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) changes in 2 ways.

The new boolean field `game_started` is `true` once the backed game's kickoff has passed, which means the snapshotted pre-game price is no longer actionable. It is absent on a legacy pick with no stored kickoff, and you should treat that as not started.

The `is_locked` description was corrected at the same time. It is a pre-release embargo flag, so it is effectively always `false` on a served pick. Use `game_started` for kickoff.

The endpoint now returns `404` when today has no published pick yet, instead of serving the most recent prior day's pick, which was often already settled. The response shape is unchanged and `404` was already a documented response. This conforms the endpoint to its "today's Pick of the Day" contract, so an automated consumer never acts on a finished game.

Prior picks stay available through the archive endpoint.

**Backward compatible.** `game_started` is optional, and the behavior change is non-breaking.

**What to change:** Nothing.

**July 4, 2026**

Sandbox test-mode API keys removed; one live key class remains

Sandbox test-mode API keys (`oxi_sk_test_...`) are removed. The API now has a single key class, `oxi_sk_live_...`, sent as `Authorization: Bearer oxi_sk_live_...`. It requires an active Insider subscription and always returns live data.

There is no fixture or deterministic-data mode any more. Every request reads live data.

**Breaking** for a client still authenticating with an `oxi_sk_test_...` key. Those requests fail.

**What to change:** Generate a live key from your account's API keys page, and switch your clients over before this release.

**July 2, 2026**

Pick of the Day: a fixed 19:00 Europe/Berlin release and any sport

[`GET /api/v1/pick-of-the-day`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) and its archive change behavior in 2 ways. No field was added, removed, or retyped, but 2 values now mean something different.

`release_at` is now a fixed daily instant: 19:00 Europe/Berlin, every day, which is 19:00 CEST in summer and 19:00 CET in winter. It used to be a kickoff-relative time that moved with whichever game was picked. `next_drop_deadline` counts down to the same fixed instant.

When no pick is available at the release slot, publication can happen later. On a thin day the actual publication can trail `release_at` by minutes to hours.

The pick can now cover more sports and prop markets, expanding beyond the previously narrower set of categories.

* Sports: soccer, tennis, baseball, basketball, hockey, MMA, cricket, golf, and esports.
* Prop markets: totals, spreads, and exact scores.
* Expect `category` values beyond `Soccer` in the archive from now on.

**Backward compatible.** Existing clients are unaffected.

**What to change:** Nothing.

**July 1, 2026**

Whale trades expose the traded outcome and its CLOB token id

Each whale trade on [`GET /api/v1/whale-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades), [`/whale-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades-history), and [`/whale-trades/{id}`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trade) now returns the traded `outcome` and that outcome's Polymarket CLOB `token_id`. The `outcome` is the provider's own label for the side the trade was on, for example Yes, No, or a team. The existing `side`, `BUY` or `SELL`, is unchanged.

Before this change only `BUY` or `SELL` was exposed, so you could not tell which outcome a whale trade was on, or get that outcome's on-chain token id.

`outcome` is `null` only for a multi-outcome market, or a market that has not synced, with no stored label. A trade from the venue retired on September 8, 2026 carries its provider label in `outcome`, and only its `token_id` is `null`, because that venue had no CLOB token; see that entry.

**Backward compatible.** Both fields are optional and nullable.

**What to change:** Nothing.

**July 1, 2026**

Every V1 YES/NO/outcome now carries its Polymarket CLOB token id

Reads that expose an outcome, a side, or a net-flow direction now also return that outcome's Polymarket CLOB `token_id`. You can go straight from a YES, NO, or outcome label to its on-chain ERC1155 asset id without a second lookup. Use it for order placement, per-token price history, and on-chain reconciliation.

The value is a decimal string for a synced Polymarket market, and `null` when it is unavailable, for example on a market from the venue retired on September 8, 2026, or a market that has not synced yet. The key is always present, and it is never in a `required` set; see that entry.

The endpoints that gained it:

* [`GET /api/v1/positions`](https://docs.0xinsider.com/api-reference/endpoint/get-positions): `token_id` next to `side`.
* [`GET /api/v1/large-positions`](https://docs.0xinsider.com/api-reference/endpoint/list-large-positions): `token_id` next to `outcome_label`.
* [`GET /api/v1/market/{condition_id}/intel`](https://docs.0xinsider.com/api-reference/endpoint/get-market-intel) and [`POST /api/v1/markets/intel/batch`](https://docs.0xinsider.com/api-reference/endpoint/batch-get-market-intel): `token_id` on `smart_money`, next to `direction`, and on every `smart_money.top_positions` entry.
* [`GET /api/v1/markets/smart-money-flows`](https://docs.0xinsider.com/api-reference/endpoint/smart-money-flows): `token_id` on `smart_money`, next to `direction`.
* [`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): `token_id` next to `outcome_side`.
* [`GET /api/v1/markets/explore`](https://docs.0xinsider.com/api-reference/endpoint/explore-markets): `token_id_yes` and `token_id_no` next to `outcome_yes` and `outcome_no`. These are CLOB token ids (decimal strings), and they are different from the integer Gamma ids `outcome_yes_provider_id` and `outcome_no_provider_id`.
* [`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): `token_id` on every `top_whale_trades` entry.

**Backward compatible.** The field is optional, so existing clients are unaffected.

**What to change:** Nothing.

**July 1, 2026**

Pick of the Day archive adds a cumulative track-record series

[`GET /api/v1/pick-of-the-day/archive`](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day-archive) now returns `hit_rate.series`, the cumulative track record of the Pick of the Day. It is ready to chart without recomputing it on the client.

Each element is one resolved pick, a win or a loss, in ascending `pick_date` order, and carries:

* `date`: the pick's publish date, as `YYYY-MM-DD`.
* `net_profit_usd`: the running cumulative profit of a \$100 stake on every resolved, priced pick through that date.
* `hit_rate_pct`: the running hit rate (wins divided by decided) through that date, to one decimal.

The final point equals the top-level `hit_rate.net_profit_usd` and `hit_rate.pct`, so a chart of the series always ends exactly on the headline numbers. The array is empty until at least one pick has resolved.

**Backward compatible.** Every existing `hit_rate` field is unchanged.

**What to change:** Nothing.

**June 29, 2026**

Trader quant\_metrics is now a documented, fixed field set

[`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 a curated, documented `quant_metrics` object when you pass `?expand=quant_metrics`. Before this change it was an unconstrained pass-through of internal metrics.

When expanded, the object always carries these 9 fields. Each is a number or `null`, and `null` means insufficient trade history, never `0`.

* `copy_score` and `smart_score`: scores from 0 to 100. `smart_score` summarizes measured performance, and `copy_score` summarizes how practical the wallet's past strategy may be to follow.
* `sharpe_30d` and `sharpe_7d`: risk-adjusted return over the trailing 30 and 7 days.
* `profit_factor`: gross profit divided by gross loss, capped at 1,000.
* `edge_consistency`: how stable the trader's edge is over time, from 0 to 1.
* `sharpe_percentile`, `pf_percentile`, and `consistency_percentile`: cross-sectional ranks against all traders, from 0 to 100.

Undocumented internal and experimental metrics that used to come through the pass-through are no longer returned.

Every field is defined on the [trader endpoint reference](https://docs.0xinsider.com/api-reference/endpoint/get-trader.md), and the [Quant metrics guide](https://docs.0xinsider.com/concepts/quant-metrics) explains what each score and metric means, its range, and how to read `null`.

**Breaking** for a client that read a metric outside this list.

**What to change:** Nothing, if you use only the 9 documented fields.

**June 1, 2026**

New endpoint: ranked market discovery by smart-money net flow

Added [`GET /api/v1/markets/smart-money-flows`](https://docs.0xinsider.com/api-reference/endpoint/smart-money-flows), a ranked discovery feed that answers where smart money is flowing before you know a `condition_id`.

It ranks markets by absolute net flow from S, A, and B grade traders over a `1h`, `4h`, `24h`, or `7d` window, with `platform`, `category`, `min_grade`, and `direction` filters. Pagination uses an opaque cursor anchored to the first page's `as_of`, so new whale trades do not reorder later pages.

To look at a single market in detail, use [`GET /api/v1/market/{condition_id}/intel`](https://docs.0xinsider.com/api-reference/endpoint/get-market-intel).

**Backward compatible.** It is a new endpoint.

**What to change:** Nothing.

**June 1, 2026**

Remote MCP read parity, usage and caching headers, and round-trippable IDs

**Remote MCP read parity.** [`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) now exposes 21 tools through `tools/list`, covering the public V1 reads: batch reads, history, event replay, webhook reads, reports, market snapshots, and trader exports. Webhook mutations stay REST-only, and the endpoint is tools-only, with no resources and no prompts.

**Your own usage.** Added [`GET /api/v1/usage`](https://docs.0xinsider.com/api-reference/endpoint/get-usage), an authenticated read of your current per-minute limiter window and your UTC-day usage. It does not spend primary quota, but it has its own guard of 100 reads a minute.

**Cheaper polling, safe retries.** Deterministic reads now support `ETag` and `If-None-Match` conditional GETs, so an unchanged read returns `304` with no body. Webhook create, update, delete, and rotate accept an `Idempotency-Key`.

**Discovery.** Added [`GET /api/v1`](https://docs.0xinsider.com/api-reference/endpoint/get-api-discovery), an API discovery document, and [`GET /api/v1/openapi.json`](https://docs.0xinsider.com/api-reference/endpoint/redirect-api-openapi-spec), a redirect to the canonical OpenAPI spec. Operation IDs are now codegen-friendly, with examples, code samples, and response-header metadata.

**Round-trippable IDs.** Market Intel and Market Snapshot now accept either the `mkt_...` market ID or the raw `condition_id`. New [`GET /api/v1/whale-trades/{id}`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trade) and [`GET /api/v1/insider-radar/{id}`](https://docs.0xinsider.com/api-reference/endpoint/get-insider-radar-flag) return a single `wt_...` or `rf_...` record. A prefix that is not a market prefix returns `400 bad_request`.

**Backward compatible.** Everything here is new or optional.

**What to change:** Nothing.

**May 8, 2026**

Remote MCP exposes position and market discovery tools

[`POST /api/v1/mcp`](https://docs.0xinsider.com/api-reference/endpoint/remote-mcp) now exposes 9 tools through `tools/list`. The new ones are `get_positions`, `get_position_timeline`, and `explore_markets`.

Each dispatches to the existing public REST handler, so an MCP client gets the same auth, pagination, and payload contracts as a direct REST caller.

**May 8, 2026**

New builder endpoints: batch, history, events, webhooks, reports, snapshots

Added task-shaped builder endpoints, so an integration needs fewer calls:

* [`POST /api/v1/traders/batch`](https://docs.0xinsider.com/api-reference/endpoint/batch-get-traders)
* [`POST /api/v1/markets/intel/batch`](https://docs.0xinsider.com/api-reference/endpoint/batch-get-market-intel)
* [`GET /api/v1/whale-trades/history`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades-history)
* [`GET /api/v1/events/feed/since`](https://docs.0xinsider.com/api-reference/endpoint/get-event-replay-since)
* [`GET /api/v1/market/{condition_id}/snapshot`](https://docs.0xinsider.com/api-reference/endpoint/get-market-snapshot)
* [`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)
* [`GET /api/v1/trader/{address}/export`](https://docs.0xinsider.com/api-reference/endpoint/get-trader-export-snapshot)
* [`GET /api/v1/webhooks`](https://docs.0xinsider.com/api-reference/endpoint/list-webhooks), plus webhook create, read, update, delete, verify, and rotate-secret operations

Batch endpoints expose item-weighted cost headers. The new snapshot, history, and report payloads document their source, freshness, completeness, and reconciliation, so you can tell a provider-backed value from a cached, partial, stale, or unavailable one.

**May 8, 2026**

TypeScript client source added

Added [TypeScript client guidance](https://docs.0xinsider.com/integrations/typescript-client.md) for the repo-owned client source in `web/src/lib/api-client`.

The client source is drift-tested against OpenAPI. It handles bearer auth, path params, repeated query params, JSON bodies, and V1 error envelopes. It is not a published npm package yet.

**May 7, 2026**

Market Intel rejects prefixed market IDs

[`GET /api/v1/market/{condition_id}/intel`](https://docs.0xinsider.com/api-reference/endpoint/get-market-intel) now returns a clearer `400 bad_request` when a caller passes a prefixed `market.id` value such as `mkt_...` instead of the raw `condition_id`.

Call [`GET /api/v1/markets/search`](https://docs.0xinsider.com/api-reference/endpoint/search-markets) first, then pass the `condition_id` it returns into the Market Intel path.

**April 14, 2026**

Trader lookup accepts usernames and plain expand params

[`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) now accepts a known trader username in the path, as well as an Ethereum wallet address.

You can request heavy trader fields with repeated `expand` query params. The older `expand[]` form still works for existing clients.

**April 2, 2026**

Leaderboard strategy fields can be null

[`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard) now returns traders that have no classified strategy.

Treat `strategy_type` as nullable for a ranked trader with no strategy classification.

**April 1, 2026**

Explore Markets excludes untitled rows

[`GET /api/v1/markets/explore`](https://docs.0xinsider.com/api-reference/endpoint/explore-markets) no longer returns untitled markets.

The response set is now titled, user-facing markets only.

**March 28, 2026**

Trader realized P\&L corrected

[`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader) now returns the canonical realized P\&L, read from the `realized_pnl` source-of-truth field.

`pnl.realized` no longer derives realized P\&L from an inconsistent approximation.

**March 26, 2026**

Explore Markets endpoint launched

Added [`GET /api/v1/markets/explore`](https://docs.0xinsider.com/api-reference/endpoint/explore-markets) for cursor-paginated market discovery.

It supports category, status, platform, and text filters. It also injects the primary market, so a grouped event includes its main market when one exists.

**March 25, 2026**

Initial V1 launch

Launched the first public developer API:

* [`GET /api/v1/trader/{address}`](https://docs.0xinsider.com/api-reference/endpoint/get-trader)
* [`GET /api/v1/whale-trades`](https://docs.0xinsider.com/api-reference/endpoint/get-whale-trades)
* [`GET /api/v1/leaderboard`](https://docs.0xinsider.com/api-reference/endpoint/get-leaderboard)
* [`GET /api/v1/markets/search`](https://docs.0xinsider.com/api-reference/endpoint/search-markets)
* [`GET /api/v1/market/{condition_id}/intel`](https://docs.0xinsider.com/api-reference/endpoint/get-market-intel)
* [`GET /api/v1/insider-radar`](https://docs.0xinsider.com/api-reference/endpoint/get-insider-radar)
* [`GET /api/v1/health`](https://docs.0xinsider.com/api-reference/endpoint/health)

The initial contract shipped with Bearer auth, `expand[]`, cursor pagination, prefixed IDs, and rate-limit headers.

**March 25, 2026**

Numeric precision standardized

Money values and scores are truncated to 2 decimal places across V1 responses.

Prices and rates are truncated to 4 decimal places.


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