Edge Hunter upcoming boards drop their 3,000-row limit; only the size limit remains
GET /api/v1/edge-hunter now reports board_upcoming_status: "capacity_limited" for a cached upcoming board only when the board reaches its 5,000,000-byte limit. A busy soccer week can now carry about 1,100 matches before that happens, up from 1,000.Before this change, a cached upcoming board was also cut at 3,000 rows, which the soccer board was close to reaching on a full weekend.Backward compatible.What to change: Nothing. Keep reading capacity_limited as an intentionally bounded list, not a complete schedule.Untraded sports markets far from kickoff refresh every 3 days; snapshots can read stale
GET /api/v1/market/{condition_id}/snapshot and MCP get_market_snapshot now refresh market_data every three days, not every 20 hours, for a sports market with no volume whose kickoff is more than 12.5 hours away or unknown. Between refreshes its market_data.status can read stale, with reason provider_refresh_older_than_24h, for up to two days.Before this change, every open sports market was refreshed at least every 20 hours, so market_data.status for these markets stayed fresh under its 24-hour bound.- A sports market with any volume, past its kickoff, or within 12.5 hours of it keeps the 20-hour refresh. A market inside a kickoff window is still refreshed every 30 minutes.
- The rule for
statusdoes not change:stalemeans the provider data is older thanstale_after_s(86,400 seconds), andas_ofgives the last refresh. - On October 14, 2026, these markets were 72% of open sports markets.
stale between refreshes; it clears at the next refresh, or when the market comes within 12 hours of kickoff.SDK 0.28.0 requires Node.js 22 or newer
@0xinsider/sdk 0.28.0 declares engines.node >=22 and joins each request’s deadline and your signal with AbortSignal.any. On Node.js 22 and later, every method and helper behaves as in 0.27.1.Before this change, the package declared Node.js 18 or newer, though Node.js 18 reached end of life on April 30, 2025, and Node.js 20 on April 30, 2026. The SDK also carried a manual fallback for runtimes without AbortSignal.any.- On Node.js 18 or 20,
npm install @0xinsider/sdk@0.28.0warns withEBADENGINE, and fails when npm’sengine-strictis set. - On a runtime without
AbortSignal.any(Node.js before 18.17, or 20.0 through 20.2), a call that passessignalnow throws aTypeErrorunlesstimeoutMsisnull. - Two error messages that named Node 18+ now name Node 22+.
Scheduled pick previews end when their release time arrives
GET /api/v1/pick-of-the-day now returns scheduled previews only for future release times on the current date. At or after release_at, the preview disappears; the selection can be published or closed without publication.Before this change, an overdue selection could remain visible as a delayed release. Published picks keep their original ledger records, and published picks awaiting readable proof keep their existing retry guidance.Breaking for clients that keep overdue scheduled previews. Response fields, access rules, and ordinary settlement and withdrawal behavior are unchanged.What to change: Remove a scheduled preview when its returned release_at arrives, and use the latest response. Keep honoring returned retry times; a scheduled preview does not guarantee publication.Daily picks can become available more promptly
GET /api/v1/pick-of-the-day can now make daily picks available more promptly when ready. Before this change, some ready selections could remain unavailable longer.Backward compatible. Current and archive response fields and returned retry guidance are unchanged.What to change: Nothing. Continue to honor returned release times and retry guidance.MCP 3.6.1 and SDK 0.27.1 refresh descriptions and correct a response type
@0xinsider/mcp 3.6.1, Remote MCP, and @0xinsider/sdk 0.27.1 refresh Pick of the Day and archive descriptions to match the current API. The SDK also corrects the getMarketHolders result type: total is required, matching a field the API always returns. SDK 0.27.1 is also the first release whose webhook payload types are generated from the OpenAPI webhooks map, under the same names, and it adds the WebhookEventData export, which pairs each event type with its payload.Before this change, some MCP descriptions still named the earlier daily limit, and the SDK treated the holder-list total as optional. The refreshed MCP descriptions state the public daily access: Pro opens 5 selections in total, and Max opens every available daily selection, up to 20.Breaking for TypeScript code that constructs a getMarketHolders result without total. Live API calls, tool names, inputs, response fields, and runtime behavior are unchanged.What to change: Include total in constructed or mocked holder-list results. Refresh a cached Remote MCP tools/list. Update local clients to @0xinsider/mcp 3.6.1 or @0xinsider/sdk 0.27.1 for the refreshed descriptions and type correction.Pick of the Day increases the public daily capacity from 15 to 20
GET /api/v1/pick-of-the-day, its dated reads, and MCP get_pick_of_the_day now support up to 20 active recommendations per date in America/New_York. Max opens all available published recommendations; Pro keeps its allowance of 5, including the designated free selection.Before this change, the public daily capacity and Max allowance were 15. After withdrawals, later additions can now use compatibility pick_rank values through 25, while the date still has at most 20 active recommendations.- Withdrawal gaps do not change existing pick IDs, order, or proof bytes. Use
pick_idfor identity andpublication_orderfor presentation. - The archive keeps the same access rules and excludes withdrawn recommendations. The public ledger retains published commitments.
- A date can have fewer than 20 recommendations. The private feed keeps its independent capacity.
potd-traderv0.4.2 accepts up to 20 daily recommendations and compatibility ranks through 25 for Polymarket and Kalshi. Its default spending limits are unchanged.
pick_rank cannot exceed 20. Stop older potd-trader watchers and upgrade to v0.4.2 before using the expanded slate. Honor the returned access fields, entry authorizations, and your own spending limits.Edge Hunter observations use the original live source clock for freshness
GET /api/v1/edge-hunter?view=observations now accepts coherent provider-live evidence for up to 30 seconds from its original observation time. A website refresh becoming due no longer rejects that evidence on its own.Before this change, the website’s 2-second refresh marker could expire while the provider observation was still within the observation view’s 30-second liveness limit, leaving live cohorts unavailable. First-page holder collection also now gets bounded priority and rotates markets awaiting evidence, so repeated attempts do not always start with the same markets.- The live source must remain valid and within 30 seconds during computation and when cached in-play rows are returned. Snapshot completion, cache reuse, and a missed-refresh grace period do not restart that clock.
- Provider-confirmed live membership has its own original source clock, independent of rendered scores and enrichment. A UI score invalidation or refresh becoming due does not invalidate that separate membership evidence.
- Invalidated provider sources, incomplete or invalid observations, and missing, future-dated, or expired source clocks are not accepted. An in-play snapshot whose live source has expired returns
503witherror.reason: read_model_warminguntil a fresh snapshot is available. - Original holder clocks, holder populations, incomplete-scan reporting, ranked views, and deeper holder completion rules are unchanged. Bounded collection does not guarantee complete coverage; continue to read
degraded,degradation_reasons, andcoverage.
503 read_model_warming with its Retry-After, and check source clocks and coverage before using a small or empty result.Edge Hunter recognizes fresh position reads even when balances stay unchanged
GET /api/v1/edge-hunter now uses a verified complete position observation to date unchanged positions when that observation covers them. This corrects directional measurements on the board, ranked signals, and observations.Before this change, an unchanged position kept the timestamp of its last value change. It could therefore leave directional measurements unknown even after a fresh complete position read.directional_confidence,one_way_holder_count,hedged_holder_count, andone_way_graded_usdcan become available for positions whose freshness is now recognized.directional_rank_scoreand ordering can change when corrected evidence changes the measurements. The ranking calculation is unchanged.- The freshness window and hedge classification are unchanged. Missing, stale, or unclassifiable evidence still remains unknown;
nullnever means zero. - Published picks keep their frozen values.
Edge Hunter keeps ranked board markets covered by live quote subscriptions
GET /api/v1/edge-hunter with view=board now keeps bounded live quote coverage active for its ranked board markets. Requests with selection filters also renew coverage for the rows they return.Before this change, a market could rank on the board without an active quote subscription, leaving outcomes[].current_price and signal.current_price as null unless another surface supplied a verified quote.Responses still read verified caches without making inline CLOB REST requests. A first request for a market without quote coverage can still return null while its first order-book update is pending. Available quotes retain their original ts and retention limit.Backward compatible. The response fields, ranking, and access requirements are unchanged.What to change: Nothing. Continue to accept null quotes and read quote ts separately from ranking as_of.Combo fills fixes intermittent timeouts for open combos filtered by wallet grade
GET /api/v1/combos/fills now uses targeted reads for open combos filtered by wallet grade, such as grades=S,A with result=pending.Before this change, requests with grades=S,A could intermittently time out, especially with result=pending, even when matching fills existed. Adding B to the selection could return results while the S,A request failed.Backward compatible. The parameters, pagination, and response fields are unchanged.What to change: Nothing.The market holders response always carries total, and the schema now says so
GET /api/v1/market/{condition_id}/holders now documents total as a field every response carries. total is the number of holders that match the request’s filters across every page.Before this change, the OpenAPI document listed total as optional, although the API has always sent it. The response itself does not change.- The OpenAPI document lists
totalin the response’srequiredfields. @0xinsider/sdktypes ittotal: numberinstead oftotal?: numberfrom 0.27.1.- Remote MCP
get_market_holdersliststotalamong the required keys of its output schema.
total changes from a pointer to a value.What to change: Nothing. After you update the SDK or regenerate a client, you can drop any check for a missing total.Market snapshot top_of_book stays available while a streamed book is quiet
GET /api/v1/market/{condition_id}/snapshot now returns a streamed market’s cached book in outcomes[].top_of_book for as long as 0xinsider streams it, however long the book goes without a change.Before this change, top_of_book answered status unavailable with reason cache_miss once a book had gone about 24 seconds without a change, while current_price was still priced from that same book. A polled market with a quiet book answered cache_miss on most reads.- A book that changes often reads as before.
freshness.top_of_bookfollows the outcomes: it isavailablewhenever an outcome’s book is cached.- A book with one side empty still answers
cache_miss, because it has no best bid and ask to report. - The first read of a market outside 0xinsider’s standing set still answers
cache_missand starts streaming that market.
top_of_book is available on more reads.What to change: Nothing.MCP 3.6.0 installs 4 packages instead of 96 and also serves the 2026-07-28 protocol
@0xinsider/mcp 3.6.0 moves to the MCP TypeScript SDK v2 (@modelcontextprotocol/server), so npx -y @0xinsider/mcp installs 4 packages (18 MB) instead of 96 (28 MB). Its stdio server also answers clients that open with the 2026-07-28 MCP revision.Before this change, the package depended on @modelcontextprotocol/sdk 1.x, which pulls in the dependencies of every transport and of OAuth, Express and Hono included, though this server speaks only stdio. A client that opened with 2026-07-28 fell back to the 2025-11-25 initialize handshake.- Every
initializerevision that 3.5.0 accepted,2024-10-07through2025-11-25, negotiates as before. - The 55 tools, 4 prompts and 4 resources keep their names, descriptions, annotations, input schema keywords and results. The server instructions are unchanged.
- Each tool’s
inputSchemanow declares"$schema": "https://json-schema.org/draft/2020-12/schema", the MCP default dialect. It declaredhttp://json-schema.org/draft-07/schema#before. - Tools no longer list
"execution": {"taskSupport": "forbidden"}. An absentexecutionmeans the same thing: the tool cannot run as a task. - A call to a tool name that
tools/listdoes not return now gets a JSON-RPC error with code-32602, the protocol error the MCP specification describes for it. Before, it got a result withisError: trueand the textMCP error -32602: Tool <name> not found. - SDK error messages drop the
MCP error -32602:prefix. An input validation message now names the field first, as inInput validation error: Invalid arguments for tool get_trader: address: Invalid input: expected string, received undefined, and an unknown resource readsResource not found: <uri>.
tools/list does not return and reads the answer as a tool result, or that matches SDK error text.What to change: Nothing if your client calls only the tools tools/list returns. Otherwise, handle the -32602 JSON-RPC error for an unknown tool, and match error codes rather than message text. Update to 3.6.0 or later for the smaller install.MCP 3.5.0 adds 10 read tools, max_age_s on get_trader, and trust on get_market_snapshot
@0xinsider/mcp 3.5.0 and Remote MCP add 10 tools, one for each /api/v1 read that had no tool. get_trader now takes max_age_s, and get_market_snapshot takes expand: ["trust"].Before this change, these reads and both parameters were REST-only. An agent on MCP could not reach them, and nothing listed which reads MCP left out or why.- Traders:
get_trader_contextreads the trader context object,get_trader_categoriesthe win record in each category, andget_trader_grade_atthe grade recorded at a past instant. - Markets:
get_market_holderslists the S, A and B graded holders withmarket,scanandtotalsbeside the page.get_market_candlesreads daily or weekly price candles. - Combos, with a Pro or Max key:
get_combo_fills(fills),get_combos_summary(live count) andget_combo(one combo). - Large trades:
get_large_trade_counterparty_executionsandget_large_trade_counterparty_makerspage past the first counterparty page thatget_large_tradeembeds, on the samesnapshot_id. max_age_songet_traderanswers only whendata_quality.statusisfreshanddata_quality.as_ofis no older than the ceiling. Otherwise the call fails with reasonfreshness_ceiling_unsatisfied, and nothing is refreshed to meet it.expand: ["trust"]onget_market_snapshotadds provenance forcurrent_priceandspread_bps.- These reads stay REST-only: discovery, health, the account reads, webhook management, the event stream, export and dataset job polling and downloads, the two
context.mdrenderings, and the whole pick ledger.
tools/list to see the new tools, and update to @0xinsider/mcp 3.5.0 to call them over stdio.A pick's odds_display rounds a half-tick price the way the web app does
odds_display in GET /api/v1/pick-of-the-day, including dated reads, GET /api/v1/pick-of-the-day/archive, and MCP get_pick_of_the_day now rounds the backed price’s decimal value half away from zero. That is the rule the 0xinsider web app uses for every price in cents. A backed price of 0.6615 now reads "66.2c"; it read "66.1c" before.Before this change, the label rounded the price multiplied by 100 as a binary floating-point number. For some prices whose fourth decimal is 5, that product falls just below the half, so the label read 0.1c lower than the web app showed for the same pick.- Only a price whose fourth decimal is 5 can change, and it moves up by 0.1c. Of the 492 picks with a backed price on October 14, 2026, 2 read differently.
- The format does not change: cents to one decimal with a
csuffix, omitted when the price is unknown. backed_pricedoes not change and remains the source value.
backed_price itself should round the decimal value half away from zero to match.Trader scores are republished when they move half a point, so ranking as_of can be older
GET /api/v1/trader/{address}, batch traders, trader context, GET /api/v1/leaderboard and the whale trade endpoints now publish a new score or forecast_score only when the hourly grading pass moves it by 0.5 points or more on its 0-100 scale. A grade change, a change of forecast_evidence, and a score that appears or disappears are still published in the pass that makes them.Before this change, nearly every pass rewrote every graded wallet’s scores for moves of about a tenth of a point, and restamped the ranking data-quality group each time.scoreandforecast_scoreare each within 0.5 points of the latest pass’s value. Leaderboard order uses the published scores.- The
rankinggroup’sas_ofis when the published scores were last written. For a wallet whose scores hold still it can be several hours old, anddata_quality.as_oftakes the oldest group. max_age_sonGET /api/v1/trader/{address}compares thatas_of, so a ceiling of a few hours or less can answer409for such a wallet.
max_age_s of a few hours or less and expect the ranking group to be at most one pass old. No field is added, removed, or retyped.What to change: Treat score and forecast_score as current to within half a point. If you send max_age_s, allow for a ranking group as_of that marks the last write, not the last check.OpenAPI describes every webhook payload in a webhooks map
The OpenAPI document now describes every webhook delivery in its top-level
webhooks map: one entry for each of the 16 event types. Each entry documents the signed delivery headers, the envelope (id, type, created_at, data), and the data payload as a schema, with each field’s type, whether it can be null, and what it means.Before this change, the document named the event types but described no payload, and @0xinsider/sdk declared its payload types by hand. Now the backend builds each payload from a typed struct, the API’s contract check holds every struct to its schema, and the SDK generates its payload types from the schemas. The payloads themselves do not change, and neither do the SDK types you import.The payload schemas are in components.schemas: LargeTradeInsertedV2Data, LargeTradesInsertedData, LiveSportsUpdatedData with LiveSportsScoreEntry, TraderSyncedData, LargePositionsUpdatedData, WalletGradeChangedData, SuspiciousTradeFlaggedData, SharpMoneyFlowDetectedData, and one for each export job event. The two spellings of a renamed event share one schema.What to change: Nothing. A client you generate from the document gains these 13 schemas as types.OpenAPI marks 23 always-sent fields as required, and SDK 0.27.0 stops marking them optional
The OpenAPI document now lists in
required 23 response fields that the API sends on every response. @0xinsider/sdk 0.27.0 types them without ?.Before this change, the document left these fields out of required, so the SDK typed them field?: T although no response omits them. The responses themselves do not change.GET /api/v1/markets/explore:freshnessandscore_componentson each market.GET /api/v1/pick-of-the-day/archive:pick_rankon each pick, andstake_usdandseriesinhit_rate.- Market intel, its batch form, and smart money flows:
large_trade_countinsmart_moneyandsharp_money. GET /api/v1/trader/{address}:strategy.strategy_typewhenstrategyis present.GET /api/v1/health:status,db,cache, andsubsystemsindata.- Trader export snapshot: the 7 keys of
large_export_policy.v1_async. - Report snapshots:
completeness.covered_days_with_large_trade_activity. - Remote MCP:
idon a JSON-RPC error, which isnullwhen the request had no readableid.
monthly_quota.unavailable_reasonis removed fromGET /api/v1/usage. The entry of October 1, 2026 announced it, but this route has never sent it. When billing needs reconciliation,pay_as_you_goisfalse.- The remote MCP
200response documents the optionalerror.data, as the MCP error response already did. The server omits it today. - The webhook list response’s
next_cursorandtotalare omitted when they have no value. They were described asnull.
monthly_quota.unavailable_reason from the SDK types, and for Go code generated from the document, where the 23 fields change from pointers to values.What to change: Remove reads of monthly_quota.unavailable_reason. After you update the SDK or regenerate a client, you can drop undefined checks on the 23 fields. Otherwise nothing.A withdrawn pick no longer takes one of Pro's four nonfree daily picks
GET /api/v1/pick-of-the-day, including dated reads, GET /api/v1/pick-of-the-day/archive, and MCP get_pick_of_the_day now skip withdrawn picks when they count the four nonfree selections a Pro credential opens. Pro still opens the designated free selection and the first 4 nonfree selections in publication order.Before this change, a withdrawn pick was left out of every read but still took one of the four places. On a day when one of the first four nonfree picks was withdrawn, a Pro credential received three nonfree picks, and the next one stayed in locked_picks with required_tier: "max".- After a withdrawal, the next nonfree pick in publication order opens to Pro credentials: it moves from
locked_pickstopicks, or toscheduled_picksif it has not published yet. - A withdrawn pick keeps the access it had, and no pick a Pro credential could open closes. Max and free access do not change.
- No pick published so far changes access: the one pick withdrawn before October 14, 2026 was a free selection.
locked_picks should expect a locked rank to open after a withdrawal.Market snapshot current_price is the price Polymarket shows, not a wide book's middle
GET /api/v1/market/{condition_id}/snapshot now sets outcomes[].current_price to the price Polymarket shows: the midpoint of the cached best bid and ask when they are at most $0.10 apart, otherwise the outcome’s last trade price. SDK getMarketSnapshot, MCP get_market_snapshot, and Market context as Markdown carry the same value.Before this change, current_price was the midpoint of the cached bid and ask however far apart they were. A thin book bidding $0.02 and asking $0.98 returned 0.5, a price that neither Polymarket nor any 0xinsider page showed.- A book at most $0.10 wide returns the same midpoint as before.
- A wider book returns the outcome’s last trade price when 0xinsider has one cached, and leaves
current_priceout when it does not.top_of_bookstill carries that book’sbest_bid,best_ask, andspread_bps. - With
expand=trust,trust.current_priceiscomputedwhen an outcome has a price, andunavailablewith a reason when a cached book was too wide to price. - The spec now describes
current_priceand bounds it from 0 to 1.
current_price whenever top_of_book has a bid and an ask. The field was already optional, and no field is added, removed, or retyped.What to change: Treat a missing current_price as no price. If you need the middle of a wide book, compute it from top_of_book yourself.SDK 0.26.0 types webhook trade_id as a number and fixed-set fields as literal unions
@0xinsider/sdk 0.26.0 types trade_id in the suspicious_trade_flagged and insider_radar_flag_raised webhook payloads as a number, the JSON number the API sends. Fields the API fills from a fixed set are now literal unions instead of string.Before this change, the SDK typed trade_id as a string, so event.data.trade_id === storedId with a string id compiled and never matched. The API has sent a number since the event shipped on June 21, 2026; the wire does not change.track:"whale" | "fresh_conviction" | "sliced_position".side(suspicious_trade_flagged) anddominant_side(sharp_money_flow_detected):"yes" | "no".direction(wallet_grade_changed):"upgrade" | "downgrade".old_grade,new_gradeandgrade_floor:Grade,"S" | "A" | "B" | "C" | "D" | "F".
trade_id as a string or compares a narrowed field with a value outside its set. JavaScript callers and the delivered JSON are unchanged.What to change: Compare trade_id with a number, for example event.data.trade_id === Number(storedId), and remove comparisons the compiler now reports as impossible.MCP 3.4.1 accepts an OXINSIDER_API_URL that ends in /api/v1 for every tool
@0xinsider/mcp 3.4.1 reads an OXINSIDER_API_URL that ends in /api/v1 as the same server for every tool, the way @0xinsider/sdk reads its baseUrl. https://api.0xinsider.com/api/v1 and https://api.0xinsider.com now reach the same routes.Before this change, with a base ending in /api/v1, every tool except get_edge_hunter requested a doubled path such as /api/v1/api/v1/trader/{address} and failed with not_found and reason unknown_endpoint. The documented default, the bare origin, was not affected.- Which bases receive your API key is unchanged:
https:, orhttp:for a loopback host only. - A refused
OXINSIDER_API_URLstill stops the server before any request. The message is now the SDK’s, which calls the settingbaseUrl. @0xinsider/sdkadds two exports in its next release.parseRetryAfterStrictreadsRetry-Afterby the RFC 9110 grammar alone and returns whole seconds ornull.isTimeoutAborttells a deadline abort from other aborts.parseRetryAfteris unchanged.
/api/v1, update to @0xinsider/mcp 3.4.1 or later.Live esports in-game scores no longer go backwards or switch teams
scores[].map_score is now always the last in-game pair the provider reported for the game in play. This applies to sports.live_score in GET /api/v1/market/{condition_id}/snapshot, SDK getMarketSnapshot, MCP get_market_snapshot, and to live_sports_updated webhook events. map_score is the kills or rounds in the map being played. The series total stays in score.Before this change, when a provider update omitted the pair, which happens about once a minute in a live game, an API response could fill the gap with an older copy, up to five minutes old. A read could then show a lower count than the read before it. For a series the provider lists in the opposite team order, the two teams’ counts could also be exchanged while the series total was level. The webhook removed map_score for that update and listed scores in changed, and the next update put the pair back.- The pair is kept only within one live game of a series: the same
period, the sameseries_format, and the same seriesscoreon both sides. - A new game, a changed series score, or the end of the series clears it.
map_scoreis then absent until the provider reports a pair for the new game. - No webhook event is sent for an update whose only difference is the missing pair.
- After a game ends, the provider can keep the old
periodfor several minutes.map_scorestays at the last reported pair during that time, which can be short of the game’s final count.
map_score when an event omits it still works.Overwatch series_format and period report the best-of length, not the wins needed
GET /api/v1/games and GET /api/v1/games/{event_slug} now report an Overwatch series’ series_format as its best-of length, such as Bo5, and status.period counts maps against that length, such as 4/5. sports.live_score in a market snapshot and the live_sports_updated webhook carry the same values.Before this change, an Overwatch best-of-5 read series_format Bo3 and period 4/3. Polymarket’s Overwatch score states the maps a team needs to win (first to 3), not the maps in the series, and 0xinsider passed that number through as the length.- An Overwatch series that needs N map wins now reads
Bofollowed by 2N-1:Bo3becomesBo5, andBo4becomesBo7. This matches the(BO5)or(BO7)in the game’stitle. periodkeeps the current map number and changes the number after the slash the same way:5/3becomes5/5.- Every other sport and esports title keeps the values it had.
- A series that ended in the 24 hours before this release can read the earlier values until its cached final score expires, at most 24 hours after its last map.
Bo3 into a best-of-5, remove that step. Otherwise nothing.SDK 0.25.0 types the large_trade_inserted_v2 webhook and exports ClientResponseMeta
@0xinsider/sdk 0.25.0 types every webhook event the API delivers. WEBHOOK_EVENT_TYPES now lists large_trade_inserted_v2, and parseWebhookEvent returns a typed payload for it, for large_trades_inserted, and for trader_synced.Before this change, the list had 15 of the 16 event types in the OpenAPI document, and the typed payloads covered 13. A case on any of the three missing types did not compile, although large_trade_inserted_v2 has been available since September 23, 2026.LargeTradeInsertedV2Eventcarries one trade indata:event_id,whale_alert_id,condition_id,trader_id,wallet,grade(nullfor an ungraded wallet),size_usd,shares,price,side,outcome_index,traded_at, andplatform.size_usd,shares, andpriceare decimal strings, and the event’screated_atis the time the trade filled.LargeTradesInsertedEventandTraderSyncedEventtype the canonical spellings.WhaleTradesInsertedEvent,WhaleTraderSyncedEvent, and their data types are marked deprecated and keep working.ClientResponseMeta, the type ofmetaonApiEnvelopeandApiListEnvelope, is now exported, so you can name it in your own code.WEBHOOK_EVENT_TYPEShas 16 entries. The new name is last, so the index of every earlier entry is unchanged.
switch on event.type that ends in a never check stops compiling until it handles the three added types.What to change: Nothing at run time. Update to SDK 0.25.0 to handle large_trade_inserted_v2 with types, and add the three cases if your switch proves it is exhaustive.Pick of the Day expands public selection coverage
GET /api/v1/pick-of-the-day can now include selections from markets that were previously omitted.Before this change, those markets were skipped. The private scanner feed is unchanged, and 15 is the daily maximum at this release, not a promised count.Backward compatible. Request and response fields are unchanged. Already selected and historical picks keep the rules they were selected under.What to change: Nothing.Trader, leaderboard, and trending P&L add a labeled neg-risk conversion correction
GET /api/v1/trader/{address} now returns pnl.correction when 0xinsider corrects Polymarket’s P&L for a wallet’s neg-risk conversions. The leaderboard and trending wallets return the same object as pnl_correction.Before this change, every P&L field carried Polymarket’s figure. Polymarket misbooks neg-risk conversions that combine NO shares of two or more outcomes, in both directions. It charges part of the cost to inactive placeholder outcomes and never books it as a loss, so the wallet reads too high. Its position records also leave out shares the wallet really got, such as YES shares minted by a conversion, so the wallet reads too low.- The object carries
basis(neg_risk_conversion_v1),amountin USD (negative when Polymarket overstates the wallet, positive when it understates it),realizedandnet_total(Polymarket’s figures plusamount),as_of,markets_measured, andmarkets_excluded. Leaderboard entries omitnet_total. - A market where shares moved in or out of the wallet by direct transfer keeps Polymarket’s figure: it is left out of
amountand counted inmarkets_excluded, which is omitted when there is none. - The amount is published only once every converted market of the wallet is measured and checked for transfers. A market that has not been read yet, or whose re-read has failed three times in a row, holds it back, and the last published amount stays until the set is complete again. A sum under $1 either way publishes no correction.
pnl.correction_pendingistruewhile some of the wallet’s converted markets are still being measured or checked for transfers, so the correction may change, or arrive for a wallet that has none yet. It is omitted otherwise. Right after this release most wallets read pending for a few hours while their first transfer check runs.- It is omitted when no correction is published.
pnl.net_total,pnl.realized,realized_pnl,all_time_pnl_usd, andtrader.pnlon positions and large positions keep Polymarket’s own figures. - Grades and the leaderboard order now use the corrected realized P&L, and the 0xinsider profile shows the corrected total with Polymarket’s figure beside it.
expand=trustaddstrust.pnl_correctionwhen the object is present.context.mdprints the corrected Total and Realized P&L, a correction line with Polymarket’s figures, and a pending line while the correction is pending.- SDK
0.25.0adds thePnlCorrectiontype andpnl.correction_pending. The hosted MCP leaderboard tool declarespnl_correctionin its output schema.
pnl.correction.net_total when it is present and pnl.net_total otherwise, and say the figure may change while pnl.correction_pending is true. Update to SDK 0.25.0 for the typed object.Market snapshot marks the always-null market_type and market_result fields deprecated
GET /api/v1/market/{condition_id}/snapshot now marks market.market_type and market.market_result as deprecated in the OpenAPI spec and the SDK types. Both fields are always null.Before this change, the spec described both as ordinary nullable fields, although neither has ever carried a value on a Polymarket market. market_type read a database column that nothing wrote, and that column is now removed.- Both keys stay in every response, with the value
null. - To tell whether a market has closed or resolved, read
market.statusandmarket.resolved_at.
null.Edge Hunter observations keep conflicting same-page holder rows incomplete
GET /api/v1/edge-hunter?view=observations now leaves holder coverage incomplete when one provider page contains conflicting rows for the same wallet, token, and outcome. The API retains the previously observed partial population instead of publishing one conflicting row as complete.Before this change, equal-share duplicate rows within one page could silently replace earlier price, P&L, or profile values and pass holder completion.- Identical duplicate rows are still counted once.
- Across different provider pages, unchanged holdings can still retain the latest price, P&L, and profile values from the same row.
- Changed shares still prevent completion. Multi-page completion still requires 2 complete scans with matching holdings.
holder_scan_complete, degradation_reasons, and coverage; a retained partial population is not a complete holder population.Pick of the Day supersedes_pick_id is deprecated and always null
GET /api/v1/pick-of-the-day, the archive, the ledger, and the ledger entry mark supersedes_pick_id deprecated. The field is always null, and the OpenAPI document, the TypeScript SDK types, and the Pick of the Day MCP tool now say so.Before this change the documentation described supersedes_pick_id as the ID of the pick a selection replaced. No pick ever carried a value: the field has been null on every response since it was added.Backward compatible. Every response keeps the key, still null, and no other field changes.What to change: Nothing. If your code reads supersedes_pick_id, do not expect it to name a pick. Identify a pick by pick_id.Edge Hunter observations keep their last snapshot through one missed refresh
GET /api/v1/edge-hunter?view=observations now keeps serving the last observation snapshot when one scheduled refresh misses its deadline. That snapshot is served for up to 45 seconds past its usual age limit. For the in_play cohort, this means up to 75 seconds old instead of 30.Before this change, every observation request returned 503 read_model_warming until the next refresh finished, usually for 10 to 15 seconds. On October 11 and 12 the refresh missed its deadline 2 to 13 times an hour.meta.cache_age_sgives the snapshot’s age in seconds, andsnapshot_as_ofgives its completion time.- A second missed refresh in a row, or a snapshot that is missing, still returns
503 read_model_warmingwithRetry-After: 5. - The
boardandsignalsviews are unchanged.
503.What to change: Nothing. If your in_play logic needs data no older than 30 seconds, check meta.cache_age_s before you act on a response.Market snapshot polling renews cached order-book coverage
GET /api/v1/market/{condition_id}/snapshot now renews its request for cached order-book coverage on each open-market read, at most once per minute per market. Continued polling can keep that coverage active beyond the 5-minute hold.Before this change, a hold could expire after 5 minutes even when you kept polling the snapshot. Coverage still depends on available capacity and provider data; read each returned value’s availability and freshness.Backward compatible. Response fields and authentication are unchanged.What to change: Nothing. If you want to retain requested order-book coverage, continue polling at least once a minute and handle unavailable or stale values.Edge Hunter board quotes use verified caches without waiting for provider requests
GET /api/v1/edge-hunter?view=board now reads its quotes from verified display-price and websocket caches without waiting for provider requests. An outcome without a usable cached quote returns current_price: null.Before this change, a missing cached quote could make the board wait for a provider request. Retained quotes keep their original observation clock and existing retention limit; each quote’s availability remains explicit.Backward compatible. Quote fields were already nullable, and the response schema is unchanged.What to change: Nothing if you already handle nullable quotes. Continue reading each quote’s source and clock, and treat null as unavailable rather than as a zero price.Edge Hunter holder completion tolerates refreshed prices on unchanged holdings
GET /api/v1/edge-hunter?view=observations now retains the latest provider economics and profile values when repeated holder rows describe the same wallet, token, outcome, and share quantity.Before this change, a price, P&L, or profile update on a repeated row could prevent holder completion even when its holding was unchanged.- Changed shares, inconsistent token or outcome identities, malformed provider evidence, and invalid cursors still prevent completion. The API still refuses to mark a changing or unverifiable holder population complete.
- Remaining incomplete scans and other snapshot quality reasons stay explicit. This correction does not change admission limits, response fields, SDK/MCP package versions, or the historical archive contract.
holder_scan_complete, degradation_reasons, and coverage; this correction does not promise a healthy or complete snapshot.Edge Hunter observations explain degradation and separate source coverage from page counts
GET /api/v1/edge-hunter?view=observations now returns required degradation_reasons and coverage on every observation page. Admitted incomplete holder scans also attempt bounded completion using the same provider holder population before qualification.Before this change, the shared snapshot’s degraded flag could stay true without a failure terminal in the selected category. Intentional admission limits and a short page also had no separate source, selection, and page counts.- Each reason names its cause and canonical
sport, ornullfor a cause affecting the whole snapshot. Reasons remain attached to the shared all-sports generation through category, cohort, league, and market selection. - On sports and esports responses,
coverage.input_markets,capacity_limited_markets,emitted_observations, andincomplete_holder_marketsdescribe that whole source generation. They are measured counts, not a complete provider census. A legacycategoryvalue that cannot resolve to a sport retains its zero-work empty result; its zero counts and empty reasons do not establish the all-sports snapshot’s health. selected_observationscounts matching cohort and selector records before pagination.returned_observationscounts this page and equalsdata.length.- Intentional
capacity_limitedadmission does not itself setdegraded, andnot_configuredupcoming supply is not a provider failure. Admission limits remain unchanged; pagination cannot recover excluded markets. - Remaining incomplete holder scans and unavailable directional evidence stay explicit. A selected funnel with no failure terminal does not establish that the whole snapshot is healthy.
- Older cached snapshots without the new quality evidence return
503 read_model_warminguntil a refreshed snapshot is ready. HonorRetry-After: 5. - SDK
0.24.0and MCP/CLI runtime3.4.0expose the same typed evidence. The SDK validates its required shape, nonnegative integer counts, and current-page count.
0.24.0 or MCP 3.4.0, read the reasons alongside degraded, and compare source, selected, and returned counts separately. Keep incomplete holder counts and dollar totals scoped to the observed subset; sharp_pct is that subset’s ratio, not a full-population percentage lower bound. Restart pagination when its snapshot expires.Edge Hunter board adds token IDs, its ranking clock, and aggregate category evidence
GET /api/v1/edge-hunter now exposes token IDs and existing ranking evidence directly in the default board. The website’s Max board and the API use the same full projection; the API remains Max-only.Before this change, board quotes omitted their token IDs, and full board signals omitted the ranking timestamp and category evidence already available in ranked records. You had to make another request to resolve a board outcome’s token ID or read the richer ranked view.- Each
outcomes[]item adds required nullabletoken_idand stays in provider order. - Each full
signaladds required nullable backedtoken_id, frozenranked_at, and the existing aggregatecategory_skillobject. The ranking clock stays attached to the served row when quotes refresh. - Category status, coverage, and nullable measurements describe evidence availability. They do not change market admission, row order, grade defaults, or backing measurements.
- The website’s
horizonmaps to APIhorizon_hours. Cards and Table are layouts ofview=board; the advanced views remain available for the former feed capabilities. - All selector, grade, limit, pagination, quote, and warming behavior is retained. This change does not introduce another cohort or ranking model.
- SDK
0.23.0adds the board evidence declarations and corrects 3 nullable reference types:outcomes[].current_price,signal.current_price, androws[].signal. The HTTP fields were already nullable; generated types now reflect that contract. MCP runtime3.3.0exposes the same board evidence.
signal as always present.What to change: Update to SDK 0.23.0 or MCP 3.3.0 for the new typed board evidence. Use returned token IDs rather than resolving them through another snapshot request, handle null token IDs, quotes, and signal, and keep ranking, category, and quote clocks separate. Existing HTTP readers can continue using the board fields they already consume.Edge Hunter adds shared market, sport, esports, and league selection to every view
GET /api/v1/edge-hunter now accepts shared selectors in its board, signals, and observation views. Every view still requires Max, and the 4 retired sports endpoints stay retired.Before this change, the board could only narrow its kickoff horizon, and advanced views could select a canonical category. A category alias such as NFL still means the whole Football bucket; league selection now has its own identity filter.kindselects sports or esports.- The
sports,leagues,market_types,condition_ids,event_slugs, andseries_slugslists accept repeated parameters or comma-separated values. Each list is bounded at 100 values before deduplication; values combine with OR inside one list and AND across axes. Sports, kind, and leagues ignore case; event, series, and market-type identities match exact case. - Each row adds nullable
market_context, with nullable league, series, market-type, andmetadata_updated_atfields when the object is present. The clock dates 0xinsider’s stored metadata update, not a provider observation. Copy these identities rather than inferring them from a title or slug. - League identity also uses recognized provider season series when explicit league metadata is absent; the initial selector rollout left these known identities
null. Explicit sports league identities take precedence, and a series must agree with the canonical sport. Recognized esports game series identify the game, includingcs2for Counter-Strike. - Selected responses echo normalized requested axes under top-level
selection. Cursors and conditional validators bind the selected representation. Unavailable selection metadata returns503 read_model_warmingfor selected reads; missing individual identities remain unknown and cannot match that selected axis. - The league identity correction invalidates existing selected advanced cursors. A valid cursor whose selection or filters no longer match returns
400witherror.reason: cursor_expired; restart from page one. Malformed or invalidly signed cursors keep a generic400 bad_request. - The board also accepts
category,min_grade=S|A|B, andlimit. Defaults remainB, 30 rows, and a 48-hour horizon; board limits clamp to 1 to 30. The advanced views keep their existing limits, cohort requirements, grade restrictions, and horizon behavior. - All three API views require ready snapshots and return
503 read_model_warmingwithRetry-After: 5while unavailable. The observation funnel still accounts for its source/category scope rather than selected league, type, or ID counts. - SDK
0.22.0and MCP/CLI runtime3.2.0support shared selector arrays. Their selected reads use strict query validation so an unsupported selector cannot silently become an unfiltered read. The official agent plugin1.2.0teaches identity discovery and selected views. - The hosted sandbox fixes mismatched example clocks in the board, keeping its horizon consistent with its fictional rows. Hosted MCP now accepts the same shared selector arrays as sandbox REST.
0.22.0 or MCP 3.2.0 to use the new typed selectors, and refresh the official agent plugin to 1.2.0 if you use it. Read provider identities from market_context, use game coverage for discovery, and retain the same normalized selection across cursor pages and conditional reads. Handle null metadata and warming responses.Start a fresh advanced cursor sequence for selected reads from the initial rollout. Keep the returned ETags when you revalidate cached advanced responses.Edge Hunter adds complete ranked signals, observation cohorts, filters, and pagination
GET /api/v1/edge-hunter now includes the former feeds’ complete capabilities under explicit views. The default quoted board stays available with no view parameter. Every view still requires Max, and all 4 old sports endpoints remain retired with 410 endpoint_retired.view=signalsreturns ranked records, nullable backedtoken_id, category-skill evidence, andcategory,min_grade,horizon_hours,limit, andcursorfilters. Its horizon defaults to 12 hours; page size defaults to 20 and clamps to 1 to 100. The S/A/B floor requires a holder at the selected grade or better on the backed side without removing other holders from the pile.view=observationsrequirescohort=wider_holder,in_play, oremerging_pile, and supports category filtering and cursor pagination. It restores verified token IDs, midpoint price marks, observation and holder clocks, provider and directional status, scan completeness,snapshot_as_of,degraded, and per-sportfunnelevidence.- Both advanced responses use
object: "list", addview, and return rows indata. They supportETagandIf-None-Match; a match returns304with no body. Both views require private revalidation. New cursors bind the view, filters, and snapshot; start a fresh walk when migrating. - Signals and observations read warmed snapshots. A source that cannot serve ready evidence returns
503witherror.reason: read_model_warming; honorRetry-Afterrather than interpreting this as an empty complete result. In-play evidence fails closed without fresh provider-live, holder, and directional reads. - SDK
0.21.0adds literal-view result types,edgeHunter.signals(),edgeHunter.observations(), advanced-onlygetConditional(), and shared list/pagination support. MCP and CLI runtime3.1.0expose the same views throughget_edge_hunterandgetEdgeHunter. - The official agent plugin’s
polymarket-sharp-moneyskill, version1.1.0, teaches the advanced views and Max requirement alongside the quoted board. - Generated error types now include
endpoint_retired, and Max guidance names Edge Hunter. Retired routes are removed from the OpenAPI introduction’s conditional GET list.
backed_price is an aggregate market midpoint at observed_at, not a wallet’s executed entry price. Quote, ranking, observation, and holder clocks remain separate; volume is shares. Emerging pile overlaps wider holder and is not holder-arrival history.Compatibility: Valid default-board requests and their data.rows response are unchanged. The advanced views are additive. A known parameter belonging to another view now returns 400; select the matching view before sending its filters.What to change: Update to SDK 0.21.0 or MCP 3.1.0. Migrate former ranked-feed calls to view=signals and former observation calls to view=observations with the required cohort. Read list rows from data, retain the page and evidence fields, and replace old cursors. Stop retrying the retired paths.