vike

Data API changelog

Every user-visible change to the /v1 REST API, the /mcp server and the bulk Parquet archive — newest first, with the PR or commit behind each one.

This page records changes a caller can see: /v1 REST routes added and removed, MCP tools added and fixed, response fields that appeared or changed meaning, error and rate-limit behaviour, and the auth and metering rules on the bulk Parquet archive. Newest first.

It does not cover the Vike trading platform — that is the Trader changelog — nor the website's own /api/* and HTML routes, nor internal plumbing no key-holder can call.

The API is versioned by path prefix. /v1 is the only version that has ever been published, and, as the marked entries below record, routes have been removed and parameters have started returning 400 inside that prefix rather than behind a new one. Do not assume /v1 is frozen — scan the markers.

⚠ BREAKING marks an entry that required a caller to change something

An entry tagged ⚠ BREAKING removed an endpoint, made a parameter start returning 400, changed the shape of a response, or added a credential requirement where there was none. Everything else is additive, or a fix to an answer that was wrong.

Entries are written from the change that actually landed rather than from probing the deployed API, so a fix is dated when it shipped, not when someone noticed it.

Every entry starts with a tag in brackets, so you can scan for the part you use: the slug of a dataset page when the change is about one dataset (hyperliquid/cohort-metrics, polymarket/markets), otherwise api (REST routes, response shapes, the spec), mcp (the tool server and its auth), archive (the Parquet archive) or limits (rate limits and metering). An entry that touches several datasets takes the general tag.

2026-10

  • [api] 2026-10-24 · These docs are organised around four products — On-chain, Hyperliquid, HL Cohorts and Polymarket, in that order on the start pages, the endpoint index, the guides and the concepts, each product linking its datasets, endpoints and guides. Getting started covers the first file of both archives; Freshness covers all four products and what an answer leaves out; the paging guide walks Polymarket's next_cursor envelope. No route, field or limit changed. Data API

  • [hyperliquid/candles] 2026-10-24 · GET /v1/hyperliquid/ohlcv/latest — the newest 1-minute candle of every symbol that traded in the last hour, in one request, instead of one /ohlcv?limit=1 call per symbol. Optional dex (omitted: every DEX, each row names its own) and market (perp | spot); interval is 1m only. A 429 on /v1/hyperliquid/ohlcv now names it in hint. /ohlcv/latest

  • [api] 2026-10-24 · JSON bodies for the 401 and the 414; request lines up to 16 KB — a missing or invalid key on /v1 or on the archive now gets 401 with the UNAUTHORIZED envelope instead of an HTML page, and a request line over 16 KB gets 414 with code URI_TOO_LONG instead of an HTML page. The limit itself went from 8 KB to 16 KB, so a /v1/polymarket/events page with the documented 100 token_ids plus a cursor (about 8.3 KB) no longer returns 414. Status codes are unchanged. Errors

  • [api] 2026-10-24 · Polymarket and On-chain error texts and descriptions no longer name internals — the 400 texts of the Polymarket routes now start with the route's own name (events requires from_ms, ohlcv requires token_id, archive/url requires date, settlements/bulk requires to_ms > from_ms) instead of a code function name; the coverage notes of /wallets/{address}/first-funder and /wallets/{address}/exchange-usage, the /wallets/discover refresh text and a few route descriptions say the same thing in plain words. Status codes, field names and numbers are unchanged. A client that matches a full 400 text exactly (not the requires … tail) has to adopt the new text. Errors

  • [api] 2026-10-24 · source strings no longer name internal tables — the source and n_wallets_source of /v1/hl-cohorts/heatmap, the source, detail and caveat text of every label_computed block, and the source of /v1/hyperliquid/ohlcv, /ohlcv/export and /symbols/hourly now describe the data in plain words (latest position snapshot, precomputed totals, hourly point-in-time label set, 1h fills rollup) instead of naming the stores behind them. Field names, numbers and meaning are unchanged. The Link successor of a /coins/{symbol}/metrics, /cohort-metrics or /size-breakdown request now names the published /v1/hl-cohorts/symbols/{symbol}/… path. Errors

  • [api] 2026-10-24 · HL Cohorts is its own namespace, /v1/hl-cohorts — the ten cohort-positioning routes are published under /v1/hl-cohorts: /cohorts, /segments, /segments/{cohort}/summary, /segments/{cohort}/history, /heatmap, and under /symbols/{symbol}/ the routes metrics, indices, large-fills, cohort-metrics and size-breakdown. Each runs the same code as before, so the body, credits and limits are those of its old path. The same ten paths under /v1/hyperliquid keep answering, so nothing in a hand-written client has to change; the OpenAPI document and these docs now list only the new prefix for them. A client generated from the OpenAPI document is the exception: it loses the seven operations that were published under /v1/hyperliquid (their paths moved to /v1/hl-cohorts) and gets renamed operationIds for them, so regenerate it before relying on those routes. The /coins/{symbol}/... spellings from before 2026-10-19 exist under /v1/hyperliquid only. Three of the ten, /segments/{cohort}/history, /symbols/{symbol}/indices and /symbols/{symbol}/large-fills, answered before but were hidden from the spec; they are published and documented now. HL Cohorts

  • [api] 2026-10-24 · include=leverage on GET /v1/hl-cohorts/segments/{cohort}/history — adds three ratios to every hourly row: perp_bias = (long − short) / equity, equity_exposure = (long + short) / equity and equity_covered_share, the main-dex notional of the counted wallets over that of the whole cohort. They are unbounded ratios (above 1 is more than 1x of equity) over the native perp account only. All three are null, never 0, for an hour with no stored row, for any hour before 2026-08-11 (leverage.data_from in the response) and for hours rebuilt from fills; perp_bias and equity_exposure are also null when no counted wallet has a positive equity. Any other include value is a 400. Without include the response is unchanged. /segments/{cohort}/history

  • [api] 2026-10-23 · Settlements name the market and the winning outcome — /v1/polymarket/settlements/{condition_id} now fills slug, token_ids and winning_token_id from the full market list, where they used to be empty for most markets, and agrees field for field with /settlements/bulk. Both routes add market_known (false when we have no description of the market), outcomes, winning_outcome and question to every row; existing fields are unchanged. /settlements/{condition_id}

  • [api] 2026-10-23 · /markets/{condition_id} answers for markets outside the recorded set — a market we do not record order books for is answered from Polymarket's full catalog (about 4 million more resolved markets) instead of []. Every row carries source (recorded or catalog); on a catalog row tick_size and neg_risk are null. Only an id neither list knows returns []. /markets/{condition_id}

  • [api] 2026-10-23 · Errors say what to do instead — a 429 on a per-item route names the bulk call that replaces the loop (hint inside the error envelope); an unknown Polymarket parameter or an invalid enum value ends with the likely intended value (did you mean 'query' for 'q'?, Nearest: 5m or 1h); a 422 keeps FastAPI's detail and adds a one-line error. New response headers, bodies unchanged: Deprecation and Link on the coin= alias and the /coins/... paths, X-Vike-Note on an empty answer whose window is before 2026-07-25, X-Vike-Hint on a hot single-item loop. Errors

  • [api] 2026-10-23 · GET /v1/polymarket/settlements/bulk: many settlements per request — the same row as /settlements/{condition_id}, oldest resolution first, up to 5,000 per page (default 5,000) with a next_cursor, filtered by resolution time (from_ms inclusive, to_ms exclusive) and slug_prefix (for example btc-updown-5m-). Walking every settled 5-minute BTC market no longer takes one request per market. Nothing that worked before changed; /v1/polymarket/settlements without a condition id is still a 404. /settlements/bulk

  • [archive] 2026-10-23 · A missing Polymarket archive file now says what exists — the 400 from /v1/polymarket/archive/url keeps its text and adds the assets with files for that stream, the tenors with files for that asset, or the published date range for that selection. /archive/url

  • [api] 2026-10-23 · A 404 on a guessed path says what to call — a 404 on a path that does not exist but is often guessed (wallets/{address}/positions, /candles, top-level /cohort-metrics, bare /settlements) now carries a hint field naming the call that answers it; detail is unchanged. Errors lists them.

  • [api] 2026-10-23 · The events window error points at the daily files — the 400 for a window over 24 hours keeps its text and ends with GET /v1/polymarket/archive/datasets?stream=book_events.

  • [limits] 2026-10-23 · Hyperliquid file links: 20 GB per user per rolling 24 hours — GET /v1/hyperliquid/archive/url answers 429 when the links a user was handed in the last 24 hours, all of the user's keys together, would pass 20 GB. What is counted is the size of each link issued, not the bytes read, and the window rolls; the message says how much was issued. Nothing else about the route changed. /archive/url (#1406)

  • [api] 2026-10-22 · The OpenAPI document is readable without a key — https://vike.io/data/openapi.json serves the /v1 spec with no credential and spends nothing: the same document /v1/openapi.json serves behind the key gate, plus a top-level x-vike-limits block. Every /v1 response names it in a Link header with rel="service-desc", beside rel="service-doc" for these docs, the 401 the edge answers for a missing key included. Route descriptions in the spec no longer carry developer notes. Additive. Schema and spec (#1390, #1392)

  • [archive] 2026-10-22 · Hyperliquid positions files have 19 columns, and the archive has free samples — account_value and pnl_cohort come after liq_progress in every positions file, the daily ones and latest/positions.parquet, which takes them from 17 columns to 19. account_value is the wallet's native perp account value in USD at the start of the row's clock hour (the last snapshot of the previous hour; null when unknown). pnl_cohort is the wallet's realized-PnL cohort at the start of that hour, graded on the fills before it, so one hour earlier than the label /v1/hyperliquid/positions gives the same row in historical mode; unknown when the wallet is ungraded. Every published day was re-issued with the two columns: a file downloaded before this date has 17, and those 17 keep their names, types and order. Separately, GET /v1/hyperliquid/archive/datasets returns samples_base, https://data.vike.io/archive/hl-samples/, which holds a BTC fills sample, a BTC positions sample and a manifest.json, all readable without a key. /archive/datasets (#1386)

  • [archive] 2026-10-21 · Hyperliquid fills and position snapshots as Parquet files, by temporary link — one Parquet file per UTC day for fills (every fill) and positions (every 5-minute snapshot of every open position), from 2026-05-01 (positions from 2026-05-08, a partial first day). GET /v1/hyperliquid/archive/datasets is the index: the days, rows and bytes per file, the snapshots count of each positions day and the column schema. GET /v1/hyperliquid/archive/url?dataset=fills&date=YYYY-MM-DD (or dataset=positions) answers with a link to exactly one file. The link needs no key, is accepted for 300 seconds from the start of a request (a running download is not cut) and answers 403 once expired or altered. No file has a permanent URL, the folder cannot be listed and a direct /archive/venue=hyperliquid/ path is a 404. Nothing that worked before changed: these routes were not published until now. Download the Hyperliquid file archive shows how to fetch a file and read it. (#1354, #1356, #1361)

  • [archive] 2026-10-21 · Position snapshot gaps filled; rebuilt hours are listed in the index — the gaps in the positions files between 2026-05-17 and 2026-10-19 (missing 5-minute snapshots and snapshots with whole wallets missing) were rebuilt from the fills, and the affected day files were replaced: row and snapshot counts of those days are higher than before (snapshots in the index). reconstructed_hours on a day's positions entry lists the rebuilt hours, and reconstructed_lower_match_hours the ones whose replay matched the next real snapshot at 83 to 97 %. Rebuilt rows carry margin_used = 0, liquidation_price = 0 and state_ts = 1970-01-01. Nothing that worked before changed: the new keys are only added to the index. (#1371)

  • [archive] 2026-10-21 · date=latest: the current open positions of every asset as one file — GET /v1/hyperliquid/archive/url?dataset=positions&date=latest links latest/positions.parquet, replaced in place about every 5 minutes (about 30 MB, with the 17 columns of the daily positions file). Download it whole instead of paging /v1/hyperliquid/positions: a ranged read can straddle two versions of the file. latest.positions in /archive/datasets carries its snapshot_ts and generated_at. (#1359)

  • [limits] 2026-10-21 · Hyperliquid file links: the link request is metered, the download is not — GET /v1/hyperliquid/archive/url is an ordinary /v1 call: one credit, one request of the hourly budget, and counted by the per-minute cap. Downloading with the link is recorded as archive_download, spends neither and needs no key. A 403 now exists for an expired or altered link; Errors lists it. (#1361)

  • [api] 2026-10-21 · end without start returns the newest buckets at or before end, on GET /v1/hyperliquid/symbols/{symbol}/cohort-metrics and /symbols/{symbol}/metrics — with no start, an end more than hours behind the newest snapshot (limit on /metrics) returned an empty series: the default window hung off the newest snapshot, so it asked for the span from the newest snapshot minus hours up to end, which holds nothing. It affected the size, tier and pnl_abs axes, pnl with labelBasis=current, and /metrics. The window is now the hours newest hourly buckets at or before end, the same rows as start = end - hours. An end at or after the newest data, a future one included, is the same as no end; an end older than all data still returns an empty series. (#1360)

  • [limits] 2026-10-20 · ⚠ BREAKING · 200 requests per minute per key on /v1 — a sustained rate with a burst of up to 100, counted once per key across every server. Over it, /v1 returns 429 with Retry-After: 1 and a message naming the per-minute cap; the hourly budget (20,000) is unchanged, and MCP and the archive are not subject to the new cap. Every /v1 response now also carries X-RateLimit-Limit and X-RateLimit-Remaining (the hourly budget; no X-RateLimit-Reset, since the window slides). The account page's MCP Calls tab shows each key's last hour against the limit and the last seven days by endpoint. (#1336, #1337, #1338)

  • [api] 2026-10-20 · GET /v1/onchain/wallets/{address}/trace and the MCP tool wallet_trace take direction — out follows the money where it went (each wallet's recipients), in where it came from (its senders), both (the default, and the only behaviour until now) either way, ranked by the two summed. Any other value is a 400. The response echoes direction. Base and HyperEVM discovery (/wallets/discover, wallet_discover) is documented as it behaves: window=all always, 24h–90d while those chains' windows tables are under two days old (refreshed by hand), otherwise a 400.

  • [api] 2026-10-20 · wallet balances price the native coin, answer in under a second, and a tiny min_usd keeps sub-cent holdings — on GET /v1/onchain/wallets/{address}/balances and the MCP tool wallet_token_balances, the ETH / BNB / HYPE row carried usd_value: null and was left out of total_usd; it is now priced and counted (vitalik.eth's total rose by about $21,900). With any min_usd above 0 (the MCP tool's default is 1) only tokens we price are read from the chain, which took vitalik.eth from 17.7 s to 0.5 s; the answer is the same. min_usd is compared with the unrounded value, so min_usd=0.000000000001 now returns holdings worth under half a cent, whose usd_value keeps three significant digits instead of reading 0.0. min_usd=0 still lists every token, priced or not.

  • [hyperliquid/traders-and-leaderboard] 2026-10-19 · ⚠ BREAKING · a Hyperliquid wallet's window is what it REALIZED in it, rows no longer freeze, and the drawdown fields can be null — window (1d, 7d, 30d, all = 365 days) on GET /v1/hyperliquid/leaderboard, /leaderboard/flow-adjusted and /traders, in the metrics block of GET /v1/hyperliquid/wallets/{address}, and in the MCP tools hl_leaderboard, hl_perp_top_traders and hl_wallet, now covers the trades closed in the current UTC day and the N days before it. It covered the trades opened there that had since closed, so a loss on a position opened before the window never showed in it: the 30-day leader of 2026-10-19 read +8.5M, and about −27.6M was realized in those 30 days. Realized PnL, the trade, win and loss counts, win_rate, volume, profit_factor, expectancy and the tags and cohorts derived from them follow the new window; max_win_streak and max_loss_streak still count trades opened in it. A row also froze at its last computation until the wallet traded again, so it kept a trade after its day had left the window (the same leader's row still held one that left ten days earlier); it is now rewritten once a day for every wallet with a trade that left a window. The same release corrects the drawdown fields: max_drawdown_pct was exactly 100.0 for most wallets (a zero equity reading was taken for a total loss) and above 100 for some, and the 1d, 7d and 30d rows carried the lifetime value. It is now taken from the wallet's cleaned equity over the row's own window, with bridge deposits and withdrawals taken out, and max_drawdown_pct, current_drawdown_pct, calmar_ratio and recovery_factor are null, not 0, where the window has too few equity days to say; a client that parses them as numbers has to accept null, which is why this entry is marked breaking. Sorting on them puts null last. The rows were rebuilt in one pass that finished 2026-10-19 20:08 UTC, and the captured example responses on the endpoint pages were refreshed after it; every row now follows the new definition. About 7% of the wallets with more than $100 of equity still read 100.0 for the lifetime drawdown (was 71%) and a quarter of the 500 largest accounts read above 98: money moved between the perp and spot sides is not a bridge flow and still reads as equity leaving, so treat a large drawdown on a large account as an upper bound.

  • [hyperliquid/traders-and-leaderboard] 2026-10-19 · GET /v1/hyperliquid/leaderboard and /leaderboard/flow-adjusted floor at 3 closed trades by default — /leaderboard defaulted to min_trades=0 and the flow board listed any wallet with a trade, so a wallet with one or two lucky trades could head a PnL board. Both now default to min_trades=3 closed trades in the window, the floor /traders has always applied, and totalCount counts the floored set. min_trades=0 is no floor (the flow board then keeps any wallet with at least one trade, as it did), so a caller that wants every wallet sends it. /leaderboard/flow-adjusted takes min_trades, which it did not. The same change reaches the MCP hl_leaderboard tool, whose min_trades default is 3 for both views.

  • [api] 2026-10-19 · the wallet leaderboard hides round-trip hubs; include_hubs=true shows them — GET /v1/onchain/wallets/discover and MCP wallet_discover no longer rank a wallet with $10B or more of volume in the chosen window whose net flow and realized PnL are each within 0.1% of that volume: flash-loan, MEV and router pass-through wallets (the Ethereum all-time #1 was a flash-loan bot with $25.7T of correctly priced volume that enters and leaves within the same transaction). The new optional boolean include_hubs, default false, ranks them again. total still counts them.

  • [api] 2026-10-19 · ⚠ BREAKING · an unknown Hyperliquid wallet is a 400, not a 200 of zeros — GET /v1/hyperliquid/wallets/{address} and /wallets/{address}/trades/summary answered an address we hold nothing for with 200: every figure 0, no metrics, and lifetime.last_fill_ts at 1970-01-01. They now answer 400 naming the address, unbilled, as /v1/polymarket/wallets/{address} does for a wallet with no trades. The summary refuses a wallet with no equity snapshot, open position, trade, fill or ledger event; the trades summary refuses one that never traded (a wallet that has traded and was quiet in the chosen window still gets its zeros). A wallet with only ledger events is answered, with last_fill_ts null where it read 1970. A caller that looped over addresses and read zeros has to handle the 400. The list routes /trades, /fills, /funding, /ledger and /builders are unchanged: an unknown address is an empty page. The same change reaches the MCP hl_wallet tool, which answers it as an error.

  • [api] 2026-10-19 · GET /v1/onchain/tokens/search and MCP token_search return token_address 0x-prefixed — the field came back as bare hex on every chain, while every other token and wallet address in /v1/onchain and the MCP tools is 0x-prefixed lower case. It is the same address with the prefix added. /tokens/{token_address}/holders and /tokens/{token_address}/transfers accept either spelling, so a caller that passes the value on is unaffected; a caller that prepends 0x itself, as the earlier docs suggested, has to test for the prefix first.

  • [mcp] 2026-10-19 · MCP perp_funding no longer lists a halted venue — with symbol it returned every row of the current-funding table, including Coinbase International's last rows (its perpetuals halted 2026-10-01; the rows stay for 90 days) with vol_24h_usd 0, beside live venues. It now lists only venues we still poll for funding whose newest row is under an hour old. Without symbol, the arbitrage ranking reads the same polled venues. A live venue we hold funding but no tickers for (weex, for one) is still listed, with vol_24h_usd 0. The response shape is unchanged; there are fewer rows.

  • [hyperliquid/position-snapshots] 2026-10-19 · GET /v1/hyperliquid/positions and MCP hl_market positions say they are ordered by key, not by size — no behaviour change. Current rows come ordered by wallet, symbol, direction and historical rows by symbol, snapshot_ts, wallet, because the cursor pages on the primary key, so limit=10 is the first ten wallets in address order, not the ten biggest positions. The route, the tool and both docs pages now say so and point to size-breakdown / size_breakdown, positions/symbols / open_interest and cohort-metrics / hl_cohort_metrics for the biggest positions. A size sort is not offered.

  • [mcp] 2026-10-19 · two wallet-provenance tools: wallet_first_funder and wallet_exchange_usage — wallet_first_funder (2 credits) returns the earliest inbound transfers of a wallet as two separate answers, first_native_in (the first plain send of the chain's coin, at least min_native whole coins, default 0.0001) and first_token_in (the first token transfer priced at min_usd dollars or more, default 1), each with the sender, its label, time, transaction hash and amounts; it is the first inbound we hold, not proof of who funded the wallet, and coverage says where each chain's history starts. wallet_exchange_usage (3 credits) returns, over a window (default 365d), the USD a wallet sent to and received from each labelled centralised exchange, with transfer counts, first and last contact and label confidence, plus pattern: "sweeps_to_single_cex" when at least 90% of its outgoing USD went to one exchange over at least three transfers: an observed pattern, not a statement that the address is a deposit address, and the exchange figures are a lower bound. Both serve ethereum, bsc, base and hyperevm, each read from that chain's own tables; a wallet we know nothing about is found: false rather than zeros.

  • [api] 2026-10-19 · GET /v1/onchain/wallets/{address}/first-funder and /exchange-usage — the REST routes for the two tools above, billed at the usual 1 credit per call like every other /v1 route. first-funder takes chain, min_native (whole coins; 0 means no floor) and min_usd; exchange-usage takes chain and window (30d, 90d, 180d, 365d or all). A read that does not finish within 20 seconds is a 400 whose message names the fix (a narrower window on exchange-usage; a retry, or min_native=0 and min_usd=0, on first-funder) rather than a 30-second wait.

  • [api] 2026-10-19 · GET /v1/polymarket/leaderboard and the MCP tool polymarket_leaderboard added — the Polymarket wallet leaderboard: wallets ranked by realized P&L, hit rate, volume or trade count, for all time or over a 24h, 7d or 30d window, optionally inside one category, as an array of rows. The route runs the tool, both read the hourly leaderboard table built from the on-chain trade tape, and each call costs 1 credit. min_resolved defaults to 20 (0 lists every wallet), paging is by offset (0 to 1000, limit at most 50, ties broken on the wallet), and a bad window, sort, category or number is a 400 that names it. Rows carry hit_rate, a volume-weighted fraction that is null where undefined, and hit_rate_ci, its plus-or-minus half-width; the bot and whale tags let a caller drop the automated wallets that top some categories. first_seen is the first trade in a tape that starts on 2026-01-01, and 24h, 7d and 30d can be revised while resolution times are corrected. The polymarket namespace is now 12 routes. Additive; nothing changed on the existing routes.

  • [mcp] 2026-10-19 · alerts_create and alerts_edit take a wallet address — address (one 20-byte EVM address, 0x + 40 hex) and address_role (from, to or any, default any) make an alert fire on a transfer that wallet sent, received or either. Until now an alert could only watch a token above a USD threshold and carried no address. eth and bsc only, one address and one chain per alert; ENS names, entity names and non-EVM addresses are refused with a message instead of being stored. min_value_usd is optional: without it every transfer touching the address matches, dust and unpriced tokens included, and the alert still sends at most one notification per cooldown_minutes and 10 a day. alerts_edit is partial like its other fields: address="" removes the condition, address_role alone moves the existing address, and setting an address replaces any earlier one. alerts_list rows gain address_conditions, a list of {role, address} (empty when none). max_value_usd is documented as what it always was: stored, never applied by the alert checker, which has no upper USD bound.

  • [api] 2026-10-19 · GET /v1/onchain/wallets/{address} keeps answering for ethereum and bsc first, and takes chain — the route shipped earlier today answering for the most recently active of the four chains, so a wallet with one dust transfer on base (the live case: the vitalik.eth address) answered with that dust instead of its ethereum figures. It is back to the more recently active of ethereum and bsc, and base or hyperevm is answered only for a wallet with no priced ethereum/bsc volume. The new optional chain query parameter (ethereum, bsc, base, hyperevm) asks for one chain; an unknown name is a 400. The response's top-level chain field is unchanged. The same change reaches the MCP wallet_summary tool.

  • [mcp] 2026-10-19 · the polymarket_market_detail description matches its answer — it promised current quotes and a smart-money cohort block, and returns neither. The answer is the market's fields, outcomes with their clob_token_ids, volume and liquidity, a price series per outcome, the top 30 holders per side, the last 100 trades with wallets, tape stats and resolution. Quotes are polymarket_orderbook, the cohort is polymarket_smart_money. Only the description changed.

  • [api] 2026-10-19 · the wallet routes and tools serve base and hyperevm — chain=base and chain=hyperevm now answer on /wallets/{address}/transactions, /wallets/{address}/counterparties, /wallets/{address}/pnl, /wallets/compare, /wallets/{address}/trace and POST /labels/batch, each reading that chain's own tables. Before, base was listed in the parameter list of some of these but came back as a 503 or empty, and hyperevm was refused with a 400. The 400 for a name outside the four now reads chain 'x' not supported (use ethereum, bsc, base or hyperevm), where it read chain 'x' not supported (use ethereum, bsc, or base). On /labels/batch the labels and the 30-day flows come from each chain's own tables: bsc has no 30-day flow data, so its four 30-day fields are null, and hyperevm has labels for only a few hundred wallets. GET /wallets/{address} now carries a top-level chain field naming the chain that answered (see the entry above for which chain that is). /wallets/{address}/ens (Ethereum mainnet names), /labels/{address}/provenance (Ethereum) and the MCP alerts_* tools (eth and bsc) are unchanged. The same change reaches the MCP wallet_summary, wallet_transactions, wallet_counterparties, wallet_pnl_history, wallet_compare, wallet_trace and wallet_batch_labels tools.

  • [api] 2026-10-19 · the token routes and tools serve base and hyperevm — chain=base and chain=hyperevm now answer on /tokens/search, /tokens/screener and /tokens/{token_address}/holders, and hyperevm is named in the chain list of /tokens/{token_address}/transfers, which already served it at runtime. Before, base was listed on some of these but came back as a 503 or empty, and hyperevm was refused with a 400. The hyperevm token registry holds about 50 tokens. smart_money_only=true and sort=smart_inflow on /tokens/screener stay ethereum only: any other chain is a 400, as it already was on bsc and base. /tokens/{token_address}/holders scans the whole chain for the token, so the busiest tokens on base take tens of seconds (WETH on base measured about 50 seconds, a hyperevm token about 2). The same change reaches the MCP token_search, token_screener, token_holders and token_transfers tools.

  • [api] 2026-10-19 · GET /v1/onchain/wallets/{address}/balances scans base and hyperevm by default — without chains the route now scans ethereum, bsc, base and hyperevm; it scanned the first two, and base had come back in chain_errors since 2026-09-04. chains_scanned and total_usd cover all four, so a caller that wants the old scope sends chains=ethereum,bsc. On base and hyperevm, symbol, name, balance and usd_value exist only for tokens we map and price (about 170 on base, about 50 on hyperevm); any other token the wallet holds is listed only with min_usd=0 (the default floor of $1 keeps priced tokens only), with its contract address and balance_raw and those four fields null. Native balances (ETH, BNB, HYPE) are listed without a USD value. hyperevm means the HyperEVM chain only: assets in HyperCore (spot or perp accounts) are not included. The same change reaches the MCP wallet_token_balances tool.

  • [api] 2026-10-19 · GET /v1/onchain/wallets/discover serves base and hyperevm, for window=all only — the chain list was ethereum and bsc. base and hyperevm now answer, but only for window=all, because their rolling-window tables are not maintained: 24h, 7d, 30d and 90d there are a 400, and an omitted window resolves to all on those two chains. On ethereum and bsc every window is served and the default stays 30d. The same change reaches the MCP wallet_discover tool.

  • [mcp] 2026-10-19 · 2 new MCP tools: perp_open_interest and perp_long_short — open interest and long/short positioning for one perpetual-futures symbol, read from the venues Vike polls (open interest: Aster, Binance, Bitget, Bybit, Hyperliquid, KuCoin, OKX; long/short: Binance, Bybit, Gate, OKX), 1 credit each like perp_funding. There is no REST route for either. oi_usd is USD notional. A venue silent for over an hour is listed under stale_venues, never summed in, and a symbol with no data returns empty lists and a note, not zeros. Every long/short row carries basis, because the venues count different things: Binance top traders by positions, OKX and Gate top traders by accounts, Bybit all accounts. Coinbase International halted its perpetuals on 2026-10-01 and is not among the venues. See Perps tools.

  • [mcp] 2026-10-19 · 5 new MCP tools over the Polymarket L2 feed: polymarket_tape, polymarket_orderbook, polymarket_market_stats, polymarket_settlement and polymarket_archive — each runs the same query as its /v1/polymarket route (/events, /orderbook, /market_stats, /settlements/{condition_id}, and /archive/datasets plus /archive/url as the two views of polymarket_archive) and costs 1 credit, what the route costs. They take the outcome token id, except polymarket_settlement, which takes the condition id; a condition id passed as a token id is refused by name instead of answering an empty or all-zero result. polymarket_tape pages at most 1,000 events (REST: 50,000). polymarket_archive lists and resolves files and never downloads them, and names the date bounds date_from and date_to where REST says from and to. See Polymarket tools.

  • [mcp] 2026-10-19 · eight new MCP tools put the /v1/hyperliquid routes behind tools/list — hl_cohort_metrics, hl_segments, hl_wallet, hl_wallet_activity, hl_leaderboard, hl_liquidations, hl_market and hl_builders. Until now only hl_perp_top_traders, hl_position_match and hl_ohlcv of the Hyperliquid routes had a tool, so an agent could not read cohort positioning, one wallet's history, the risk-metric leaderboard, liquidations or builder codes. A tool with several routes takes a view (hl_wallet_activity reads fills, funding, ledger or builders); each view runs the query function of the route it mirrors, takes that route's parameters with its defaults and caps, and costs 1 credit, what the route costs. symbol is the instrument parameter and coin is accepted as its old name. A call is refused with an error that names the fix, instead of answering something else, for an unknown view, a missing required input, a parameter the view does not take, or a number over the route's cap. tools/list now returns 39 tools. Additive; no existing tool changed. Units that differ between similar fields (win_rate is a fraction on hl_leaderboard and a percent on hl_perp_top_traders; percent_risk and pct_wallets_in_profit are fractions) are listed on the Hyperliquid tools page.

  • [hyperliquid/traders-and-leaderboard] 2026-10-19 · GET /v1/hyperliquid/traders returns roi_pct and max_drawdown_pct in percent — both came back 100 times too large (multiplied by 100 twice): the top trader of the documented example read roi_pct 1752.226 and max_drawdown_pct 10000.0, and now reads 17.522 and 100.0. roi_pct is the window's realized PnL divided by the wallet's current account value, in percent (12.5 is 12.5%); max_drawdown_pct is account-level and all-time, not per window. win_rate_pct and the other fields were already right. Field names and types are unchanged. A caller that divided by 100 itself has to stop. The same fix reaches the MCP hl_perp_top_traders tool.

  • [onchain/wallet-labels] 2026-10-19 · POST /v1/onchain/labels/batch honours chain, and a missing 30-day flow is null, not 0 — the route accepted chain and ignored it: every address was read from the Ethereum label table. ethereum (the default), bsc and base now each read their own chain's label table and 30-day flow table. The four 30-day fields (net_30d_usd, volume_30d_usd, tx_30d, tokens_30d_count) are null where we hold no flow data for the wallet — every bsc wallet today — and for an address we have no label for (found: false). They were 0, indistinguishable from a wallet that moved nothing, so a caller that summed or averaged them over a batch now gets null and has to skip it. Ethereum wallets that have a flow row keep their figures; a base address now gets its own chain's figures instead of the Ethereum wallet's. The same fix reaches the MCP wallet_batch_labels tool.

  • [api] 2026-10-19 · labels on bsc and base results come from that chain, on /wallets/{address}/counterparties, /wallets/compare, /wallets/{address}/trace and /tokens/{token_address}/holders — all four joined the Ethereum label table onto the result whatever chain said, so a bsc or base address was labelled with whatever Ethereum says about the same 20 bytes. They now join the requested chain's own label table. Ethereum results are unchanged. The same fix reaches the MCP wallet_counterparties, wallet_compare, wallet_trace and token_holders tools.

  • [onchain/token-screener] 2026-10-19 · ⚠ BREAKING · GET /v1/onchain/tokens/screener refuses the smart-money filter off Ethereum — smart_money_only=true and sort=smart_inflow exist for chain=ethereum only. On bsc and base they now return a 400. Before, the Ethereum cohort (wallets with over $100k of realized PnL on Ethereum) was applied to the other chain's activity and the result was presented as that chain's smart money; no such cohort exists there. A caller that sends either on those chains has to drop it or use chain=ethereum. The same fix reaches the MCP token_screener tool.

  • [mcp] 2026-10-19 · MCP wallet_token_balances no longer advertises chains it does not serve — the input-schema description of chains said "default: eth, bsc, base, arbitrum, polygon, optimism". The tool reads ethereum and bsc only, from our own nodes, and scans both by default; any other chain lands in chain_errors, as it does on GET /v1/onchain/wallets/{address}/balances (see the 2026-09-04 entry below). Only the description changed.

  • [api] 2026-10-19 · ⚠ BREAKING on 2026-11-19 · /v1/hyperliquid names the instrument symbol everywhere — the parameter, the paths and the response fields. Requests: symbol= on every route that took coin= (coin= still works; both with different values is a 400), and the paths /symbols/{symbol}/metrics, /cohort-metrics, /size-breakdown, /liquidation-heatmap, /positions/symbols and /symbols/hourly (the /coins/..., /positions/coins and /assets/hourly paths still answer). /ohlcv and /ohlcv/export now accept coin= as well, where it was a 422. Responses: asset and coin become symbol, by_coin and by_asset become by_symbol, coin_count → symbol_count, n_coins → n_symbols, share_of_coin → share_of_symbol, and the assets counts and lists → symbols; /ohlcv's symbol is now the resolved id (@107 for a spot pair) and its separate asset is gone. Until 2026-11-19 every response also carries the old name beside the new one, with the same value; on that date the old names are removed and the /symbols/hourly columns entry asset becomes symbol. Switch parsers to the new names before then. Before this change ?symbol= on the coin routes was silently ignored — an unfiltered 200.

  • [mcp] 2026-10-19 · hl_position_match takes symbol; its matches carry symbol — the input was coin (still accepted), and each match's and the echoed query's coin is now symbol. hl_ohlcv accepts coin too and its result drops the separate asset (its symbol is the resolved id). MCP results carry only the new names.

  • [api] 2026-10-19 · GET /v1/hyperliquid/wallets/{address}/fills and /builders/{builder}/fills page past a fill whose trade_id is above 2^63 — such a page's nextCursor was refused on the next request as malformed (400), so paging stopped there. About 5.1 M fills since 2026-04-02 carry one.

  • [api] 2026-10-19 · GET /v1/onchain/labels/{address}/provenance returns the raw sources it names — the route never matched most of the raw third-party label sources, so every response carried at most one provider source and the heuristic: source_count: 1 for the Binance 14 hot wallet, which four sources name, and 0 for vitalik.eth. The shape is unchanged; sources is longer. The same fix reaches the MCP wallet_label_provenance tool.

  • [api] 2026-10-19 · GET /v1/onchain/wallets/{address}/trace returns one edge per pair of wallets — two expanded wallets that each ranked the other came back as two mirrored edges, so stats.edge_count over-counted (12 for 9 relationships in the documented example) and a node's total_volume_usd depended on the mirrors. Each node's total_volume_usd is now the sum of its edges in the graph. The same fix reaches the MCP wallet_trace tool.

  • [api] 2026-10-19 · GET /v1/hyperliquid/wallets/{address}/trades/summary counts each trade once — every stored version of a still-open trade was counted, inflating trade_count, open_trade_count, net_pnl and the gain and loss statistics: the top 30-day wallet read 619 trades and $27.1M where 445 and $8.44M existed. Field names and shape are unchanged.

  • [mcp] 2026-10-17 · An MCP call with a missing or bad credential is HTTP 401 — it was HTTP 200 with a JSON-RPC error in the body. It is now 401 with WWW-Authenticate: Bearer resource_metadata="https://vike.io/.well-known/oauth-protected-resource", where an OAuth client starts discovery (the MCP authorization spec). The body is the same JSON-RPC error object, code -32000. Parse errors, unknown methods or tools and failed tool calls still arrive at 200; the rate limit stays 429. A client that treated a 200 carrying -32000 as "bad key" has to read the status instead. Errors (#1180)

  • [api] 2026-10-16 · GET /v1/polymarket/wallets/{address} and GET /v1/polymarket/smart_money added — the two Polymarket trader tools that existed only over MCP (polymarket_wallet, polymarket_smart_money) now have REST routes that run the same code, so the two surfaces return the same payload. They read the on-chain trade tape, not the recorded book. The polymarket namespace is now 11 routes (68 across the API). Additive; nothing changed on the nine existing routes.

  • [mcp] 2026-10-16 · ⚠ BREAKING · MCP options_flow, web_search and web_fetch are removed — tools/list now returns 31 tools. options_flow (Deribit call/put flow) had 1 call in the previous 90 days; the two web tools are a proxy to a third-party search service rather than Vike data, and web_fetch fetched arbitrary URLs from our servers. A tools/call for any of the three now returns the unknown-tool error. Nothing replaces them.

  • [api] 2026-10-16 · ⚠ BREAKING · fund_holdings and GET /v1/onchain/funds/holdings are removed — the labelled fund / market-maker / treasury / CEX leaderboard is no longer offered on any surface. The MCP tool is gone from tools/list (34 tools remain), the route answers 404, and the /data dataset page and its panel are gone with it. Callers of the REST route or the tool have to drop the call; nothing replaces it.

  • [onchain/token-transfers] 2026-10-13 · GET /v1/onchain/tokens/{token_address}/transfers returns whole tokens and plain USD — bought, sold, net_tokens, usd_spent, usd_received and net_usd came back 1,000,000 times too large; only the *_fmt strings beside them were right. They are now divided once, on this route and on the MCP token_transfers tool. Field names, order and types are unchanged. A caller that divided by 1e6 itself has to stop.

  • [api] 2026-10-12 · GET /v1/onchain/wallets/{address}/counterparties returns plain USD — total_volume_usd, sent_usd and received_usd came back in micro-USD, 1,000,000 times too large, so this route disagreed with /trace and /wallets/compare about the same wallet. They are now divided once, on this route and on the MCP wallet_counterparties tool. Field names, order and types are unchanged. A caller that divided by 1e6 itself has to stop.

2026-09

  • [mcp] 2026-09-21 · ⚠ BREAKING · MCP token_chart removed; ohlcv replaced by hl_ohlcv and polymarket_ohlcv — both tools read the merged centralised-exchange candle engine. ohlcv read it directly; token_chart resolved an ERC-20 contract to a canonical symbol and read the same engine behind it, which is why a per-contract chart could answer for a token that trades nowhere on chain. Vike redistributes market data only from venues whose data is itself on chain — Hyperliquid and Polymarket — so the candle tools are scoped to those two rather than filtered venue by venue.

    tools/call with either retired name returns -32601. hl_ohlcv serves Hyperliquid candles and polymarket_ohlcv serves Polymarket candles; there is no replacement for a candle on a centralised venue, and no candle tool takes a contract address. The REST candle routes are unaffected by this entry — /v1/hyperliquid/ohlcv(/export) and /v1/polymarket/ohlcv already serve the same two venues.

  • [api] 2026-09-04 · ⚠ BREAKING · /v1/onchain/wallets/{address}/balances reads the chain, and covers two chains instead of six — balances are now balanceOf calls against our own Ethereum and BSC nodes, with the candidate token list drawn from our transfer index. base, arbitrum, polygon and optimism are no longer scanned: they come back named in chain_errors rather than silently contributing nothing.

    Two response fields are new — balance_raw (the contract's integer, as a string, for callers that need exactness) and name. usd_value and usd_price are now null on a holding we cannot price, and the holding is still listed; total_usd sums only the priced ones and should be read as a floor. The previous provider filtered unpriced holdings out entirely.

    The route no longer answers 200 with an empty holdings array when the lookup fails. That was the old shape and it read exactly like an empty wallet.

  • [api] 2026-09-04 · ⚠ BREAKING · GET /v1/onchain/wallets/{address}/defi is removed — decoded DeFi protocol positions, and the defi_positions MCP tool beside it. The route was served by an upstream vendor whose free tier was withdrawn on 2026-09-03, and it cannot be rebuilt from our own data: we record Transfer events, and a lending position is not a transfer. It recorded 4 calls in its entire history, so it was retired rather than replaced. fund_holdings is unaffected. Calls now return 404.

  • [api] 2026-09-04 · /v1/onchain/wallets/{address}/ens resolves over Ethereum RPC — the fallback for an address our pre-resolved table has not seen was an external API; it is now two eth_calls to the ENS registry over Ethereum RPC — public RPC endpoints first, then our own pool, so the address is sent to those RPC providers (wording corrected 2026-10-19; this entry first said "our own node"). No behaviour change for a caller beyond the obvious one: the fallback works again, where since 2026-09-03 it returned nothing. The name is forward-verified before it is returned — a reverse record is written by the address itself and means nothing until resolving it forward lands back on the same address — so a spoofed record answers null rather than somebody else's name.

  • [api] 2026-09-03 · ⚠ BREAKING · the flat Polymarket paths were retired — /v1/markets, /v1/markets/{condition_id}, /v1/market_stats, /v1/ohlcv, /v1/orderbook, /v1/settlements/{condition_id} and /v1/events now return 404. They predated the /v1/polymarket/ namespace and answered alongside it for compatibility. Add /polymarket after /v1 and nothing else changes — same handlers, same responses. Retired because the usage record showed no caller: 28 requests across their entire history, all from the account that owns the platform.

  • [api] 2026-09-03 · Polymarket moved to the same service as every other namespace — the nine endpoints were served by a separate process and are now served by the same application as onchain and hyperliquid. No path, parameter or response shape changed. What did change is below.

  • [polymarket/markets] 2026-09-03 · ⚠ BREAKING · market state is real — active and closed were CONSTANTS: every market reported active=1, closed=0, so ?active=0 returned nothing at all and ?closed=1 returned open markets with a 200. State is now derived from on-chain resolutions and the venue's own flag, either of which alone misses thousands. 119,047 of 121,275 markets report closed where none did before. ⚠ If you filtered on these fields, your results change — that is the fix, not a regression. closed is also accepted now as the complement of active; passing both is refused rather than silently resolved.

  • [limits] 2026-09-02 · Archive downloads no longer spend the hourly request budget — a ranged GET against /archive/ is still authenticated and still writes its usage row, but it no longer consumes the hourly request allowance. Bulk Parquet readers (pyarrow, DuckDB, fsspec) fetch a footer and then one ranged GET per column chunk, each of which cost a unit: one 1.26 GB partition measured 20,237 usage rows, more than the whole 20,000/hour ceiling for a single file, and almost every rate-limit rejection recorded in the platform's whole history was an archive download. /v1 and /mcp still meter normally, and the counter's periodic reseed excludes archive_download rows too, so the skip is not erased 30 seconds later.

  • [limits] ⚠ BREAKING · 2026-09-02 · Rate-limit rejections speak one dialect on every surface — a throttled request now returns 429 with Retry-After: 60 and {"error": {"code": "RATE_LIMITED", ...}}. Previously /v1 raised {"detail": ...}, the archive gate hand-built {"error": "rate limited"}, and /mcp answered 200 with a JSON-RPC error — so a client could not detect throttling by status code at all. /mcp still returns a valid JSON-RPC body and carries the envelope in error.data.

  • [api] 2026-09-02 · The published OpenAPI spec declares X-API-KEY — the /v1 spec carried no securitySchemes and no security, so a client generated from it omitted the API-key header and 401'd on every call. The schemes are injected into the generated spec itself, so the live spec and the exported file cannot disagree; ReDoc moved under /v1/ at the same time.

  • [api] ⚠ BREAKING · 2026-09-02 · The website app stopped publishing its route table — /openapi.json (283 paths), /docs and /redoc are switched off on the website app. Only the data API publishes a schema, scoped under /v1/. No /v1 route changed.

  • [api] ⚠ BREAKING · 2026-09-02 · /v1/etf/* and /v1/marketdata/ohlcv(/export) removed — the ETF router is no longer mounted and the marketdata candle routes are deleted; both now 404 for an authenticated caller, a closure pinned by a regression test so it cannot quietly come back. Public candles remain at /v1/hyperliquid/ohlcv(/export). Usage showed exactly one key had ever called each surface, last on Aug 17 and Aug 6.

  • [api] 2026-09-02 · New docs site at vike.io/docs/data — replaces the MkDocs site, which documented 8 of the 36 MCP tools the server exposes and quoted rate limits wrong by more than an order of magnitude. It covers getting started, authentication, rate limits, errors, the full 36-tool MCP reference generated from what the registry's tools/list actually serves, per-client setup (Claude Desktop and Code, Cursor, Gemini CLI, VS Code, raw HTTP), the /v1 REST overview and the archive; the Polymarket REST reference landed the same day. PRs #852 · 0b032622, #855 · a0afdb91, #856 · ecf9a730

  • [api] 2026-09-01 · Non-finite floats serialize as null instead of failing the request — a single NaN or Infinity anywhere in a payload previously produced a 503 through the error handler or a 500 on /v1, losing the entire response; the field is now null and the rest of the body arrives. It is also a large latency win on bulk pages: a 5,000-candle page went 44.14 ms to 1.41 ms, and NDJSON export lines 3.35 µs to 0.30 µs.

2026-08

  • [hyperliquid/position-snapshots] 2026-08-22 · MCP hl_position_match stopped returning closed positions — the tool read a latest-known-position view with no recency filter, and that view keeps a wallet's last-seen row forever (89.8% of rows more than a day stale, the oldest from 2026-04-02), so "who has a 25x ETH long open at $3,200" could answer with a position closed in April while the tool card promised <5 min staleness. Results are now gated on the newest snapshot batch for the asset.
  • [hyperliquid/cohort-metrics] ⚠ BREAKING · 2026-08-19 · /v1/hyperliquid/symbols/{symbol}/metrics refuses labelBasis and declares its contamination — the route filters every historical hour by today's wallet grading, resolved at request time rather than as of the hour being reported. Measured on the 2026-04-20T12:00Z BTC "3x smart" cohort: 938,495,920.6 against a point-in-time 861,706,562.3 — 8.91% inflated. It used to answer 200 to a request for honest labels; it now returns 400 for the parameter and points at /cohort-metrics.
  • [hyperliquid/cohort-metrics] 2026-08-19 · grading= on /v1/hyperliquid/symbols/{symbol}/cohort-metrics, and responses declare when the label was computed — one parameter selects among realized, realized-pit and unrealized, which previously took three different spellings (axis=pnl plus labelBasis, a separate axis, and no parameter at all). Every response now carries label_computed on the envelope and grading on every row.
  • [hyperliquid/cohort-metrics] 2026-08-19 · freshness object added to cohort-metrics responses — windows reaching the present now carry freshness: {newest_ts, age_seconds, settled_lag_ceiling_seconds, stale}. Before this, ?grading=realized-pit&hours=1 with no start returned its own newest bucket — measured 63 hours old and identical in shape to a live one, with nothing in the payload letting a program tell them apart. stale is the precomputed verdict, so a caller need not re-derive the rollup cadence. (figure corrected in)
  • [hyperliquid/candles] 2026-08-18 · New endpoint: GET /v1/hyperliquid/ohlcv (and /export) — minute-resolution Hyperliquid candles built from executed fills, mirroring /v1/marketdata/ohlcv's parameters and envelope. Two parameters are Hyperliquid-specific: dex (HL core versus builder-deployed HIP-3 perp DEXs) and tick intervals such as 15t.
  • [hyperliquid/cohort-metrics] 2026-08-17 · New cohort axis: axis=pnl_unrealized — grades a wallet by unrealized PnL on open positions as a share of account value, a different signal from the realized ladder: 44% of wallets change unrealized rung day over day, against 2.4% on realized. Point-in-time by construction, and not reachable through the API at all before this.
  • [api] ⚠ BREAKING · 2026-08-16 · /v1/marketdata/orderbook removed — the L1/L2 recorder behind it was retired and its stored datasets dropped (quotes 1.376B rows, book events 531M, trades 296M, among others; ~51 GiB reclaimed). The route was their only consumer, so it goes with them rather than becoming a permanent 503. There is no orderbook surface.
  • [api] 2026-08-15 · New namespace: /v1/etf/* (physical-ETF holdings) — 23 funds, 19 of them with a daily measured source; quantity is a measured count in the fund's own unit, never assets divided by a price. ⚠ This namespace was closed again on 2026-09-02.
  • [api] 2026-08-12 · Repeated identical /v1 requests return byte-identical bodies — the query engine reduces sum() in an unpinned parallel order and f64 addition is not associative, so the last digits of a nine-figure notional were reduction noise: one URL executed six times returned six distinct bodies, with 24–35% of values differing pairwise. Values are now snapped to 10 significant digits at the serialization boundary with a midpoint nudge, which took one research pipeline's content-addressed cache from broken to working; consumers no longer need to canonicalize floats themselves.
  • [hyperliquid/cohort-metrics] ⚠ BREAKING · 2026-08-11 · One canonical position-size ladder; retired labels now 400; new GET /v1/hyperliquid/cohorts — the position-size axis had four vocabularies (the site's dollar-range ladder, a stored micro..mega tier vocabulary, and two reconstruction vocabularies). The dollar-range ladder wins: axis=tier, /symbols/{symbol}/size-breakdown and /segments trade_size all derive the bucket from size_usd and serve the same canonical ten labels, largest first, and a retired label in a cohort filter returns 400 naming the canon. The new flat taxonomy endpoint GET /v1/hyperliquid/cohorts publishes all three ladders.
  • [hyperliquid/cohort-metrics] 2026-08-11 · New cohort axis: axis=tier on /symbols/{symbol}/cohort-metrics — the per-position size ladder as the third matrix axis. It is rejected on the per-wallet aggregates (heatmap, segment summary) because a wallet straddles tiers, and the refusal names where the axis is valid; a conflicting labelBasis is a 400 rather than a silent downgrade.
  • [hyperliquid/cohort-metrics] 2026-08-06 · labelBasis=point_in_time on axis=pnl — the pnl axis had lookahead — axis=pnl resolved the cohort at query time, so a historical row came back with today's grading and a backtest was told which wallets eventually became rankable. Measured on BTC over 3 days: 0 of 852 cells exact before, 852 of 852 after (max relative error 5.45e-16), and hourly totals from 4.37% mean error to 0.000000%. The frozen source costs five fields — no position count, no unrealized PnL, no token-denominated size — which come back null rather than 0 and are named in unavailable_fields; every row and the envelope carry label_basis.
  • [hyperliquid/cohort-metrics] 2026-08-06 · New endpoint: GET /v1/hyperliquid/symbols/{symbol}/cohort-metrics — returns the full coin-by-cohort matrix in one request instead of one request per bucket (12 for size, 13 for pnl). Measured on BTC over 24 hours: 0.25–0.44 s per axis against ~12 s for the equivalent loop. Paginated by hour rather than by row, so a page never lands mid-bucket.
  • [hyperliquid/cohort-metrics] 2026-08-06 · provisional flag on /symbols/{symbol}/metrics rows — the endpoint reads an hourly rollup that does not write hour H until H+1:00 to H+1:30; measured, the newest row was 114 minutes old and a client polling for "current positioning" had no way to know. Rows now carry provisional, true on at most one row (the unsettled right edge), and the live row cuts staleness to roughly 5 minutes.
  • [hyperliquid/cohort-metrics] 2026-08-06 · /segments rows carry groupable; axis error messages fixed — /segments published four axes but only three were valid as ?axis= (trade_size buckets a position, not a wallet), with nothing in the payload saying so; every row now carries groupable so a generated client can filter. Refusals name where the axis is valid, and the "forgot the axis" case no longer reports the server's own default back at the caller.
  • [api] 2026-08-04 · The /v1 data API goes live on data.vike.io — 34 routes across four namespaces under one host: marketdata, onchain, hyperliquid and polymarket. The error contract from day one: 400 for caller input, 503 for upstream, never a 200 with an empty body. The same work made archive authentication independent of the website, so a website deploy can no longer 500 an archive download — the mechanism of the 2026-07-31 outage. PRs #574 · af98d88d, #584 · 638a6d93
  • [api] 2026-08-04 · /v1/hyperliquid expands from 2 endpoints to 22 — new: cohort catalogue, per-cohort summary and coin-by-cohort heatmap; position list and history, market-wide OI, hourly coin metrics, trade-size breakdown; trader leaderboard with the full risk-metric set, and per-wallet summary, trades, trade-stats, fills, funding and ledger; liquidation fills, a price-binned liquidation heatmap and liquidation risk by asset; ecosystem stats, perp volume and HYPE holders. Pagination is keyset throughout.
  • [hyperliquid/builders] 2026-08-04 · New: /v1/hyperliquid/builders/* (6 routes) — leaderboard, builder profile, that builder's traders, raw fills, a per-bucket time series, and the reverse lookup of which builders a wallet routes through. Schema note for consumers: builder_fee and deployer_fee are USD, but fee is denominated in fee_token (1.04% of rows pay in something else), so fee aggregates are USD-only and the profile reports what it excluded.
  • [hyperliquid/builders] 2026-08-04 · New: GET /v1/hyperliquid/builders/stats, plus richer builder fields — leaderboard rows gain revenue_per_user, taker_pct, market_share_pct and first_seen_lifetime; the profile gains profitable_users(_pct), biggest_day, market_share_pct, a lifetime block and user_volume_distribution (volume deciles). /builders/stats returns ecosystem totals, all-time builder revenue and a daily series. The same change fixes a keyset pagination bug that could drop or repeat rows.
  • [hyperliquid/traders-and-leaderboard] 2026-08-04 · axis=pnl_abs, a position-age filter, and /leaderboard/flow-adjusted re-enabled — the board was withheld in #588 and now ranks on total realized PnL (closed round-trips), because the upstream ledger records sends one-sided: over 30 days, 1,010,263 negative against 835,295 positive send rows, netting -$1.27B, so an outflow was recorded while the matching inflow was invisible and booked as profit. The attributed figures ship under their own attributed key with a flow_unbalanced flag.
  • [api] 2026-08-04 · /v1/marketdata/options/chain returned settled contracts, not the live chain — the query had no time bound: it aggregated the whole recorded history and returned the oldest expiries first, so a BTC chain request came back with contracts that had settled eight weeks earlier while the live chain was three expiries inside the next 72 hours. The read is now bounded to one snapshot.

2026-07

  • [limits] 2026-07-29 · Hourly rate limit raised from 2,000 to 20,000 requests per key — the 2,000 ceiling was sized for the MCP and AI-chat surface and inherited by the data routes, where it was far too low: a real hour measured 2,543 calls with 558 rejected. It is one shared ceiling across /v1, /mcp and the archive, not a per-surface number — see Rate limits.
  • [archive] ⚠ BREAKING · 2026-07-29 · The Parquet archive became credential-gated and metered, and usage is labeled per surface — /archive/ downloads are now validated at the edge through the same API-key and OAuth auth, the same hourly limit and the same metering as /mcp, so an unauthenticated download stops working. Usage rows are labeled from the request URI rather than hardcoded — /archive/... to archive_download, /v1/<route>... to api_<route>, /mcp to mcp, anything else to api_other. Auth and rate-limit decision logic elsewhere was unchanged; only the label.

2026-06

  • [mcp] 2026-06-16 · MCP perp_funding(symbol=...) fixed — it errored on every call — any symbol-scoped request returned an error instead of data; only the unscoped call worked. The symbol path was rewritten.

2026-05

  • [api] 2026-05-30 · New: a historical OHLCV API (REST + MCP) — API-key-gated historical candles built on a canonical 1-minute base and correct at any timeframe from 1m to 1w: UTC left-aligned buckets, partial buckets excluded so the series is look-ahead-safe, and deterministic cursor pagination. Shares MCP auth, the hourly rate limit and usage logging. ⚠ This surface is no longer documented — see the note at the foot of this page — and its MCP tool was removed on 2026-09-21.
  • [api] 2026-05-30 · include_partial flag on ohlcv (REST + MCP); token_chart returns real candles — include_partial is off by default (look-ahead-safe); switched on, it includes the in-progress current candle. token_chart was a stub and now resolves a token address to a canonical symbol and serves real candles through the ohlcv engine, with the legacy 5/30/120 values mapping to 5m/30m/2h. ⚠ Both tools were removed on 2026-09-21.
  • [mcp] 2026-05-26 · New MCP tool: hl_position_match — reverse-lookup of Hyperliquid share cards. 72bafc07
  • [limits] 2026-05-25 · Hourly per-key cap raised from 100 to 2,000 — headroom for agent workloads, where one skill workflow can call 5–15 tools per turn. da4c744d
  • [mcp] 2026-05-25 · 5 new MCP tools (v0.7) — wallet_transactions, wallet_compare, wallet_trace, wallet_batch_labels, token_screener. fdc32aad
  • [mcp] 2026-05-25 · 4 new MCP tools (v0.5.0) — alerts_register_webhook, wallet_counterparties, wallet_pnl_history, wallet_token_balances. 2832bb04
  • [mcp] 2026-05-25 · New MCP tool wallet_ens; defi_positions repointed from DeBank to Moralis — the provider swap changes the data source behind an existing tool. 00cfc5ce
  • [mcp] 2026-05-25 · 2 new MCP tools — web_search, web_fetch. e2143e3f
  • [mcp] 2026-05-25 · 4 new MCP tools (v0.3.0) — fund_holdings, wallet_label_provenance, token_holders, defi_positions. 65a51900
  • [mcp] 2026-05-25 · 4 new Polymarket MCP tools — polymarket_markets, polymarket_market_detail, polymarket_wallet, polymarket_smart_money. 57d327c1

2026-04

  • [mcp] 2026-04-20 · New MCP tool: hl_perp_top_traders — 138e9234
  • [mcp] 2026-04-19 · OAuth 2.1 and Dynamic Client Registration on /mcp — the MCP endpoint accepts Authorization: Bearer alongside X-API-KEY, with RFC 8414 discovery, RFC 7591 dynamic client registration, Authorization Code + PKCE S256, refresh-token rotation and RFC 7009 revocation — so Claude Desktop's "Add custom connector" dialog works with no mcp-remote and no JSON config. The rate limit stays per credential: per api_key_id for API keys, pooled per user_id for OAuth. 72774187
  • [mcp] 2026-04-16 · MCP server launches: POST /mcp, JSON-RPC 2.0, X-API-KEY auth, 9 tools — initial tools: token search, wallet summary, wallet discover, transfers, chart, perps leaderboard, funding, spreads, options flow. Per-tool credit costs, hourly rate limiting and usage tracking ship with it. 7d9bec99

What this page cannot see

Entries are derived from the repository's own history — read from the commit diff, not the subject line — rather than from probing the deployed API. Four gaps are structural, and it is better to name them than to let the page imply completeness:

  • /v1/polymarket/* has no dated history here. Those routes are served by a separate system with its own history, and were frozen at the /v1 cutover on 2026-08-04. The current surface is documented in Polymarket REST; its change history is not on this page.
  • Some surfaces this history records are no longer documented. Entries above describe endpoints and MCP tools that shipped and are not in the current reference — the CEX candle, perp and options surfaces. ⚠ They carry no ⚠ BREAKING entry deliberately, because that marker means a caller had to change something and nothing here was withdrawn from callers: the documentation was withdrawn, not the routes. Treating an undocumented surface as a supported one is the mistake this note exists to prevent.
  • Edge configuration is applied outside this history. Routing, edge caching, throughput caps, compression and which paths are gated can change without a commit to record, so an edge-only change is invisible here.
  • The archive's dataset inventory is generated on the host, not committed. There are no "dataset added to the archive" entries above, and that is absence of evidence rather than evidence of absence — the open manifest.json is the live answer for what the archive holds today.

On this page