Skip to main content
These are the API changelog entries from November 6, 2026, newest first. The newest changes are on the API changelog.
TypeScript SDK: streamFeedResilient no longer gives up on a quiet stream after 10 ends
In the next @0xinsider/sdk release after 0.41.0, streamFeedResilient() counts a connection toward maxReconnects only when it fails to open, or ends within 60 seconds of opening without delivering a frame. A connection that stays open 60 seconds resets the count however it ends, as a delivered frame already did. consumeStreamCheckpointed(), which drives it, behaves the same.Before this change, the count reset only when a frame arrived, and every connection end added one. The server ends each stream connection after its lifetime and on each release, so a filter that matched nothing for hours raised StreamReconnectsExhaustedError after 10 healthy connections in a row, about 140 minutes.
  • The 60-second threshold is exported as STREAM_HEALTHY_CONNECTION_MS.
  • Connections that fail to open or close within 60 seconds still back off from 1 to 30 seconds and still count, so a server that closes at once still ends the loop after maxReconnects.
  • onReconnect reports attempt 1 after a healthy connection.
Backward compatible. No option or signature changes; STREAM_HEALTHY_CONNECTION_MS is a new export.What to change: Nothing. Code that caught StreamReconnectsExhaustedError on a quiet stream and restarted the loop can drop that restart once it runs the new release.
Whale dataset submits no longer reuse a file written in an older row shape
POST /api/v1/datasets/whale-trades now returns an identical ready dataset only when its file was written in the current row shape. If the row shape has changed since that file was written, the submit reserves a new job and answers 202 with a new job_id.Before this change, an identical submit inside the 24-hour retention window always returned the existing job with 200, whatever row shape its file was written in.
  • An identical queued or running job is still returned with 200.
  • The new job counts against the daily and hourly dataset quotas, like any new submit.
  • Files written before this release are not reused, so the first identical submit after it builds a new file.
  • The status, download and cancel responses do not change.
Backward compatible. No field, status code or error is added or removed.What to change: Nothing. After a release that changes the dataset row, expect 202 and a new job_id for a submit that used to return the existing job.
The stream ends each connection cleanly at 14 minutes, before the 15-minute edge cap
GET /api/v1/stream now ends each response 14 minutes after it opens. The body ends cleanly, with no final frame, and a reconnect with Last-Event-ID replays the frames published in between.Before this change the hosting edge cut every connection at 15 minutes with a transport error, for example an HTTP/2 stream error that curl reports as exit code 92.Backward compatible. A backend release already ends open streams the same way, and frames, ids, and replay are unchanged.What to change: Nothing, if your client reconnects when the stream ends, as streamFeedResilient() in @0xinsider/sdk does. A client that treats a clean end as final must reconnect with Last-Event-ID.
market_price_moved reports phase pre_game before kickoff instead of unknown
The market_price_moved webhook and the MarketPriceMoved stream frame now carry phase: pre_game for a move before the game’s scheduled start. The scheduled start is the market’s kickoff, the same time the games endpoints serve as scheduled_at.Before this change, a game had live state only once it went live, so a move before kickoff carried phase: unknown. A subscription with phase: pre_game received almost no moves.
  • game_state stays null, with game_state_unavailable_reason: no_game_state, until the game goes live. Only phase changes.
  • A move on a market with no scheduled start, or after a start that passed before the game went live, still carries phase: unknown.
  • The nba_moneyline_before_tip example delivery now shows phase: pre_game.
Two delivery fixes ship with it. A move that could not be queued for delivery during a database fault is now retried for up to 15 minutes instead of being dropped. A move that reaches the same level again right after its window ends is no longer skipped.Backward compatible. No field is added or removed, and phase keeps its three values.What to change: Nothing. A subscription with phase: pre_game now receives moves before kickoff, and one with phase: any receives every move as before.
Pick of the Day ledger entries drop selected_by, and stats drop selections
GET /api/v1/pick-of-the-day/ledger and GET /api/v1/pick-of-the-day/ledger/{pick_id} no longer return selected_by on any entry. GET /api/v1/pick-of-the-day/stats no longer returns the selections section.Before this change, every ledger entry carried selected_by, and the stats body carried selections[]. Both were added on November 4, 2026.
  • sections=selections on the stats route now returns 400 bad_request with error.param sections, the answer for any unknown section name.
  • The archive and the current picks never returned selected_by, so their responses do not change.
  • hit_rate, every other stats section, and every count are unchanged. selected_by was outside the hashed payload, so no commitment_hash changes and verification is unchanged.
  • The hosted MCP server’s get_pick_of_the_day_stats tool no longer accepts selections in sections. The OpenAPI document drops both fields, and the next @0xinsider/sdk and @0xinsider/mcp releases drop them too.
Breaking for clients that read selected_by or request sections=selections.What to change: Stop reading selected_by and stop requesting selections. Read hit_rate for the full record.
market_price_moved carries book depth and every large trade in the window, and filters on book depth
Three additions to the market_price_moved webhook and the MarketPriceMoved stream frame. Existing fields do not change.Book depth. data.book_depth_within_2c is { bid_usd, ask_usd, book_observed_at }: the dollars resting on bids and asks within 2 cents of the midpoint, from the latest full order book we received while its best bid and ask were the event’s best_bid and best_ask. When we cannot measure it, it is null and book_depth_unavailable_reason says why: no_book, book_changed or band_not_covered.Every large trade. concurrent_sharp_flow.large_trades_in_window counts the market’s large trades in the window at any grade, ungraded wallets included. ranked_large_trades is the part of them by wallets graded B or better.Depth filter. price_move_filters takes an optional min_book_usd_within_2c, a whole number of dollars from 1 to 10,000,000. A subscription with it receives only moves whose book_depth_within_2c is present and reaches that amount on both sides. A value outside the range returns 400 with param: "price_move_filters.min_book_usd_within_2c".The spec adds an example delivery, nba_moneyline_before_tip, to test a receiver with. The new Discord line-move alerts recipe uses it. The TypeScript SDK types the new fields in its next release.What to change: Nothing. A strict decoder that rejects unknown fields must accept the three new fields first.
New market_price_moved webhook and MarketPriceMoved stream frame for line moves on sports and esports markets
A new webhook event, market_price_moved, fires when the price of a sports or esports market moves. The same payload streams as a MarketPriceMoved frame on GET /api/v1/stream. Both are for Pro and Max.We measure each market’s outcome-0 midpoint from the Polymarket CLOB stream over four windows: 60, 120, 300 and 900 seconds. A move counts only on a book with orders on both sides. A one-sided or empty book never fires, so a final game never fires on its settlement.Subscribe. POST /api/v1/webhooks and PATCH /api/v1/webhooks/{id} take a new price_move_filters object. It is required when event_types includes market_price_moved, and refused with 400 (param: "price_move_filters") when it does not:
  • min_move_cents: the threshold, in whole cents from 2 to 50.
  • window_seconds: 60, 120, 300 or 900.
  • Optional condition_id, event_slug, league (slug prefixes such as nba or epl), phase (any, pre_game or in_play) and require_concurrent_sharp_flow.
A PATCH without price_move_filters keeps the stored settings. Removing the event from event_types clears them. The webhook object now carries price_move_filters, which is null unless the event is subscribed.At most one delivery per market per window. A move is reported in whole-cent steps. Inside one window, only a larger move in the same direction fires again, and it carries previous_level_cents. Your threshold matches the one step where previous_level_cents < min_move_cents <= level_cents.Payload. data carries:
  • The market: condition_id, event_slug, market_slug, league, label.
  • The move: direction, from_price, to_price, move_cents, level_cents, previous_level_cents, window_seconds, window_start, observed_at (provider time) and detected_at.
  • The book: best_bid, best_ask and spread_cents.
  • The game: phase and game_state (status, period, clock, live, scores).
  • Ranked-wallet flow over the same window: concurrent_sharp_flow, which counts large trades by wallets graded B or better. detected is true when at least one such trade landed and the net flow points the way the price moved.
  • gap_before, which is true on the first event after we lost the price stream.
Prices are decimal strings at full precision. A value we could not read is null, with game_state_unavailable_reason or concurrent_sharp_flow_unavailable_reason saying why.Stream filters. GET /api/v1/stream takes three new query params for MarketPriceMoved frames: league (comma-separated), min_move_cents (the same threshold rule as the webhook) and window_seconds. While any of them is set, every other frame type is excluded. condition_id also matches the frame’s market.The TypeScript SDK adds MarketPriceMovedEvent, MarketPriceMovedData and the three stream options in its next release.Backward compatible. This adds an event type, a request field, a response field and three stream params. Existing subscriptions and streams are unchanged.What to change: Nothing, unless you want line-move alerts. To receive them, subscribe an endpoint to market_price_moved with price_move_filters, or open the stream with event=MarketPriceMoved.
ITF tennis games name home and away on their markets and sharp money
A market’s side on GET /api/v1/games and GET /api/v1/games/{event_slug}, and each outcome’s side on GET /api/v1/games/{event_slug}/sharp-money, now carry home or away on ITF tennis games where Polymarket designates both players. The MCP tools, the CLI and the TypeScript client that read these routes change with them.Before this change, these games served side: null even though Polymarket names one player home and the other away. Polymarket gives ITF players no provider id, and the side was bound to its player by that id alone. It is now bound by the player’s name when no id exists: the YES outcome must name one player and the NO outcome the other. On November 6, 2026, all 10 scheduled ITF games we checked served null, among them itf-liu13-combs1-2026-11-06, where Polymarket designates Kallista Liu home.
  • side stays null when Polymarket designates neither player, or when the outcome names do not match the two players one each.
  • Only a side that was null can change. Any game whose teams or players Polymarket gives no provider id gains the same binding; ITF tennis is where we measured it.
Backward compatible. side already allowed home, away and null; fewer games now serve null.What to change: Nothing.
Edge Hunter most-held selections keep their 8 places when the default one fills up
GET /api/v1/edge-hunter with view=observations&cohort=wider_holder and admission=most_held_48h or admission=most_held_48h_by_type now fills its places, up to 8 markets a sport (and a type) with at most 4 per event, whatever the size of the default selection. The get_edge_hunter MCP tool reads the same responses.Before this change, both selections could evaluate only the markets the default selection left room for out of 168 a snapshot. When the 48-hour window took in a weekend slate, the default selection grew and the opt-in selections lost places: on November 6, 2026, from 16:33 to 17:04 UTC, admission=most_held_48h_by_type&market_types=totals&category=Soccer went from 7 markets to none, each counted as capacity_limited, and admission=most_held_48h left a Soccer market out the same way.
  • Each opt-in selection now holds up to 168 markets of its own. A market it shares with the default selection is still read once.
  • A market only an opt-in selection takes is still read after every market of the default selection, at most once every 10 minutes, so holder_snapshot_at can still be up to 15 minutes old.
  • The default response does not change.
Backward compatible. No field, value or type changes. An opt-in response can carry more rows and fewer capacity_limited markets at busy times.What to change: Nothing. If you treated a short opt-in response at weekend peaks as a quiet slate, read it again: it now carries the full selection.
Game sharp money names home and away by Polymarket's designation, not by outcome order
GET /api/v1/games/{event_slug}/sharp-money, and the sharp_money object that GET /api/v1/games?expand=sharp_money attaches, now set each outcome’s side to home or away from Polymarket’s own home/away designation of that outcome’s team. The get_game_sharp_money MCP tool, the CLI’s games sharp-money and the TypeScript client’s getGameSharpMoney change with them. This follows the same change to a market’s side on the games routes earlier today.Before this change, side followed the outcome’s place: home was the team on the moneyline’s YES side, or the team listed first. Polymarket lists the away team first in US leagues. On November 6, 2026, nba-bos-cha-2026-11-06 served the Boston Celtics as home while Polymarket designates the Charlotte Hornets home, as it did in all three NBA games we checked that day.
  • An outcome in US leagues now names the other team home. Soccer outcomes keep their sides: Polymarket lists the home team first there.
  • side is null when Polymarket designates neither team home or away. Before, it always held home or away. draw is unchanged.
  • outcomes keep their order, label, money and counts. Only side changes.
Breaking for clients that read side on US-league games, or that expect it never to be null.What to change: Read the team from label and its home or away from side, and handle side: null. A side you stored for a US-league game before this change may name the away team as home.
SDK 0.41.0 and MCP 3.15.0 carry closing lines and closing line value
@0xinsider/sdk 0.41.0 and @0xinsider/mcp 3.15.0 are on npm, and 3.15.0 is in the MCP Registry. They bring the November 4 and November 6 closing line changes to the SDK, the local MCP server and the CLI.Before these releases, 0xinsider market close in 3.14.0 printed Error: Unknown product command, and api list named neither getMarketClose nor getTraderClv. SDK 0.40.0 had no method or type for either read, and no clv on a large trade.
  • CLI: market close <condition_id> reads a market’s closing line, and traders clv <wallet> reads a wallet’s closing line value, with --query from=, to=, min_size= and category=. api call getMarketClose and api call getTraderClv reach the same reads, and api call batchGetMarketClose --body '{"condition_ids":[...]}' reads up to 25 markets’ closes in one request.
  • Local MCP: the tools get_market_close and get_trader_clv, the same as the remote server’s. The local server now lists 71 tools.
  • SDK: getMarketClose(conditionId), batchGetMarketClose({ condition_ids }) and getTraderClv(address, { from, to, min_size, category }), the MarketClose and TraderClv types, and clv on every LargeTrade.
  • Both: the Game.sides and GameMarket.side descriptions match the November 6 home and away change below.
The CLI, MCP and introduction pages now install @0xinsider/mcp@3.15.0.Backward compatible. Every change adds a command, a tool, a method, a type or a field.What to change: Run npm install @0xinsider/sdk@0.41.0. For the CLI and the local MCP server, run npm install --global @0xinsider/mcp@3.15.0, or change a client’s @0xinsider/mcp@3.14.0 argument to @0xinsider/mcp@3.15.0. 0xinsider --version prints 3.15.0 once the update is in place.
Closing lines for up to 25 markets at once, and closing line value on whale dataset rows
POST /api/v1/markets/close/batch is new. It returns the closing line of 1 to 25 sports or esports markets in one request, each item in the shape GET /api/v1/market/{condition_id}/close returns. It takes raw condition_id values or mkt_ ids, keeps your order, and reports a bad, unknown or out-of-scope market as that item’s error while serving the rest. Each id costs one batch item unit.Before this change, reading the closes of many markets took one request per market.Every row of a whale dataset file (GET /api/v1/datasets/whale-trades/{job_id}/download) now carries clv, the same closing line value object a large trade carries on GET /api/v1/large-trades, judged at the manifest’s generation.selected_at. Before this change, a dataset row had no clv, so a backtest had to join each row to its market’s close itself.The TypeScript client (batchGetMarketClose) and the CLI’s api call batchGetMarketClose add the batch route in their next release. The route needs a Pro or Max key.Backward compatible. The route is new, and clv is a new field on the dataset row; no field changed.What to change: Nothing. If your parser refuses unknown fields on a dataset row, allow clv.
Game markets name home and away by Polymarket's designation, not by team order
GET /api/v1/games and GET /api/v1/games/{event_slug} now set a market’s side to home or away from Polymarket’s own home/away designation of the team its YES outcome names. The MCP tools and the TypeScript client that read these routes change with them.Before this change, side followed the team’s place in Polymarket’s team list, which puts the away team first in US leagues. On November 4, 2026, all 55 scheduled NBA, NHL, NFL and college basketball moneylines we checked served the away team as home.
  • A moneyline in US leagues, and in some other basketball, football, baseball, hockey and table tennis leagues, now names the other team home. Soccer, tennis and esports did not change in the games we checked.
  • side is left out when Polymarket designates neither team home or away. Before, it came from the team order.
  • A finished game’s two-outcome moneyline now sends side when its last score was recorded after this change. Before, it sent none.
  • competitors keep Polymarket’s order, which says nothing about home or away. The reference said a team league lists the home side first; that holds in soccer only.
  • Each entry of sports.live_score.scores on GET /api/v1/market/{condition_id}/snapshot can carry side, home or away, the same designation. It is left out when Polymarket gives none.
Breaking for clients that read side on US-league games, or that take the first competitor as the home team.What to change: Read home and away from side, never from the order of competitors. A side you stored for a US-league game before this change may name the away team as home.