Skip to main content
These are the API changelog entries from October 27 to 28, 2026, newest first. The newest changes are on the API changelog.
Pick of the Day publishes no pick earlier than 4 hours before kickoff
GET /api/v1/pick-of-the-day no longer publishes a pick while its game starts more than 4 hours later. A pick chosen earlier stays in scheduled_picks with release_at set to 4 hours before the current kickoff, and moves if the kickoff moves. Every publication check runs again at that instant, so a pick can still leave the schedule unpublished. A pick still publishes no later than 30 minutes before kickoff, and never before 3:00 AM Eastern.Before this change a pick published as soon as it qualified. On October 28, 2026, one published 16 hours before its game, and over the 30 days before, 246 of 480 picks published more than 4 hours before kickoff.Backward compatible. No field is added, removed, or retyped. 404 pick_not_released can last longer on a day whose first pick waits for its hold.What to change: Nothing, if you schedule reads from release_at and retry_at. If you assumed a qualified pick publishes at once, read the release time from scheduled_picks instead.
Position timeline usdc_notional is documented as shares times price, fees excluded (corrected October 29)
On GET /api/v1/trader/{address}/position-timeline and GET /api/v1/traders/{trader}/position-timeline, the reference now says exactly what usdc_notional is: the fill’s shares times its price, rounded to 6 decimals, with the trading fee excluded.Correction, October 29, 2026. The first version of this entry said that usdc_notional changed on fills recorded from the Polymarket activity feed, and that it had carried Polymarket’s fee-bearing usdcSize. That was wrong for this endpoint. The position timeline reads only fills recorded from the on-chain order log, which were always on this basis: from October 1 to 8, 2026, 0 of 3,391 timeline fills differed from shares times price by more than 1%. No value on this endpoint changed.Backward compatible. Nothing is added, removed, retyped, or changed in value.What to change: Nothing.
Large positions min_grade matches the grade each row shows
GET /api/v1/large-positions now applies min_grade to the trader.grade each row returns, which is the wallet’s current grade. Every row in a filtered response shows a grade at or above the floor.Before this change, min_grade matched the grade stored when the position was last scanned. If the wallet’s grade moved after that scan, a row could be listed under a filter its own trader.grade did not meet, and a wallet just promoted could be left out.On October 28, 2026, 39 of 1,610 stored positions held a grade other than the wallet’s current one. None of them was at or above the $50,000 listing floor, so no served row was affected that day.Backward compatible. No field, parameter, or value changes. Only which rows a min_grade filter returns can differ, and only for a wallet whose grade moved since its last scan.What to change: Nothing.
Edge Hunter wider_holder excludes only what view=signals lists; new signals_as_of
GET /api/v1/edge-hunter?view=observations now excludes from cohort=wider_holder exactly the markets view=signals lists at its widest request (horizon_hours=48, min_grade=B, no selector). Every observations response names that signals snapshot in the new signals_as_of.Before this change, wider_holder excluded every market the signals view considered, before its holder checks. A market that failed those checks left wider_holder as primary_slate_candidate, but view=signals did not list it, so neither view showed it until kickoff. On October 28, 2026, at least 2 of the 9 Basketball markets counted as primary_slate_candidate were in that gap.
  • signals_as_of (date-time or null): the ranked_at of the view=signals snapshot whose markets this snapshot excluded. null means no signals snapshot could be read and no market was excluded. Omitted on an unmappable legacy category.
  • departures[].reason follows view=signals while an entry is open: it becomes primary_slate_candidate when a later snapshot excludes the market, and takes that snapshot’s outcome for the market when one no longer does. departed_at and the reason values are unchanged.
  • A sport’s funnel count of primary_slate_candidate is now at most its number of view=signals rows at the widest request.
  • The SDK’s EdgeHunterObservationsResponse type and the get_edge_hunter MCP output schema carry signals_as_of.
Backward compatible. One field is added; no field is removed or retyped, and the reason values are the same.What to change: Nothing. To match a primary_slate_candidate departure to its signal, read view=signals&horizon_hours=48 and pair it with the observations response whose signals_as_of equals its rows’ ranked_at.
Rust client oxinsider 0.4.0 is on crates.io; install with cargo add oxinsider
The Rust client oxinsider 0.4.0 is published on crates.io. Install it with cargo add oxinsider, and read its API reference on docs.rs.Before this change, the crate had no crates.io release, and you added it from its GitHub repository with a --git install.Backward compatible. The crate’s API is unchanged; only where you install it from is new.What to change: Nothing. To take crates.io releases instead of the repository’s main, replace the git dependency in your Cargo.toml with oxinsider = "0.4".
sync_coverage counts the combo markets a wallet traded; new markets_combo
GET /api/v1/trader/{address}/context now returns position_summary.markets_combo, and position_summary.sync_coverage adds it to the synced, pruned, and unstored markets before dividing by markets_total.Before this change, a wallet that traded combos read below 1.0 even when every market it held was synced. Polymarket counts each combo as one market in markets_total, and no position list includes one. One wallet with all 62 of its markets synced and 67 combos read 0.48.
  • position_summary.markets_combo (integer, always sent): combo markets the wallet traded, as maker or taker. 0 when it traded none. No other count in position_summary includes them.
  • GET /api/v1/trader/{address}/export: completeness.sync_coverage uses the same numerator, so such a wallet can now read complete.
  • The context.md coverage line names them, for example 100% (62 synced plus 67 combo markets, of 129 Polymarket markets traded, every category).
  • The get_trader_context MCP tool and the SDK’s PositionSummary type carry the new field.
Backward compatible. One field is added; no field is removed or retyped.What to change: Nothing. To check a coverage figure, compute (markets_synced + markets_pruned + markets_unstored + markets_combo) / markets_total.
sync_coverage counts new markets of other categories; new markets_unstored
GET /api/v1/trader/{address}/context now returns position_summary.markets_unstored, and position_summary.sync_coverage divides markets_synced plus markets_pruned plus markets_unstored by markets_total.Before this change, a market of another category that a wallet first traded on or after October 26, 2026 was neither stored nor counted. A wallet that kept trading other categories read below 1.0, and its export read partial.
  • position_summary.markets_unstored (integer, always sent): markets of other categories the wallet first traded on or after October 26, 2026. 0xinsider does not store them and counts them as the wallet syncs. 0 when there are none. No other count in position_summary includes them.
  • GET /api/v1/trader/{address}/export: completeness.sync_coverage uses the same numerator.
  • GET /api/v1/trader/{address}: pnl.in_scope.markets_out_of_scope also counts these markets once the wallet’s record is next computed.
  • The context.md coverage line names them, for example 98% (431 synced plus 1794 pruned and 39 not stored outside sports and esports, of 2310 Polymarket markets traded, every category).
  • The get_trader_context MCP tool and the SDK’s PositionSummary type carry the new field.
  • A market of another category that a wallet traded and closed between October 26, 2026 and this change can stay uncounted.
Backward compatible. One field is added; no field is removed or retyped.What to change: Nothing. To check a coverage figure, compute (markets_synced + markets_pruned + markets_unstored) / markets_total.
Large trades: recorded_review_score reads the sports and esports win rate
GET /api/v1/large-trades, GET /api/v1/large-trades/{id} and GET /api/v1/large-trades/history now record recorded_review_score from the wallet’s win rate on sports and esports markets, for every trade recorded after this change. The deprecated /api/v1/whale-trades routes, the large-trade MCP tools, and recorded_signal_score change the same way.Before this change, the win-rate part of recorded_review_score used the wallet’s win rate over every Polymarket market. review_score moved to the sports and esports win rate on October 27.
  • The score’s formula, its size, price, and age parts, and its 0 to 1 scale are unchanged.
  • A trade recorded before this change keeps the value it was recorded with.
  • A wallet with no sports and esports record yet gets the same fixed win-rate part a wallet with no measured win rate got before.
Over the 4,427 large trades of the 7 days before the change, 141 recorded scores would have moved by 0.01 or more and 24 by 0.05 or more.Backward compatible. No field is added, removed, or retyped.What to change: Nothing. For trades recorded after this change, review_score and recorded_review_score differ only by the trade’s age.
sync_coverage counts deleted other-category markets again; new markets_pruned
GET /api/v1/trader/{address}/context now returns position_summary.markets_pruned, and position_summary.sync_coverage divides markets_synced plus markets_pruned by markets_total. A fully synced wallet reads 1.0 again.Before this change, sync_coverage divided only the wallet’s synced sports and esports markets by Polymarket’s count of every market it traded. Since October 27, 2026, a wallet that also traded other markets read below 1.0, and its export read partial.
  • position_summary.markets_pruned (integer, always sent): markets of other categories whose rows 0xinsider deleted, counted when they were deleted. 0 when none were. No other count in position_summary includes them.
  • GET /api/v1/trader/{address}/export: completeness.sync_coverage uses the same numerator, so a fully synced wallet reads complete again. A wallet with nothing synced and no pnl day reads empty, whatever its coverage.
  • The context.md coverage line names both parts, for example 100% (12157 synced plus 575 pruned outside sports and esports, of 12608 Polymarket markets traded, every category).
  • The get_trader_context MCP tool and the SDK’s PositionSummary type carry the new field.
  • A market of another category first traded on or after October 26, 2026 is neither synced nor counted. A wallet that keeps trading other categories reads below 1.0 by those markets.
Backward compatible. One field is added; no field is removed or retyped.What to change: Nothing. To check a coverage figure, compute (markets_synced + markets_pruned) / markets_total.
Trader position totals and unrealized P&L now cover sports and esports markets
GET /api/v1/trader/{address}/context and GET /api/v1/trader/{address} now count only a wallet’s sports and esports markets in its position totals. Since October 27, 2026, 0xinsider keeps no other market of a wallet that holds a sports or esports market.Before this change, these figures counted every Polymarket market the wallet traded, and the spec, the SDK types, and the get_trader_context MCP tool said so.
  • position_summary: markets_synced, markets_resolved, markets_open, unrealized_mtm, cost_basis_locked, resolved_wins, resolved_decided, and resolved_win_rate.
  • pnl.unrealized on the trader.
  • The context.md document: its heading is now Position breakdown (synced sports and esports markets), and its unrealized line reads Unrealized P&L (open sports and esports positions). The realized line leaves out “0 other Polymarket markets” when there are none.
  • Three figures still cover every market the wallet traded, and their descriptions now say so: position_summary.total_realized_pnl, position_summary.synced_realized_pnl, and position_summary.markets_total.
  • position_summary.sync_coverage and GET /api/v1/trader/{address}/export’s completeness.sync_coverage divide sports and esports markets by markets_total. A fully synced wallet that also traded other markets now reads below 1.0, and its export reads partial.
  • A wallet with no sports or esports market can still show older markets of other categories until 0xinsider deletes them.
Backward compatible. No field, type or status changes. The values changed on October 27, 2026; this entry records them and the corrected descriptions.What to change: Read pnl.in_scope.realized_pnl for sports and esports realized P&L, not position_summary.total_realized_pnl. Do not read a sync_coverage below 1.0 as missing sports and esports markets.
An export cut by a deploy restarts within seconds instead of failing after 90 minutes
A trader export or whale dataset job that is running when 0xinsider restarts its backend for a deploy now reads queued again at once, and the next worker starts it again within seconds. GET /api/v1/trader/{address}/export/status and GET /api/v1/datasets/whale-trades/{job_id} show it.Before this change, such a job read running with no progress for up to 90 minutes, then failed with error set to export provider artifact retired without a ready object.
  • A requeued job reads queued with error saying why: export worker restarted; export requeued after a deploy, or worker lease expired; export requeued when a worker stopped without handing the job back. The second case now requeues within a minute of the 30-minute lease lapsing, not up to an hour after it.
  • A deploy restart does not use one of the job’s 3 attempts, so attempt steps back by one when the job reads queued for that reason. The 24-hour expires_at still bounds every job.
  • A job you asked to cancel reads cancelled as the worker shuts down, not after its lease lapses.
  • A reconcile_required job is read back within a minute, not at the next hourly pass. A failed readback still retries an hour later.
Backward compatible. No field, status or type changes, and poll_after_s is unchanged.What to change: Nothing. If your client treated a queued job with an error as failed, keep polling it instead: it is waiting for a worker.
Rounded category-skill, Edge Hunter and Pick of the Day numbers serve a zero as 0, never -0.0
The /api/v1 numbers that 0xinsider rounds to the nearest decimal, rather than truncating, now also serve a zero as 0.0, never -0.0. The MCP tools that return the same data change the same way.Before this change, a small negative value that rounded to zero kept its sign. For example, a category-skill edge_mean of -0.00001 served as -0.0.Backward compatible. -0.0 and 0.0 are equal numbers, and no field or type changes. An Edge Hunter cursor issued before the change still pages the same rows.What to change: Nothing. A guard that hid -0.0 in your client is no longer needed.
Truncated money, share, price and rate fields serve a zero as 0, never -0.0
Every /api/v1 number that 0xinsider truncates to two or four decimals, such as money, share counts, prices and rates, now serves a zero as 0.0, never -0.0. The MCP tools that return the same data change the same way.Before this change, a negative value that truncated to zero kept its sign. For example, GET /api/v1/large-positions served "in_scope_realized_pnl": -0.0 for a wallet whose sports and esports P&L is -$0.000026, and `Intl.NumberFormat` prints that as `-$0.00`.
  • Only the sign of a zero changes. Every other value, and the truncation toward zero, stay as they were.
  • Signed fields can show the change: P&L, unrealized P&L, and share changes such as amount_delta on a position timeline. Prices and rates are never negative.
Backward compatible. -0.0 and 0.0 are equal numbers, and no field or type changes.What to change: Nothing. A guard that hid -$0.00 in your client is no longer needed.
Edge Hunter: a holder read that was never sent reports holder_deadline_unavailable
GET /api/v1/edge-hunter observations now report holder_deadline_unavailable when a market’s holder read was never sent to Polymarket because 0xinsider’s own request capacity ran out, and no earlier read is recent enough to serve.Before this change, that read was reported provider_unavailable, the reason for a read Polymarket failed. On October 27, 47 of 49 failed holder reads in one deployment were reads that never left 0xinsider.
  • provider_unavailable now means only a holder read that failed at Polymarket: a timeout, an error status, a body that could not be read, or a read held back while Polymarket is refusing these requests.
  • The change applies to the funnel terminal counts and to departures[].reason. Expect fewer provider_unavailable and more holder_deadline_unavailable.
  • A market with a recent enough earlier read still serves it, as before, with provider_read_source set to cached.
Backward compatible. No field, value or status is added or removed.What to change: Nothing. If you alert on provider_unavailable as a Polymarket outage, it now counts only reads that failed at Polymarket.
Edge Hunter observations keep a card when one holder read fails
GET /api/v1/edge-hunter observations now keep a market’s row when the latest holder read for it fails and an earlier read is recent enough to serve. The row carries that earlier read under the limits that already applied to a read that did not finish: up to 15 minutes old for wider_holder and emerging_pile, up to 10 minutes for in_play, never a pre-kickoff read on an in_play row.Before this change, one failed read took the card out of data for that snapshot with the funnel reason provider_unavailable, and a wider_holder read listed it in departures.
  • The reused row keeps the earlier read’s holder_snapshot_at, and provider_read_source is cached.
  • provider_unavailable now means the read failed and the market had no earlier read to serve. Expect fewer of them in funnel and departures.
Backward compatible. No field, value or status changes.What to change: Nothing. If you treat provider_read_source: "cached" as fresh, check holder_snapshot_at instead.
Trader export provider observations no longer carry Polymarket's all-time leaderboard figures
In the JSON and NDJSON files from POST /api/v1/trader/{address}/export, export_metadata.provider_observations.rows now holds one row, positions_value: the wallet’s open position value.Before this change the array also held the all row: Polymarket’s all-time leaderboard P&L and volume across every market the wallet traded. 0xinsider wallet figures cover sports and esports markets only, and the day, week and month rows left the file earlier today.
  • rows[].fact takes only the value positions_value. No field of that row changes, and the rest of provider_observations is unchanged.
  • trader.positions_value and the positions_value row still cover every Polymarket market: Polymarket values the whole book in one observation, and no exact sports and esports open value exists. export_metadata.scope_note says so.
  • Files exported before this change keep the all row. A submit without fresh=true can return such a file until it expires, 24 hours after it was queued.
Breaking for clients that read the all row.What to change: Read the wallet’s P&L from trader.product_scope_pnl.realized_pnl, the sports and esports figure its 0xinsider profile shows.
Large trades: review_score reads the wallet's sports and esports win rate
GET /api/v1/large-trades, GET /api/v1/large-trades/{id} and GET /api/v1/large-trades/history now compute review_score from the wallet’s win rate on sports and esports markets, the rate its 0xinsider profile shows. The deprecated /api/v1/whale-trades routes and the large-trade MCP tools change the same way.Before this change, the win-rate part of review_score used the wallet’s win rate over every Polymarket market.
  • The score’s size, price, and age parts and its 0 to 1 scale are unchanged.
  • A wallet with no sports and esports record yet gets the same fixed win-rate part a wallet with no measured win rate got before.
  • recorded_review_score is unchanged. It keeps the value stored at insert, which read the every-market win rate, so it can now differ from review_score by more than the trade’s age.
  • signal_score keeps carrying the same value as review_score.
Over the 4,513 large trades of the 7 days before the change, 157 scores moved by 0.01 or more and 21 by 0.05 or more.Backward compatible. No field is added, removed, or retyped.What to change: Nothing. If you compare review_score with recorded_review_score, expect a gap for wallets that also trade other markets.
Leaderboard and trending wallets carry sports and esports figures only, and their wallet-wide P&L fields are retired
GET /api/v1/leaderboard and GET /api/v1/leaderboard/trending now describe each wallet by its sports and esports record, the figures its 0xinsider profile shows. The get_leaderboard and get_trending_wallets MCP tools change the same way.Before this change, both lists also sent figures that covered every Polymarket market the wallet traded.
  • On the leaderboard, pnl, realized_pnl, pnl_correction and volume are never sent. The wallet’s P&L is in_scope.realized_pnl.
  • On the leaderboard, markets_traded and win_rate keep their names and types and now restate in_scope.markets and in_scope.win_rate. Both are absent for a wallet with no in_scope record yet.
  • On trending wallets, all_time_pnl_usd and pnl_correction are never sent. in_scope_realized_pnl is new: the wallet’s realized P&L on sports and esports markets, in USD, absent until the wallet’s record is computed. The list order, trending_pnl_usd and the window figures do not change.
The retired fields stay in the OpenAPI document with deprecated: true and x-never-sent: true, so generated code still compiles.Breaking for clients that read the retired fields, or that compare markets_traded or win_rate with a wallet-wide figure.What to change: Read the wallet’s P&L from in_scope.realized_pnl on the leaderboard and from in_scope_realized_pnl on trending wallets. Expect lower market counts and a different win rate for wallets that also trade other markets.
Position and large-position traders carry sports and esports figures, and trader.pnl is retired
GET /api/v1/positions and GET /api/v1/large-positions now describe each row’s wallet by its sports and esports record, the figures its 0xinsider profile shows. The get_positions and get_large_positions MCP tools change the same way.Before this change, trader.pnl was Polymarket’s total P&L over every market of the wallet, and trader.win_rate and the market count covered every market too.
  • trader.pnl is never sent. It stays in the OpenAPI document with deprecated: true and x-never-sent: true, so generated code still compiles.
  • trader.in_scope_realized_pnl is new: the wallet’s realized P&L on sports and esports markets, in USD. It is absent until the wallet’s record is computed.
  • trader.win_rate and trader.markets (trader.markets_traded on large positions) keep their names and types and now count sports and esports markets only. Both are absent for a wallet with no record yet.
A consistency=snapshot cursor on positions taken before this change returns its rows in the old shape until it expires, at most 5 minutes later.Breaking for clients that read trader.pnl, or that compare trader.win_rate or the market count with a wallet-wide figure.What to change: Read the wallet’s P&L from trader.in_scope_realized_pnl. Expect lower market counts and a different win rate for wallets that also trade other markets.
The sandbox stops serving the retired trader fields, and the OpenAPI document marks them x-never-sent
The sandbox no longer returns trader fields that production stopped sending. POST /sandbox/api/v1/traders/batch omits pnl.total, pnl.net_total, pnl.realized, pnl.correction, pnl.exact, stats.daily_win_rate, quant_metrics and, with expand=trust, trust.pnl_correction. GET /sandbox/api/v1/trader/{address}?expand=quant_metrics accepts quant_metrics and adds nothing, as production does.Before this change, the sandbox answered these fields with sample values, so a client built against the sandbox read figures the live API never returns.In the OpenAPI document, each of these properties now carries "x-never-sent": true beside deprecated: true. The schemas stay, so code generated from the document still compiles. A deprecated field that is still sent, such as signal_score on large trades, carries no marker.Backward compatible. No production response changes.What to change: Nothing. To skip retired fields in code you generate from the document, filter properties that carry x-never-sent.
The dataset export's trader figures, risk_metrics and duration and hour buckets cover sports and esports markets
In a file from POST /api/v1/trader/{address}/export, the trader figures, risk_metrics and category_performance.by_duration and by_hour_bucket now cover the wallet’s sports and esports markets only, the figures its 0xinsider profile shows.Before this change, these figures covered every Polymarket market the wallet traded, while trades, markets and pnl in the same file held sports and esports markets only.
  • trader.realized_pnl, trader.markets_traded and trader.win_rate come from trader.product_scope_pnl, and trader.pnl_tier is the tier of that realized P&L. All four are null until the record is computed.
  • trader.total_volume is the wallet’s sports and esports trade volume, both sides, the same figure as stats.total_volume on GET /api/v1/trader/{address}.
  • trader.total_pnl, trader.daily_win_rate, trader.biggest_win, trader.total_fees_paid and trader.calibration_edge are always null. No sports and esports figure exists for them. The career fee total stays in trader.pnl_accounting.fees_paid.
  • risk_metrics and the duration and hour buckets are the figures of the wallet’s sports and esports markets. risk_metrics.concentration is the concentration of the wallet’s sports and esports volume across categories.
  • summary (and the position-summary keys that trader repeats), trader.pnl_accounting, trader.unrealized_pnl, trader.positions_value and export_metadata.provider_observations still cover every market of the wallet. export_metadata.scope_note lists which sections cover what.
Breaking for clients that read the five retired trader figures or compare the scoped figures with Polymarket’s wallet-wide figures. No field is removed or retyped, and generation.product_scope stays sports_esports_v1.What to change: Read the wallet’s P&L from trader.product_scope_pnl.realized_pnl. A file whose scope_note does not list risk_metrics was written before this change. A submit without fresh=true can return such a file until it expires, 24 hours after it was queued.
Trader stats cover sports and esports markets, and wallet-wide P&L fields are retired
GET /api/v1/trader/{address}, POST /api/v1/traders/batch, GET /api/v1/trader/{address}/context, its Markdown twin and the get_trader MCP tool now report a wallet’s figures over sports and esports markets only. pnl.in_scope is the wallet’s P&L, and stats comes from the same record.Before this change, pnl.total, pnl.net_total, pnl.realized, pnl.correction and every stats figure covered every Polymarket market the wallet traded, while the 0xinsider profile shows sports and esports markets only.
  • pnl.total, pnl.net_total, pnl.realized, pnl.correction, pnl.exact and stats.daily_win_rate are no longer sent. The OpenAPI document keeps them, marked deprecated, so code generated from it still compiles. With expand=trust, trust.total_pnl, trust.net_total_pnl, trust.realized_pnl and trust.daily_win_rate report not_computed, and trust.pnl_correction is no longer sent.
  • stats.markets_traded is the wallet’s sports and esports market count, pnl.in_scope.markets. stats.win_rate is the share of its decided sports and esports markets it won, pnl.in_scope.win_rate truncated to 4 places. Both are omitted until the record is computed.
  • stats.total_volume and stats.exact.total_volume are the wallet’s sports and esports trade volume, both sides, from its stored trading days. Before this change they were Polymarket’s full-history figure for the whole wallet. They are omitted before the first completed sync and while a stored day is not computed yet, and read 0 for a synced wallet with no trading day.
  • data_quality.field_groups has six groups: sync, sports_record, ranking, leaderboard_rank, volume and positions. sports_record dates pnl.in_scope, stats.markets_traded and stats.win_rate. leaderboard_pnl is removed with pnl.total.
  • pnl.unrealized still covers every open position of the wallet, and the context’s position_summary still covers every synced market. The Markdown document labels both.
Breaking for clients that read the retired pnl fields or stats.daily_win_rate, and for clients that compare stats with Polymarket’s wallet-wide figures. No request fails, and no field changes type.What to change: Read pnl.in_scope.realized_pnl for the wallet’s P&L and check pnl.correction_pending before you treat it as final. For Polymarket’s own wallet-wide figures, read Polymarket’s API.
Trader export provider observations no longer carry the day, week and month leaderboard figures
In the JSON and NDJSON files from POST /api/v1/trader/{address}/export, export_metadata.provider_observations.rows now holds two rows: all, the wallet’s all-time Polymarket leaderboard figures, and positions_value, its open position value.Before this change the array also held day, week and month rows: Polymarket’s leaderboard P&L and volume over the past day, week and month across every market the wallet traded. 0xinsider wallet figures cover sports and esports markets only, so 0xinsider no longer reads those three periods. Their stored values had a median age of 22 days.
  • rows[].fact takes only the values all and positions_value. No field of a remaining row changes, and the rest of provider_observations is unchanged.
  • Files exported before this change keep their five rows.
Breaking for clients that read the day, week or month row.What to change: Stop reading those rows. For the wallet’s sports and esports P&L over a window, add up pnl[].daily_change over the window in the same export, or read GET /api/v1/trader/{address}/pnl.
Trader daily volume counts trade size without fees, as Polymarket counts it
entries[].total_volume on GET /api/v1/trader/{address}/pnl, and pnl[].total_volume and volume_reconciliation.exported_activity_volume in the Pro dataset export, now add up each fill’s size times its price: the measure Polymarket reports as a wallet’s volume.Before this change these figures added up the cash each fill moved. Since April 28, 2026 a taker’s cash includes the trading fee, so a buy counted above its size times price and a sell below it, and a wallet’s volume could read a fraction of a percent above or below Polymarket’s.
  • Trading days from this release use the new measure. Days stored before it keep the earlier measure until they are recomputed.
  • trades[].usdc_size in the export is unchanged: it is still the cash the fill moved, fee included.
  • trader.total_volume is unchanged: it is Polymarket’s own full-history figure.
Backward compatible. No field is added or removed and no type changes. Values move by a fraction of a percent.What to change: Nothing. To compare with the cash a wallet paid or received, add up trades[].usdc_size.
Trader quant_metrics is retired, and the export's quant metrics cover sports and esports
GET /api/v1/trader/{address} and POST /api/v1/traders/batch no longer return quant_metrics. Both still accept expand=quant_metrics, so no request fails, and with expand=trust the entry trust.quant_metrics reports not_computed.Before this change, expand=quant_metrics returned 9 figures over every Polymarket market the wallet traded. 0xinsider wallet figures now cover sports and esports markets only, and 6 of the 9 ranked the wallet against every other wallet across all markets, so they have no sports and esports version.
  • The OpenAPI document keeps Trader.quant_metrics, marked deprecated, so code generated from it still compiles. The SDK types and the get_trader MCP tools describe the same change.
  • The Pro dataset export’s quant_metrics and the ratios in its risk_summary (sharpe_ratio, sortino_ratio, max_drawdown, profit_factor, var_95, calmar_ratio) now come from the wallet’s sports and esports P&L by day. Before this change they covered every market. A wallet whose sports and esports record is not computed yet exports an empty quant_metrics and null ratios.
  • The export’s risk_metrics, summary, and the duration and hour buckets of category_performance still cover every market of the wallet. Its pnl already covers sports and esports markets, as the entry on the export’s daily P&L below describes.
Breaking for clients that read quant_metrics, including copy_score and smart_score. The field was already optional and absent whenever its figures were more than 6 hours old.What to change: Stop requesting expand=quant_metrics. For the wallet’s sports and esports record, read pnl.in_scope; for its P&L by day and drawdown, read GET /api/v1/trader/{address}/pnl.
Trader export snapshot P&L dates and pnl_days count the days the export file carries
GET /api/v1/trader/{address}/export now reports source_range.first_pnl_date, source_range.last_pnl_date and counts.pnl_days from the export file’s pnl section: the wallet’s sports and esports realized P&L by UTC day. They are the file’s export_metadata.pnl_date_from, pnl_date_to and pnl_rows.Before this change, they counted the days of the wallet’s P&L curve across every market, which no longer matched the file after its pnl section moved to sports and esports. For one wallet read on October 27, 2026, the snapshot reported 693 days while the file held 288.
  • source_range.pnl_series_status is new: ready, or pending while 0xinsider has not computed the wallet’s daily series. While it is pending, the dates are null and pnl_days is 0, which then does not mean the wallet has no days. It is the file’s export_metadata.pnl_series_status.
  • completeness.status reads empty for a wallet with no synced market and no day in the file’s pnl section. It used to read partial when the wallet-wide curve had days.
  • reconciliation.exported_activity_volume is unchanged. It is the same figure as the file’s summary.volume_reconciliation.exported_activity_volume.
Backward compatible in shape: no field is removed or retyped, and pnl_series_status is additive. The values of the dates and pnl_days change for every wallet that traded markets outside sports and esports.What to change: Read source_range.pnl_series_status before you read pnl_days. If you size or validate an export file from pnl_days, the count now matches the file’s pnl rows.
The dataset export's daily P&L covers sports and esports markets only
The pnl section of a file from POST /api/v1/trader/{address}/export now holds the wallet’s realized P&L in sports and esports markets, one row per UTC day: a day on which it realized P&L in those markets or traded them. daily_change and pair_profit are the day’s realized P&L, and cumulative_profit and total_pnl its running total, which ends at the sum of the days.Before this change, pnl held the daily changes of Polymarket’s P&L curve for the whole wallet, every market included, so its running total could differ from the wallet’s sports and esports P&L in size and sign.
  • export_metadata.pnl_series_status is new: ready, or pending while 0xinsider has not computed the wallet’s daily series. While it is pending, pnl is empty, and an empty pnl does not mean zero.
  • export_metadata.pnl_freshness_at is new: when the series was computed, null while pending.
  • export_metadata.pnl_realized is new: basis, realized_pnl (the same figure as trader.product_scope_pnl.realized_pnl), dated_pnl (the sum of every day), and undated_pnl, the part no day carries, such as the rebate share. null while pending.
  • markets_traded counts the day’s markets only when every stored fill of that day is in a sports or esports market, and is null otherwise. On a day with realized P&L and no fill, markets_traded and total_volume are 0.
  • summary.volume_reconciliation.exported_activity_volume is unchanged. It is the same figure as GET /api/v1/trader/{address}/export reports, and it is not always the sum of pnl[].total_volume.
Backward compatible in shape: no field is removed or retyped, and the new fields are additive. The values in pnl change for every wallet that trades markets outside sports and esports.What to change: Read export_metadata.pnl_series_status before you read pnl. A file without it was written before this change and still holds the whole-wallet values; a submit without fresh=true can return such a file until it expires, 24 hours after it was queued. To replace pnl rows you stored from an earlier export, submit again with fresh=true.
Grade 90-day forecasting edge and S and A capital floors read sports and esports markets
The forecasting edge over the last 90 days inside grade and score is now measured on the wallet’s resolved sports and esports positions. The capital an S or A grade requires now counts the dollars the wallet put into sports and esports positions.Before this change, the 90-day edge read every market the wallet trades, and the capital requirement read the wallet’s Polymarket trading volume across every market.
  • The lifetime forecasting edge and the Sortino ratio inside the grade still read every market the wallet trades: measured on sports and esports alone, the lifetime edge ranked wallets’ later results worse.
  • stats.total_volume and the other volume fields are unchanged. Only the grade stops reading volume.
  • grade changes wherever it is returned, including large trades, positions and their min_grade filters. On a copy of production from October 26, 574 of 162,572 graded wallets (0.4%) changed letter, 99 of them to or from S, A or B. Another 2,083 wallets, which could not be graded without a volume figure, get their first grade. The share of graded wallets at S, A or B moved from 6.07% to 6.09%.
  • A wallet’s grade and score change at its next grading pass after the release. A wallet whose sports and esports 90-day edge 0xinsider has not computed yet keeps the previous one; computing every wallet takes about two hours after the release.
Backward compatible. Field names, types, allowed values and presence rules are unchanged; what the values measure changes.What to change: Nothing. If you store grades, expect a one-time change for some wallets.
Market holders returns 400 for a page cursor issued before October 2
GET /api/v1/market/{condition_id}/holders now returns 400 with param: "cursor" for a page-only cursor, the format the API stopped issuing on October 2, 2026. Every next_cursor the API has returned since then still works.Before this change the API still accepted a page-only cursor and served the page at its original limit.Breaking for clients that saved a cursor before October 2, 2026, or built one by hand. A cursor continues a live list, so a cursor that old does not resume anything a fresh first page does not show.What to change: Treat cursor as opaque and send back the next_cursor from your previous response. On a 400 with param: "cursor", restart without a cursor.
SDK 0.32.0 removes the old method and type names from the September renames
@0xinsider/sdk 0.32.0 removes nine deprecated methods and 17 deprecated types. They were kept as aliases after the September 2026 renames. Each new name takes the same arguments and returns the same data.
  • The removed methods called the deprecated routes. The new methods call the canonical routes, so a response carries the canonical envelope object: large_trade, suspicious_trade, market_flow and market_flow_batch instead of whale_trade, radar_flag, market_intel and market_intel_batch.
  • call(), list() and paginate() no longer accept the 11 deprecated operation IDs. UNSUPPORTED_OPERATIONS lists each one with the operation to use instead.
  • WebhookEvent still includes the old event types whale_trades_inserted, whale_trader_synced, insider_radar_flag_raised and smart_money_flow_detected, because a subscription made under an old name still receives it. Only the named TypeScript types for them are removed.
  • From the next @0xinsider/mcp release, which compiles this SDK source, 0xinsider market intel and 0xinsider whales list keep working but read the canonical routes, so market intel prints object: "market_flow". 0xinsider api call refuses the deprecated operation IDs.
  • The deprecated routes still answer until their sunset on February 1, 2027. A client that calls them directly, not through the SDK, is unaffected by this release.
Breaking for TypeScript code that uses a removed name: it no longer compiles after the upgrade. A ^0.31 range does not install 0.32.0.What to change: Replace each removed name with the name in the “Use instead” column, and match the canonical object if your code branches on it. To narrow a webhook delivery that uses an old event name, check event.type.
Leaderboard strategy filter lists the 6 current trading styles only
The strategy filter of GET /api/v1/leaderboard and the get_leaderboard MCP tool now list only the 6 current trading styles: two_sided, category_focused, high_activity, diversified, mixed and unclassified.Before this change, the OpenAPI enum, the TypeScript SDK’s LEADERBOARD_STRATEGIES and the MCP input schema also listed the 10 styles the classifier wrote before October 1, 2026: accumulator, algo_trader, arbitrageur, directional, event_driven, market_maker, momentum, scalper, speculator and swing_trader. No wallet has carried one since every wallet was reclassified, so those filters always returned an empty list.
  • The API still accepts the 10 historical values and still returns an empty list for each. Any other unknown value still returns 400 with error.param set to strategy.
  • The SDK types and the MCP tool input schemas list only the 6 current styles. The @0xinsider/mcp stdio package checks its input against that schema, so it refuses a historical value before calling the API.
  • strategy_type in responses only ever holds one of the 6 current styles.
Backward compatible for HTTP clients: every request that worked before returns the same response. Breaking for TypeScript code that passes a historical value to listLeaderboard, which no longer type-checks, and for stdio MCP calls that send one.What to change: Remove the 10 historical values from your code. A filter on one of them never matched a wallet.
Deprecated V1 routes and MCP alias tools are removed on February 1, 2027
The 11 deprecated V1 routes and their 9 MCP alias tools now have a sunset date: 2027-02-01T00:00:00Z. Each route now sends Sunset: Mon, 01 Feb 2027 00:00:00 GMT (RFC 8594) beside its Deprecation header and its Link to the successor. Until that date every alias answers exactly as it does today. From it, a deprecated route returns 410 with error.code endpoint_retired, and the MCP alias tools are removed.Before this change, the aliases had no end date and sent no Sunset header. The OpenAPI document, the MCP tool descriptions and the versioning policy now name the date.Each successor returns the same data. The single-trade and flow successors use their own envelope object (large_trade, suspicious_trade, market_flow, market_flow_batch) where the alias kept the old one (whale_trade, radar_flag, market_intel, market_intel_batch).Backward compatible until 2027-02-01. Breaking from that date for clients that call a deprecated route or MCP alias tool.What to change: Call the route or tool in the “Use instead” column before 2027-02-01, and match the new envelope object if your client branches on it. The Link header with rel="successor-version" on every alias response names the exact URL to call. A client that already calls the canonical names needs no change.