Added
GET /api/v1/sports-edge-observations, an Insider-tier evidence endpoint for sports opportunities that do not enter the funded Sports Edge slate.Choose one required cohort: wider_holder measures pre-game markets with current graded-holder consensus even when no recent graded whale flow exists, while in_play measures only provider-confirmed live games with fresh holder and directional evidence. Provider event_status is authoritative for in-play classification when present (Live and Paused are in progress; Ended is not), with the legacy score overlay used only when that field is absent. A stale or unavailable provider live-board snapshot also fails in_play closed. Every row has observation_only: true, provider and holder freshness fields, and an explicit directional status. The response includes a per-sport funnel that accounts for every input as an emitted observation or a terminal exclusion reason. capacity_limited records intentional bounded admission and does not by itself mark the snapshot degraded. Directional degradation is cohort-specific: wider_holder can emit a row with directional_status: "unavailable", while in_play fails that candidate closed under in_play_directional_unavailable.Omit category to evaluate all 14 observation sports. Board reads use bounded fair waves, and cold holder admission gives each represented canonical sport a first-candidate attempt before any sport repeats; terminal gates can still leave a sport with no emitted row. All category scopes share one global observation provider-work admission, so independent cache keys cannot multiply concurrent provider fan-out. That registry includes Table Tennis and Pickleball, classified from provider-confirmed tags and kept separate from Tennis. The table-tennis, table tennis, and pickleball filters resolve through the canonical taxonomy. Those two sports remain outside the 12-sport funded projection.Every 200 response includes required top-level degraded: boolean, the snapshot-wide operational or unknown-completeness verdict. A healthy wider_holder request can reuse a snapshot for about 180 seconds; in_play never serves one older than about 30 seconds. Conditional reads use a weak semantic ETag over stable page content, including next_cursor and excluding request-specific meta. Malformed typed query values return the standard JSON 400 bad_request envelope. Refresh or global-admission contention, or the route’s compute deadline elapsing before a usable cache, universe, or exact raw funded-slate membership result exists, returns 503 with error.reason: "read_model_warming"; later operational failures are represented in a degraded 200 funnel where possible. The public API’s outer 30-second transport timeout remains an empty-body 408, so clients must check the status before parsing JSON. It does not change or feed GET /api/v1/sports-edge-signals, Pick of the Day, or any order executor. Promotion remains closed until a separate review pre-registers and then satisfies sample-size, independent-event, fee-inclusive-return, uncertainty, and unknown-coverage thresholds.GET /api/v1/sports-edge-signals and GET /api/v1/pick-of-the-day can now surface eligible markets for Golf, Formula 1 and NASCAR, NBA Summer League, CFL, and Boxing.Polymarket sends only generic sports metadata for some of these markets. 0xinsider now classifies the provider tags it actually receives - including pga, pga-tour, formula1, nba-summer-league, and cfl - before applying the existing smart-money, calibration, liquidity, and kickoff gates. Racing and Boxing are now admitted canonical buckets.Correction: the earlier version of this entry also named Table Tennis and Pickleball. The final funded release did not admit either sport. They are registered for observation-only evaluation through the endpoint added July 14, and do not feed funded signals or Pick of the Day.No request or response shape changed, and no existing category was renamed. For the funded taxonomy changes in this July 13 release, open markets can adopt the corrected category on a provider refresh; historical rows require a controlled refold and are not implied to have reclassified automatically.Added
GET /api/v1/sports-edge-signals - the ranked list of upcoming pre-game sports markets (moneyline and props) where graded (S/A/B) smart money is piled on one side, computed server-side in one call.Each signal returns the piled side and its CLOB token_id, the pile’s grade distribution (s_count/a_count/b_count), dollar concentration (sharp_pct, backed_sharp_usd), the market’s game_start_time (kickoff), and a grade-weighted conviction_score. Ranking is grade-distribution driven - a market with more top-grade (S/A) traders on the piled side ranks higher - and roughly-50/50 markets with no clear pile are excluded. Bearer + insider tier, ETag-cached, cursor-paginated with a snapshot-pinned cursor.Two changes to
GET /api/v1/pick-of-the-day:- New field
game_started(boolean): true once the backed game’s kickoff has passed, so the snapshotted pre-game price is no longer actionable. Absent for a legacy pick with no stored kickoff (treat as not-started). Additive and optional - existing clients are unaffected. Separately, theis_lockeddescription was corrected: it is a pre-release embargo flag (effectively always false on a served pick), not a “kicked off” signal - usegame_startedfor kickoff. - Behavior change (non-breaking): the endpoint now returns
404when today has no published pick yet, instead of serving the most recent prior day’s (often already-settled) pick. The response shape is unchanged and404was already a documented response; this conforms the endpoint to its “today’s Pick of the Day” contract so an automated consumer never acts on a finished game. Prior picks stay available through the archive endpoint.
Sandbox / test-mode API keys (
oxi_sk_test_...) are removed. The API now has a single key class: oxi_sk_live_..., sent as Authorization: Bearer oxi_sk_live_..., which requires an active Insider subscription and always returns live data.Any request still authenticating with an oxi_sk_test_... key will fail. Generate a live key from your account’s API keys page and switch clients over before this lands. There is no fixture/deterministic-data mode - every request now reads live data.Two behavior changes to
GET /api/v1/pick-of-the-day and its archive. No fields were added, removed, or retyped - existing clients are unaffected - but two value semantics changed:release_atis now a fixed daily instant: 19:00 Europe/Berlin (19:00 CEST in summer, 19:00 CET in winter), every day, instead of a kickoff-relative time that moved with whichever game was picked.next_drop_deadlinecounts down to the same fixed instant. If no candidate qualifies at the release slot, the selector keeps retrying every 15 minutes until one does (or the day’s eligible-kickoff window closes), so on a thin day the actual publish can trailrelease_atby minutes to hours.- The pick can now be any sport or prop bet. The candidate pool evaluates every sport category with real smart-money flow that day - soccer, tennis, baseball, basketball, hockey, MMA, cricket, golf, and esports, including prop markets such as totals, spreads, and exact scores - instead of only whatever survived a global hot-markets ranking (which one surging sport could monopolize). Expect
categoryvalues beyondSoccerin the archive going forward. Selection guardrails and the ranking metric are unchanged.
Each whale trade (
GET /api/v1/whale-trades, /whale-trades/history, /whale-trades/{id}) now returns the traded outcome (the provider outcome label - which leg the trade was on, e.g. Yes/No/team) and its per-outcome Polymarket CLOB token_id, alongside the existing side (BUY/SELL, unchanged). Previously only BUY/SELL was exposed, so you could not tell which outcome a whale trade was on, or get that outcome’s on-chain token id.outcome is null only for a multi-outcome or unsynced market with no stored label; a Kalshi trade carries its provider label here (only token_id is null for Kalshi, since there is no CLOB token). Both fields are additive and nullable, so existing clients are unaffected.Reads that expose an outcome, side, or net-flow direction now also return a per-outcome Polymarket CLOB
token_id, so you can go straight from a YES/NO/outcome label to its on-chain ERC1155 asset id without a second lookup. Use it for order placement, per-token price history, and on-chain reconciliation.The value is a decimal string for a synced Polymarket market and null when unavailable (for example Kalshi markets, or markets that have not synced yet). It is always present and never in a required set, so the change is purely additive and safe for existing clients.The endpoints that gained it:GET /api/v1/positions:token_idalongsideside.GET /api/v1/large-positions:token_idalongsideoutcome_label.GET /api/v1/market/{condition_id}/intelandPOST /api/v1/markets/intel/batch:token_idonsmart_money(alongsidedirection) and on everysmart_money.top_positionsentry.GET /api/v1/markets/smart-money-flows:token_idonsmart_money, alongsidedirection.GET /api/v1/trader/{address}/position-timelineandGET /api/v1/traders/{trader}/position-timeline:token_idalongsideoutcome_side.GET /api/v1/markets/explore:token_id_yesandtoken_id_noalongsideoutcome_yes/outcome_no. These are CLOB token ids (decimal strings), distinct from the integeroutcome_yes_provider_id/outcome_no_provider_idGamma ids.GET /api/v1/reports/daily,weekly, andmonthly:token_idon everytop_whale_tradesentry.
GET /api/v1/pick-of-the-day/archive now returns a hit_rate.series array — the cumulative track record of the Pick of the Day, ready to chart without recomputing it on the client.Each element is one resolved (win or loss) pick, in ascending pick_date order, and carries:date— the pick’s publish date (YYYY-MM-DD).net_profit_usd— the running cumulative profit of a $100 stake on every resolved, priced pick through that date.hit_rate_pct— the running hit rate (wins / decided) through that date, to one decimal.
hit_rate.net_profit_usd and hit_rate.pct, so a chart of the series always ends exactly on the headline numbers. The array is empty until at least one pick has resolved. Every existing hit_rate field is unchanged — this is purely additive.GET /api/v1/trader/{address} and POST /api/v1/traders/batch now return a curated, documented quant_metrics object when you pass ?expand=quant_metrics, instead of an unconstrained pass-through of internal metrics.When expanded, the object always carries these nine fields, each a number or null (null means insufficient trade history and is never 0):copy_score,smart_score: 0-100 composite scores.smart_scoreblends risk-adjusted return, profit factor, edge consistency, return on capital, equity smoothness, and diversification.copy_scoreis that same base minus penalties for traits that make a strategy hard to replicate (small sample, concentration, oversized position sizing, large single losses, inconsistent edge).sharpe_30d,sharpe_7d: risk-adjusted return over the trailing 30 and 7 days.profit_factor: gross profit divided by gross loss (capped at 1000).edge_consistency: stability of the trader’s edge over time (0-1).sharpe_percentile,pf_percentile,consistency_percentile: cross-sectional ranks versus all traders (0-100).
null. Undocumented internal and experimental metrics that previously leaked through the pass-through are no longer returned.Added
GET /api/v1/markets/smart-money-flows, a ranked discovery feed that answers where smart money is flowing before you know a condition_id.It ranks markets by absolute net flow from S, A, and B grade traders over a 1h, 4h, 24h, or 7d window, with platform, category, min_grade, and direction filters. Pagination uses an opaque cursor anchored to the first page’s as_of, so new whale trades do not reorder later pages. Drill into a single market with GET /api/v1/market/{condition_id}/intel.June 1, 2026
Remote MCP read parity, round-trippable IDs, usage and caching headers, and easier discovery
Remote MCP read parity.
POST /api/v1/mcp now exposes 21 read-only tools through tools/list, covering the public V1 reads: batch reads, history, event replay, webhook reads, reports, market snapshots, and trader exports. Webhook mutations stay REST-only, and the endpoint is tools-only (no resources or prompts).See your usage. Added GET /api/v1/usage, an authenticated peek at your current per-minute limiter window and UTC-day usage. It doesn’t spend primary quota, but has its own 100 reads/minute guard.Cheaper polling, safe retries. Deterministic reads now support ETag / If-None-Match conditional GETs, so an unchanged read returns 304 with no body. Webhook create/update/delete/rotate accept an Idempotency-Key.Easier discovery. Added GET /api/v1 (an API discovery document) and GET /api/v1/openapi.json (a redirect to the canonical OpenAPI spec). Operation IDs are now codegen-friendly, with examples, code samples, and response-header metadata.Round-trippable IDs. Market Intel and Market Snapshot now accept the mkt_... market ID or the raw condition_id. New GET /api/v1/whale-trades/{id} and GET /api/v1/insider-radar/{id} dereference a single wt_... / rf_... record. Non-market prefixes return 400 bad_request.POST /api/v1/mcp now exposes nine read-only tools through tools/list.The new tools are get_positions, get_position_timeline, and explore_markets. Each dispatches to the existing public REST handler, so MCP clients receive the same auth, pagination, and payload contracts as direct REST callers.May 8, 2026
Builder API expansion adds batch, history, events, webhooks, reports, and market snapshots
Added task-shaped builder endpoints for lower-call-count integrations:
POST /api/v1/traders/batchPOST /api/v1/markets/intel/batchGET /api/v1/whale-trades/historyGET /api/v1/events/feed/sinceGET /api/v1/market/{condition_id}/snapshotGET /api/v1/reports/daily,weekly, andmonthlyGET /api/v1/trader/{address}/exportGET /api/v1/webhooksplus webhook create, read, update, delete, verify, and rotate-secret operations
Added TypeScript client guidance for the repo-owned client source in
web/src/lib/api-client.The client source is drift-tested against OpenAPI and handles bearer auth, path params, repeated query params, JSON bodies, and V1 error envelopes. It is not a published npm package yet.GET /api/v1/market/{condition_id}/intel now returns a clearer 400 bad_request when callers pass a prefixed market.id value such as mkt_... instead of the raw condition_id.Use GET /api/v1/markets/search first, then pass the returned condition_id into the Market Intel path.GET /api/v1/trader/{address} now accepts a known trader username in the path in addition to an Ethereum wallet address.Heavy trader fields can be requested with repeated expand query params, and the legacy expand[] form remains supported for existing clients.GET /api/v1/leaderboard now safely returns traders without a classified strategy.Clients should treat strategy_type as nullable for ranked traders without a strategy classification.GET /api/v1/markets/explore no longer returns untitled markets.This tightens the response set to titled, user-facing markets only.GET /api/v1/trader/{address} now returns the canonical realized P&L from the realized_pnl source-of-truth field.The pnl.realized field stopped deriving realized P&L from an inconsistent approximation.Added
GET /api/v1/markets/explore for cursor-paginated market discovery.The endpoint supports category, status, platform, and text filters, plus primary-market injection so grouped events include a main market when one exists.Launched the first public developer API:
GET /api/v1/trader/{address}GET /api/v1/whale-tradesGET /api/v1/leaderboardGET /api/v1/markets/searchGET /api/v1/market/{condition_id}/intelGET /api/v1/insider-radarGET /api/v1/health
expand[], cursor pagination, prefixed IDs, and rate-limit headers.Money values and scores are truncated to 2 decimal places across V1 responses.Prices and rates are truncated to 4 decimal places.