# Tessera Analytics > Hyperliquid perp market data as an API — 1-minute OHLCV enriched with order flow, hourly funding, and hourly positioning, downloadable as Parquet over REST, plus a hosted MCP server that answers cross-sectional questions about the whole perp universe on complete days or completed hours. REST access is keyed by an API key (`Authorization: Bearer `, created free at https://tesseralytics.dev/signup). A free key reaches `gold_ohlcv_1m` for BTC, ETH, SOL and HYPE over the trailing month, unlimited downloads. The MCP intelligence layer is scoped separately: a free key ranks every market (HIP-3 included) over the trailing 7 days at 20 tool calls a day. Pro ($29/month) removes every limit — all three datasets, every market, the full history, and uncapped MCP calls. Closed history is also sold one-off with no subscription: https://tesseralytics.dev/pricing lists three bundles — Majors ($19), the `xyz` HIP-3 deployer ($24) and All Markets ($29) — each the closed months of all three datasets, frozen at purchase, perpetual on the account and inherited by every key on it. A bundle grants no MCP entitlement. `https://tesseralytics.dev/v1/bundles` returns every bundle's price, month ceiling, partition counts and per-dataset coverage as JSON, with no key. ## How to buy There is **no agent-initiated payment path**: every purchase completes in a browser with a human present, through Stripe Checkout. An agent that decides its operator should buy should return the pricing URL — https://tesseralytics.dev/pricing — instead of retrying a purchase; no request to this API creates a charge. The human path is: create an account at https://tesseralytics.dev/signup (email verification), then on https://tesseralytics.dev/pricing either subscribe to Pro or buy a one-off bundle. The API key is minted in the account dashboard at https://tesseralytics.dev/account (`POST /account/keys`, which needs the portal's login session, not an API key), and a bundle bought on the account is usable by every key on it immediately — no activation step, no per-download charge. Prices, month ceilings and coverage are machine-readable before any purchase at `https://tesseralytics.dev/v1/bundles`. Everything below is the site's own content, converted to markdown at build time. Markdown alternates of individual pages sit alongside this file (`/datasets.md`, `/mcp-server.md`, …) — prefer those when only one page is needed. --- Source: https://tesseralytics.dev/ Hyperliquid · MCP + REST # Hyperliquid intelligence, built for trading agents. The intelligence layer is our MCP server: rank the whole market in one call — crowded funding, funding divergence, decile screens — over order-flow-enriched Hyperliquid data. Nine tools for your agent; REST and Parquet for everything else. [Get an API key](https://tesseralytics.dev/signup) [Explore the MCP server](https://tesseralytics.dev/mcp-server) No card required — the free tier is order-flow-enriched minute OHLCV for BTC, ETH, SOL & HYPE over the trailing month. tessera.mcp · claude query\_cross\_section · ok youWhich markets’ longs are paying the most to hold? query\_cross\_section({ day: "2026-09-15", order\_by: "funding\_rate\_mean", top\_n: 6 }) One call. No download code, no files, no aggregation in the prompt — the intelligence layer ranks the cross-section and returns 6 rows. 33 of 234 markets ranked as of 2026-09-15 #CoinFunding /hAnnualised 1 USELESS +0.00204% +17.9% 2 VVV +0.00189% +16.6% 3 CASHCAT +0.00182% +16.0% 4 PONS +0.00170% +14.9% 5 LIT +0.00125% +10.9% 6 ENA +0.00125% +10.9% Real Hyperliquid funding history, complete UTC day 2026-09-15 — the mean of the day’s 24 hourly rates, captured 2026-09-16. ## One question, two shapes A row API hands the model fills — one row each, millions a day — and leaves the aggregation to it. The intelligence layer ranks the cross-section and returns the answer. GET /v1/trades?coin=BTC raw rows - {"px":75744.0,"sz":0.00345,"side":"B","time":1789566701384} - {"px":75743.0,"sz":0.00037,"side":"B","time":1789566701384} - {"px":75743.0,"sz":0.00015,"side":"B","time":1789566701384} - {"px":75743.0,"sz":0.00017,"side":"B","time":1789566701384} - {"px":75743.0,"sz":0.00017,"side":"B","time":1789566701384} - {"px":75743.0,"sz":0.0002,"side":"B","time":1789566701384} - {"px":75743.0,"sz":0.00032,"side":"B","time":1789566700697} - {"px":75742.0,"sz":0.00016,"side":"A","time":1789566700507} - {"px":75743.0,"sz":0.00227,"side":"B","time":1789566699555} - {"px":75743.0,"sz":0.00017,"side":"B","time":1789566699555} 10 consecutive BTC prints. The market’s shape is still yours to compute. screen\_universe 3 of 33 matched screen\_universe({ day: "2026-09-15", conditions: \[ { field: "funding\_rate\_mean", op: ">=", value: 0.000015 }, { field: "ret\_1d", op: "<", value: 0 } \] }) Longs paying most, price falling as of 2026-09-15 #CoinFunding /hDay 1 VVV +0.00189% −-7.83% 2 CASHCAT +0.00182% −-2.25% 3 PONS +0.00170% −-2.16% Two conditions, one call, 33 markets screened — computed here from the same captured day. ## The market, then the numbers behind it Both paths serve the same three gold datasets, rebuilt every night from the raw Hyperliquid tape: order-flow-enriched minute OHLCV with CVD, hourly funding with cumulative carry, hourly positioning with whale net position. BTC, minute by minute Daily close from `gold_ohlcv_1m` — sample data, charted straight from the Parquet the free tier serves. Every market, including HIP-3 234 markets were listed on the venue at the last capture. Builder-deployed markets carry a venue prefix and history from their listing — the coverage the majors-only vendors don’t have. Deduped and quality-checked end to end. Unlimited Parquet downloads — no per-GB fee. The intelligence layer and the API read the same lake. [Browse the catalog →](https://tesseralytics.dev/datasets) Cumulative volume delta `gold_ohlcv_1m` · 2026-03..2026-05 Cumulative funding `gold_funding_1h` · 2026-03..2026-05 Whale net position `gold_positioning_1h` · 2026-03..2026-05 ## Two paths to the same lake The intelligence layer and the API read identical Parquet. Pick whichever suits your use case: raw Parquet for backtests, the intelligence layer for live trading agents. Agentic · intelligence layer Hand your agent the market’s shape A hosted MCP server at one endpoint: rank the cross-section, screen on several conditions, measure funding divergence, pull a per-coin series, read the live market. No download code and no local files — the model calls a tool and reasons over the answer. ``` claude mcp add --transport http tessera https://tesseralytics.dev/mcp \ --header "Authorization: Bearer $TESSERA_API_KEY" ``` Auth is the API key you already have. Discovery tools work without one. [See the tool reference →](https://tesseralytics.dev/mcp-server) Not ready to wire a client? [Run one of these calls in the browser →](https://tesseralytics.dev/playground) Agentless · REST + Parquet Pull the partitions into your own pipeline Every partition is a plain Parquet file behind a presigned URL, or one call from the Python SDK straight into Polars or DuckDB SQL. Drop it into a backtester; there’s no per-GB fee. ``` df = client.read("gold_ohlcv_1m", "BTC", "2026-05") ``` `GET /v1/datasets` lists what your key can reach. [See the SDKs →](https://tesseralytics.dev/sdks) Tessera is Latin for a small tile — one piece of a larger picture. Two large tiles and the small ones beneath them: the intelligence layer and the REST API are the ways in, and every dataset is a tile of the market behind them. ## How it works 1. Step 1 ### Sign up Google or email — the free tier needs no card. [Create an account →](https://tesseralytics.dev/signup) ``` curl https://tesseralytics.dev/v1/datasets \ -H "Authorization: Bearer $TESSERA_API_KEY" ``` 2. Step 2 ### Create an API key It’s shown once, so save it as $TESSERA\_API\_KEY. Keys are hash-only and revocable from your account. 3. Step 3 ### Connect your agent, or your pipeline Point an MCP client at the endpoint, or install the Python SDK and query straight into DuckDB SQL. [See the SDKs →](https://tesseralytics.dev/sdks) ``` pip install "tessera-api[duckdb]" ``` ## Start free. Upgrade when you need the whole market. The free tier is the full experience on a slice of the market; Pro unlocks full history, every market and every dataset. Free $0 /mo Get started with no card. - Order-flow-enriched minute OHLCV - BTC, ETH, SOL & HYPE — trailing month - REST API + Parquet downloads - MCP: every market, daily bars, last 7 days (20 calls/day) [Sign up for a free API key](https://tesseralytics.dev/signup) Pro Recommended $29 /mo Everything in Free, plus full history on every coin. - Everything in Free - Full funding history — every coin - Funding & positioning data, all coins incl. HIP-3 - MCP: the full record, daily + hourly state bars, unlimited calls Every plan is all-you-can-eat — unlimited downloads, no per-GB fees. Pull the whole history as often as you like. One-off downloads Prefer to own the history? Buy the closed months of all three datasets once — from **$19**, no subscription. [See the bundles](https://tesseralytics.dev/pricing#bundles) --- Source: https://tesseralytics.dev/datasets Data catalog # Every dataset, column by column Order-flow-enriched minute OHLCV, hourly funding and hourly positioning — built from the raw Hyperliquid tape and partitioned per `(coin, month)`. Each dataset is a tile: one exact piece of the market, cut to a coin and a month. Every dataset is a Parquet file; open one to see what each column means. 3 datasets · 60 documented columns · the same catalog the MCP intelligence layer and the REST API serve [Get a free API key](https://tesseralytics.dev/account) [Query it from code](https://tesseralytics.dev/sdks) ## Raw tiles Order-flow OHLCV, funding and positioning — the market, as it traded. Tessera is Latin for a small tile — one piece of a larger picture. one square = one dataset · 3 datasets, the seams shared [ ### Order-flow OHLCV (1-minute) Free `gold_ohlcv_1m` 1-minute Hyperliquid OHLCV candles enriched with order flow — volume at bid versus ask, CVD, fees and realized PnL — downloadable as Parquet. 1-minute bars, partitioned per (coin, month) 25 columns → ](https://tesseralytics.dev/datasets/gold_ohlcv_1m)[ ### Funding rates (hourly) Pro `gold_funding_1h` Hourly Hyperliquid funding-rate data per coin — the current rate, an annualized view, and a running cumulative total that stitches cleanly across months. hourly, partitioned per (coin, month) 6 columns → ](https://tesseralytics.dev/datasets/gold_funding_1h)[ ### Positioning & flow (hourly) Pro `gold_positioning_1h` Hourly Hyperliquid open interest and positioning — long-vs-short skew, per-side concentration, whale net position, and what changed since the last hour. hourly snapshots, partitioned per (coin, month) 29 columns → ](https://tesseralytics.dev/datasets/gold_positioning_1h) Ask the intelligence layer, or pull the file The MCP tools rank and screen this catalogue without you downloading anything; the REST API hands you the partitions and the SDK streams them into Polars or DuckDB. [MCP server](https://tesseralytics.dev/mcp-server) [REST reference](https://tesseralytics.dev/api-docs) [Field dictionary](https://tesseralytics.dev/datasets/fields) Coverage A free key reaches order-flow minute OHLCV for BTC, ETH, SOL & HYPE over the trailing month. Pro unlocks every dataset, every market including HIP-3, and full history from October 2025. [Compare plans](https://tesseralytics.dev/pricing) [Rank the HIP-3 markets yourself →](https://tesseralytics.dev/playground) --- Source: https://tesseralytics.dev/datasets/gold_ohlcv_1m [← Data catalog](https://tesseralytics.dev/datasets) # Order-flow OHLCV (1-minute) Free `gold_ohlcv_1m` 1-minute bars, partitioned per (coin, month) gold\_ohlcv\_1m is 1-minute Hyperliquid OHLCV candle data enriched with order flow — open/high/low/close, volume, the aggressor buy/sell split, cumulative volume delta (CVD), fees and realized PnL — for every perpetual market. Download the historical candles as Parquet or query them through the Tessera API. Free covers BTC, ETH, SOL and HYPE for the trailing month. The workhorse market-data tile: a normal candle chart plus the "who was pushing" detail — was the move backed by real aggressive flow? — that price alone can't show. Free covers BTC, ETH, SOL and HYPE for the trailing month; Pro unlocks every coin, including HIP-3 RWA markets, with full history from October 2025. What you'd use it for: Backtesting intraday strategies, building volume-profile and CVD signals, or charting Hyperliquid price with the order-flow context raw candles can't show. Timing · `time` (1m) \`time\` is the START of the minute; each bar covers the half-open interval \[time, time + 1 minute). Every field is computed over that forward window, so a bar labelled \`time\` embeds information up to time + 60s. Do not use a bar to make a decision AS OF \`time\` itself, and lag by one bar before joining to point-in-time data (this is the OPPOSITE labelling to gold\_positioning\_1h, whose flow fields are backward-looking). [Get a free API key](https://tesseralytics.dev/account) [API reference](https://tesseralytics.dev/api-docs) ## What it looks like Sample data for BTC, charted from the same Parquet the API serves. Close · BTC · sample CVD · BTC · sample ## Data dictionary 25 columns, every one documented. The same table is served by `describe_dataset` to an MCP client and by `/v1/catalog/gold_ohlcv_1m` over HTTP. window starting at timestamp | Column | Type | What it means | | --- | --- | --- | | `time` | timestamp\[us\] | The minute this bar covers (its starting timestamp, UTC). How it's computed: Minute bucket start, UTC. | | `coin` | string | Which market this row is for. HIP-3 markets carry a deployer prefix, e.g. xyz:NVDA. | | `open` | float64 | Price at the start of the minute. | | `high` | float64 | Highest trade price during the minute. | | `low` | float64 | Lowest trade price during the minute. | | `close` | float64 | Price at the end of the minute — the one most people mean by 'the price'. | | `volume` | float64 | How much traded in the minute, in quote units. The raw activity level. How it's computed: Total traded volume in the minute. | | `buy_vol` | float64 | The slice of volume where the aggressor was buying (lifting the offer). Demand pressure. How it's computed: Volume on aggressor-buy fills. | | `sell_vol` | float64 | The slice of volume where the aggressor was selling (hitting the bid). Supply pressure. How it's computed: Volume on aggressor-sell fills. | | `aggressor_delta` | float64 | Net aggressive pressure this minute: buy\_vol minus sell\_vol. Positive means buyers were leaning on the book harder than sellers. How it's computed: buy\_vol - sell\_vol (stateless per-bar). | | `cvd` | float64 | The running total of aggressor\_delta — a continuous line of cumulative net buying. When price rises but CVD is flat or falling, the move isn't backed by aggressive flow and is more likely to fade. How it's computed: Running cumulative aggressor\_delta, continuous across day and month boundaries (gold-owned). | | `trade_count` | uint32 | How many individual trades happened in the minute — a proxy for activity and fragmentation. | | `unique_takers` | uint32 | How many distinct wallets took liquidity this minute. Broad participation vs. one big player. | | `vwap` | float64 | The volume-weighted average fill price for the minute — a fairer 'where did it actually trade' than the close. | | `total_fees` | float64 | All trading fees paid in the minute. | | `taker_fees` | float64 | Fees paid by the aggressive side (takers). | | `maker_fees` | float64 | Fees paid — or rebates earned — on the passive side (makers). | | `taker_open_long_vol` | float64 | Aggressive volume that opened new long positions — fresh long risk entering. | | `taker_open_short_vol` | float64 | Aggressive volume that opened new short positions — fresh short risk entering. | | `taker_close_long_vol` | float64 | Aggressive volume that closed existing longs — longs taking profit or cutting. | | `taker_close_short_vol` | float64 | Aggressive volume that closed existing shorts — shorts covering. | | `closed_pnl_long` | float64 | Realized profit or loss booked by longs that closed this minute. | | `closed_pnl_short` | float64 | Realized profit or loss booked by shorts that closed this minute. | | `funding_rate` | float64 | The prevailing hourly funding rate at this minute, carried forward from the funding feed. Positive means longs pay shorts. How it's computed: Forward-filled from bronze\_funding (NULL before first event). | | `bootstrap_source` | string | Housekeeping flag for how the running CVD was seeded at the previous partition boundary — the prior day for this daily series, the prior month at a month boundary ('cold\_start' or 'carried\_from\_prior'). Ignore unless you're auditing continuity. How it's computed: 'cold\_start' or 'carried\_from\_prior'. | --- Source: https://tesseralytics.dev/datasets/gold_funding_1h [← Data catalog](https://tesseralytics.dev/datasets) # Funding rates (hourly) Pro `gold_funding_1h` hourly, partitioned per (coin, month) gold\_funding\_1h is hourly Hyperliquid funding-rate data for every perpetual market — the current rate, an annualized view, and a month-continuous cumulative funding total. Download the full funding-rate history as Parquet or query it through the Tessera API. Funding is the carry longs and shorts pay to keep the perp tethered to spot. Hyperliquid settles funding every hour, so this is a genuine hour-by-hour series rather than the 8-hourly snapshots most venues publish. The cumulative total stitches across month boundaries, so the carry a held position paid or earned reads straight off the column. What you'd use it for: Funding-carry and basis strategies, measuring the cost of holding a perp, or reading crowded positioning from persistent funding. Timing · `time` (1h) \`time\` is the hour the funding settles for (UTC): the rate is charged at \`time\` for the hour that ended there, which is the venue's own convention (the print is published moments after \`time\`). funding\_rate and annualized are the point-in-time rate for that hour; cum\_funding is the running total through \`time\`. Every field is knowable at \`time\` — there is no forward window. [Get a free API key](https://tesseralytics.dev/account) [API reference](https://tesseralytics.dev/api-docs) ## What it looks like Sample data for BTC, charted from the same Parquet the API serves. Annualized funding · BTC · sample Cumulative funding · BTC · sample ## Data dictionary 6 columns, every one documented. The same table is served by `describe_dataset` to an MCP client and by `/v1/catalog/gold_funding_1h` over HTTP. snapshot · as of timestamp | Column | Type | What it means | | --- | --- | --- | | `time` | timestamp\[us\] | The hour this funding observation applies to (UTC). | | `coin` | string | Which market this row is for. | | `funding_rate` | float64 | The hourly funding rate. When it's positive, longs pay shorts (the crowd is long and pays for it); when negative, shorts pay longs. | | `annualized` | float64 | The same rate scaled to a yearly figure (× 24 × 365) so you can compare carry against other yields at a glance. It is a point-in-time print annualized, not a plausible carry: a single stress hour annualizes to an absurd figure (one −0.38 %/h hour, a real squeeze print, reads as ≈ −3 300 %/yr). For context, the venue's neutral print is +0.00125 %/h (≈ +11 %/yr) and October 2026's hour-to-hour range ran to −0.5 %/h (≈ −4 400 %/yr), mostly on thin HIP-3 markets — compare a row against the funding distribution, or use cum\_funding for carry actually paid. How it's computed: funding\_rate \* 24 \* 365. | | `cum_funding` | float64 | Running total of funding since the series began, stitched across month boundaries — a lifetime level, not an interval's carry, so a cross-sectional rank on it mixes carry with listing age and size. How it's computed: Cumulative funding\_rate, spliced across month boundaries. | | `bootstrap_source` | string | Housekeeping flag for how the cumulative total was seeded at the previous partition boundary — the prior hour for this hourly series, the prior month at a month boundary. Ignore unless auditing continuity. | --- Source: https://tesseralytics.dev/datasets/gold_positioning_1h [← Data catalog](https://tesseralytics.dev/datasets) # Positioning & flow (hourly) Pro `gold_positioning_1h` hourly snapshots, partitioned per (coin, month) gold\_positioning\_1h is hourly Hyperliquid open-interest and positioning data, derived from the full two-sided perp ledger — total open interest, long-vs-short account skew, per-side concentration, whale-cohort net position, and the taker flow behind each change. Download the history as Parquet or query it through the Tessera API. Because the perp ledger is a closed system — every long is someone's short — the signal lives in asymmetries, not in a net total that is always zero. These aggregates measure who is crowded (head-count skew), who is concentrated (per-side share), and who is big (the whale cohort), plus the taker flow that moved each of those since the last snapshot. What you'd use it for: Tracking open-interest trends, gauging crowded or concentrated positioning, and spotting squeezes and capitulations from whale and taker-flow shifts. Timing · `time` (1h) \`time\` is the instant the positioning snapshot was taken (~top of the hour, UTC). The snapshot aggregates (open interest, concentration, whale, head-counts) are point-in-time AS OF \`time\`. The attribution and taker-flow fields are BACKWARD-looking: they sum over the interval (previous snapshot, time\] — the hour ENDING at \`time\` — so the whole row is knowable at \`time\` and is safe to act on without look-ahead. This is the OPPOSITE labelling to gold\_ohlcv\_1m, whose bars are start-labelled; align the two by lagging OHLCV one bar. [Get a free API key](https://tesseralytics.dev/account) [API reference](https://tesseralytics.dev/api-docs) ## What it looks like Sample data for BTC, charted from the same Parquet the API serves. Open interest (BTC) · BTC · sample Whale net position · BTC · sample ## Data dictionary 29 columns, every one documented. The same table is served by `describe_dataset` to an MCP client and by `/v1/catalog/gold_positioning_1h` over HTTP. ### Core aggregates snapshot · as of timestamp | Column | Type | What it means | | --- | --- | --- | | `time` | timestamp\[us\] | The hour this positioning snapshot was taken (UTC). | | `coin` | string | Which market this row is for. | | `open_interest` | float64 | Total size of open positions in the market — how much risk is on the table. Rising OI means new money committing; falling OI means positions being unwound. How it's computed: Two-sided open interest = (long\_oi + short\_oi)/2. long\_oi == short\_oi by the ledger identity, so this is the single OI figure. | | `n_long_positions` | uint32 | How many wallets are currently holding a long. | | `n_short_positions` | uint32 | How many wallets are currently holding a short. | | `n_unique_users` | uint32 | How many distinct wallets have a position at all — the breadth of participation. | | `account_ls_ratio` nullable | float64 | Long accounts divided by short accounts. Above 1 means more wallets are long than short (crowd leaning long by head-count). Extreme readings often mark crowded, vulnerable positioning. How it's computed: n\_long\_positions / n\_short\_positions — the long/short \*account\* ratio (crowd direction by head-count). NULL when no shorts. | | `top10_long_share` nullable | float64 | How much of the long side is held by its ten biggest accounts — high means the longs are a few whales, not a broad crowd. | | `top10_short_share` nullable | float64 | The same concentration measure for the short side. | | `concentration_skew` nullable | float64 | Whether shorts or longs are the more concentrated side (short share minus long share). Positive means the shorts are the whale-heavy side — the ones more prone to a squeeze. How it's computed: top10\_short\_share - top10\_long\_share; >0 when shorts are more concentrated than longs. NULL when either side is empty. | | `hhi_gross` nullable | float64 | A standard market-concentration score over all exposure — high when a handful of accounts dominate the whole book. How it's computed: Herfindahl–Hirschman concentration index over gross exposure. | | `whale_net_position` | float64 | The net direction of the biggest accounts (top 10% by size). Positive means the whales are net long. This survives the zero-sum ledger because it's a sub-group, so it's a genuine 'smart money' tilt signal. How it's computed: Net signed szi of the top 10% of accounts by |szi| (the whale cohort). Signed: >0 = whales net long. Non-degenerate because it sums over a sub-population, not the whole zero-sum ledger. Divide by open\_interest for an OI-relative skew. | | `whale_long_account_share` nullable | float64 | What fraction of the whale cohort is on the long side, by head-count. How it's computed: Fraction of the whale cohort net long, by head-count. NULL when empty. | | `n_whale_accounts` | uint32 | How many accounts make up the whale cohort this hour (the top 10% by position size). How it's computed: Whale cohort size = ceil(0.10 \* n\_unique\_users), floored at 1 when non-empty. | ### Attribution — what changed since the previous snapshot window ending at timestamp Head-count deltas versus the prior hour: how many wallets opened, closed, or flipped sides. This is the raw churn behind the positioning change — useful for telling a quiet drift apart from a violent reshuffle. | Column | Type | What it means | | --- | --- | --- | | `d_open_interest` nullable | float64 | Change in open interest across the completed hour — net risk added or removed. NULL if the previous hour's snapshot is missing, so the figure is never a change spanning several hours presented as one hour's move. | | `n_new_longs` nullable | uint32 | Wallets that opened a fresh long during the completed hour. NULL if the previous hour's snapshot is missing, so the count never spans more than one hour. | | `n_new_shorts` nullable | uint32 | Wallets that opened a fresh short during the completed hour. NULL if the previous hour's snapshot is missing, so the count never spans more than one hour. | | `n_closed_longs` nullable | uint32 | Wallets that closed a long during the completed hour. NULL if the previous hour's snapshot is missing, so the count never spans more than one hour. | | `n_closed_shorts` nullable | uint32 | Wallets that closed a short during the completed hour. NULL if the previous hour's snapshot is missing, so the count never spans more than one hour. | | `n_flipped_l2s` nullable | uint32 | Wallets that flipped from long to short during the completed hour — a sentiment reversal, one wallet at a time. NULL if the previous hour's snapshot is missing, so the count never spans more than one hour. | | `n_flipped_s2l` nullable | uint32 | Wallets that flipped from short to long during the completed hour. NULL if the previous hour's snapshot is missing, so the count never spans more than one hour. | ### Taker-flow rollup — aggressive flow over the hour window ending at timestamp | Column | Type | What it means | | --- | --- | --- | | `aggressor_delta_1h` nullable | float64 | Net aggressive buy-minus-sell pressure summed over the hour — the hourly version of CVD's slope. How it's computed: Σ aggressor\_delta over the window — net taker buy−sell pressure (windowed CVD). | | `net_taker_open_1h` nullable | float64 | Net new aggressive directional risk: long opens minus short opens by takers. The single headline 'which way is the aggressive money leaning' number for the hour. How it's computed: Σtaker\_open\_long\_vol − Σtaker\_open\_short\_vol — net aggressive new directional risk. The headline signed positioning-flow figure. | | `oi_opened` nullable | float64 | Aggressive volume that opened positions this hour — flow-implied risk coming on. How it's computed: Σtaker\_open\_long\_vol + Σtaker\_open\_short\_vol — flow-implied OI added. | | `oi_closed` nullable | float64 | Aggressive volume that closed positions this hour — flow-implied risk coming off. How it's computed: Σtaker\_close\_long\_vol + Σtaker\_close\_short\_vol — flow-implied OI removed. | | `flow_vs_snapshot_oi_residual` nullable | float64 | The gap between the OI change we saw and the OI change taker flow can explain. What's left is mostly the maker side — passive positioning you can't see directly in the trade tape. How it's computed: d\_open\_interest − (oi\_opened − oi\_closed). Reconciles snapshot ΔOI against flow-implied ΔOI (flips folded in); residual ≈ maker-driven OI, unobservable from taker fills. | | `taker_flip_l2s_1h` nullable | float64 | Aggressive long-to-short flip volume — a capitulation tell (longs giving up and flipping). How it's computed: Aggressive 'Long > Short' flip volume (close-long + open-short legs) — capitulation signal. | | `taker_flip_s2l_1h` nullable | float64 | Aggressive short-to-long flip volume — a squeeze tell (shorts giving up and flipping). How it's computed: Aggressive 'Short > Long' flip volume (close-short + open-long legs) — short-squeeze signal. | ### Provenance key / provenance | Column | Type | What it means | | --- | --- | --- | | `bootstrap_source` | string | Housekeeping flag for how the first row of the month was seeded from the prior month. Ignore unless auditing continuity. | --- Source: https://tesseralytics.dev/datasets/fields [← Data catalog](https://tesseralytics.dev/datasets) # Field dictionary The cross-section's field vocabulary: every column the [intelligence layer](https://tesseralytics.dev/mcp-server) can rank, screen and query, at the daily and hourly grain. 84 fields, each with its unit and grain. Fields measured on their own carry a signal class — state, momentum, microstructure or no signal — and, where the measurement exists, its forward IC and delay retention. [Read the research](https://tesseralytics.dev/blog/mcp-cross-section) that produced the classes. ## State Durable 24-hour-horizon signal — carry, positioning and size. Retains ≈1 of its IC after the publication delay. | Field | Unit · grain | What it means | | --- | --- | --- | | `account_ls_ratio` | ratio 1d · 1h IC 0.0156 @24h · retention 1.04 | Long accounts divided by short accounts. Above 1 means more accounts are long than short — crowd direction by head-count. | | `cum_funding` | fraction (of notional) 1d · 1h IC 0.0473 @24h · retention 1.016 | Running total of funding since the series began, continuous across months — a lifetime level, not an interval's carry. It grows with listing age and cumulative notional, so a cross-sectional rank on it mixes carry with size and history; use funding\_paid\_7d (the funding accumulated over the trailing window, widened by window\_days) or funding\_rate\_7d\_avg (the window's mean rate) for the interval-sized signal. | | `d_open_interest` | base units 1d · 1h | Change in open interest over the completed interval — net risk added or removed. NULL when the previous interval's snapshot is missing, so it is never a multi-interval change labelled as one interval. | | `funding_paid_7d` computed | fraction (of notional) 1d · 1h | Funding accumulated over the trailing 7 days — what a constant position of one unit of notional paid (positive) or earned (negative) in funding across the window (widened when window\_days is passed). This is the sum, not the mean: funding\_rate\_7d\_avg is this accumulation divided by the window's completed-interval count, so the two agree exactly only for a market that published every interval in the window — a market with holes in its funding series carries a smaller sum than its own average rate implies. A market whose funding source has no reading anywhere in the window is null rather than zero. | | `funding_rate_7d_avg` computed | fraction (of notional per interval) 1d · 1h | Average funding over the trailing 7 days, normalized by the selected grain's completed-interval count (widened when window\_days is passed). Positive means longs paid. | | `funding_rate_mean` | fraction (hourly rate) 1d · 1h | Mean funding rate for the completed interval. Positive means longs paid shorts on average — the crowd was long and paid for it. The venue's neutral print is +0.00125%/h (≈ +11%/yr) and a large block of markets prints exactly that, so a percentile or z-score of funding ties across the block; compare a market's rate against the neutral print rather than expecting a ranking to separate it. | | `pnl_imbalance` computed | ratio 1d · 1h IC 0.0306 @24h · retention 0.785 | The interval's realised close PnL split by the side that booked it, as a share of the gross PnL booked by both sides. Exactly +1 when shorts finished net-positive and longs net-negative, exactly -1 in the mirror case, and an intermediate value only when both sides finished the same way (both up or both down) — so read it as which side won the interval, not as a graded magnitude. It is a sign, not a score: whenever the two sides' PnL have opposite signs the reading is exactly ±1, so a large block of markets can tie at the maximum. Positive means the short side won the interval — the price fell over the positions it closed, not necessarily over the interval; negative means the long side won. A zero reading means neither side realised anything and is reported as null. Holds the interval's own row only, so it describes what already happened rather than predicting what comes next. For a graded measure, read the stored closed\_pnl\_long and closed\_pnl\_short instead. Do not order or rank a cross-section on it — ranking on pnl\_imbalance ranks on a sign; use a continuous factor for ordering. | | `whale_long_account_share` | ratio 1d · 1h IC 0.0318 @24h · retention 1.005 | What fraction of the whale cohort is on the long side, by head-count. | | `whale_net_position` | base units 1d · 1h | Net signed size of the whale cohort, in coin size. Positive means the biggest accounts are net long. | ## Momentum A short-term reversal that survives the delay, but is small and often below round-trip cost. | Field | Unit · grain | What it means | | --- | --- | --- | | `ret_1h` | fraction 1h IC -0.0152 @24h · retention 0.682 | The completed hour's return: close divided by the previous published hour's close, minus 1. | ## Microstructure Real at the bar, gone after the entry delay — contemporaneous with the bar’s own move, not predictive. | Field | Unit · grain | What it means | | --- | --- | --- | | `oi_change_pct_1h` computed | fraction 1h IC -0.0271 @1h · retention 0.34 | Change in USD open interest over the hourly interval ending at the row's timestamp, as a FRACTION of the level it opened at: 0.347 is +34.7%, not +0.347%. Multiply by 100 for a percentage. | | `taker_imbalance_vw_1h` computed | ratio 1h IC -0.0226 @1h · retention 0.066 | Notional-weighted taker imbalance over exactly 1 completed hourly interval: aggressor\_delta × vwap divided by usd\_volume. | ## No signal Measured on its own; the order-flow hypothesis did not hold. There is no edge to decay. | Field | Unit · grain | What it means | | --- | --- | --- | | `aggressor_delta` | base units 1d · 1h | Net aggressive pressure during the completed interval: buy volume minus sell volume. Positive means buyers leaned on the book harder than sellers. | | `net_taker_open` | base units 1d · 1h | Net new aggressive directional risk: long opens minus short opens by takers during the completed interval. | | `net_taker_open_over_oi` computed | ratio 1d · 1h IC -0.005 @1h · retention 0.88 | The selected interval's net aggressive directional risk as a share of open interest — the taker tilt, normalized. | | `taker_flip_l2s` | base units 1d · 1h | Aggressive long-to-short flip volume — a capitulation tell (longs giving up and flipping). | | `taker_flip_s2l` | base units 1d · 1h | Aggressive short-to-long flip volume — a squeeze tell (shorts giving up and flipping). | ## Other fields Stored and descriptive fields that were never measured on their own, so they carry no signal class. | Field | Unit · grain | What it means | | --- | --- | --- | | `buy_vol` | base units 1d · 1h | The slice of volume where the aggressor was buying (lifting the offer). Demand pressure. | | `close` | USD 1d · 1h | Price at the end of the completed interval — the one most people mean by 'the price'. | | `closed_pnl_long` | USD 1d · 1h | Realized profit or loss booked by longs during the completed interval. | | `closed_pnl_short` | USD 1d · 1h | Realized profit or loss booked by shorts during the completed interval. | | `coin` | symbol 1d · 1h | Which market the row is for. A bare symbol for crypto perps; HIP-3 markets carry their deployer prefix, e.g. xyz:NVDA. | | `concentration_skew` | ratio 1d · 1h | Short-side concentration minus long-side concentration (top10\_short\_share − top10\_long\_share). Positive means the shorts are the whale-heavy side — the one more prone to a squeeze. | | `day` | date 1d | The UTC day the row covers. | | `flow_vs_snapshot_oi_residual` | base units 1d · 1h | The gap between the completed interval's open-interest change and the change taker flow explains. What's left is mostly the maker side — passive positioning the trade tape can't show. | | `funding_hours` | count 1d | How many hourly funding observations the day's figures are built from (sparse on some HIP-3 venues). | | `funding_paid` | fraction (of notional) 1d · 1h | Funding rates summed over the completed interval — the share of notional a position held across the interval paid (positive) or earned (negative). | | `funding_rate_delta_1h` computed | fraction (hourly rate) 1h | Current funding rate minus the immediately previous published hour's funding rate. | | `funding_rate_max` | fraction (hourly rate) 1d | The day's highest hourly funding rate. | | `funding_rate_min` | fraction (hourly rate) 1d | The day's lowest hourly funding rate. | | `funding_rate_sum_24h` computed | fraction (of notional) 1h | Sum of the current and 23 immediately prior published hourly funding rates. | | `funding_sign_change_1h` computed | boolean fraction 1h | 1 when the current and immediately previous published hourly funding rates have different signs, 0 when their signs match, and NULL when either rate is missing. | | `hhi_gross` | ratio 1d · 1h | A standard market-concentration score over all exposure — high when a handful of accounts dominate the book. | | `high` | USD 1d · 1h | Highest trade price during the completed interval. | | `hour` | timestamp 1h | The completed UTC hour the row covers. | | `low` | USD 1d · 1h | Lowest trade price during the completed interval. | | `maker_fees` | USD 1d · 1h | Fees paid — or rebates earned — on the passive side (makers). | | `n_closed_longs` | count 1d · 1h | Accounts that closed a long during the completed interval. NULL when the previous interval's snapshot is missing, so it is never a multi-interval count labelled as one interval. | | `n_closed_shorts` | count 1d · 1h | Accounts that closed a short during the completed interval. NULL when the previous interval's snapshot is missing, so it is never a multi-interval count labelled as one interval. | | `n_flipped_l2s` | count 1d · 1h | Accounts that flipped from long to short — a sentiment reversal, one account at a time — during the completed interval. NULL when the previous interval's snapshot is missing, so it is never a multi-interval count labelled as one interval. | | `n_flipped_s2l` | count 1d · 1h | Accounts that flipped from short to long during the completed interval. NULL when the previous interval's snapshot is missing, so it is never a multi-interval count labelled as one interval. | | `n_long_positions` | count 1d · 1h | How many accounts held a long at the completed interval's close. | | `n_new_longs` | count 1d · 1h | Accounts that opened a fresh long during the completed interval. NULL when the previous interval's snapshot is missing, so it is never a multi-interval count labelled as one interval. | | `n_new_shorts` | count 1d · 1h | Accounts that opened a fresh short during the completed interval. NULL when the previous interval's snapshot is missing, so it is never a multi-interval count labelled as one interval. | | `n_short_positions` | count 1d · 1h | How many accounts held a short at the completed interval's close. | | `n_unique_users` | count 1d · 1h | How many distinct accounts held any position — the breadth of participation. | | `n_whale_accounts` | count 1d · 1h | How many accounts make up the whale cohort (the top 10% by position size). | | `net_taker_flow_7d` computed | base units 1d · 1h | Net aggressive pressure summed over the trailing 7 days (widened when window\_days is passed): buy-minus-sell taker flow. Base units, so it scales with the market's size — use taker\_imbalance\_7d to rank markets of different sizes against each other. | | `oi_change_over_volume_4h` computed | ratio (USD ÷ USD) 1h | USD open-interest change summed over exactly 4 completed hourly intervals divided by USD traded notional over the same interval. | | `oi_change_over_volume_7d` computed | ratio (USD ÷ USD) 1d · 1h | Open-interest notional added over the trailing 7 days divided by average traded notional for the selected grain — higher means open interest is growing faster than the volume trading it; 1.0 means OI grew by a full interval's turnover. | | `oi_change_pct_4h` computed | fraction 1h | The same for the four-hour interval ending at the row's timestamp, as a FRACTION: 0.347 is +34.7%. Multiply by 100 for a percentage. | | `oi_change_z_30d` computed | z-score 1d · 1h | How unusual the completed interval's open-interest change is against its own trailing 30-day distribution, in standard deviations. | | `oi_closed` | base units 1d · 1h | Aggressive volume that closed positions — flow-implied OI removed. | | `oi_open` | base units 1d | Open interest at the day's own 00:00 boundary — the level the day started from. NULL when the coin had not started trading by that instant (its first snapshot came later), rather than a later hour's level presented as the day's open. | | `oi_opened` | base units 1d · 1h | Aggressive volume that opened positions — flow-implied OI added. | | `oi_over_volume` computed | ratio 1d · 1h | Open-interest notional divided by traded notional for the selected interval — how much risk sits on the book per unit of turnover. High means a market is crowded relative to its liquidity. | | `oi_usd` | USD 1d · 1h | Open interest at the completed interval's close in USD notional (open\_interest × close) — the cross-comparable open-interest figure, one-sided like open\_interest. | | `open` | USD 1d · 1h | Price at the start of the completed interval. | | `open_interest` | base units 1d · 1h | Size of open positions at the completed interval's close, in coin size, counting each contract once (the classical one-sided convention). The venue's own API and UI sum both sides instead, so their open-interest figure is twice this one. Rising means new money committing; falling means positions unwinding. | | `range_pct` | fraction 1d · 1h | The completed interval's high-to-low range as a share of its opening price. | | `ret_1d` | fraction 1d | The day's return: close divided by the previous day's close, minus 1. | | `ret_24h` computed | fraction 1h | Compounded close-to-close return over exactly 24 completed hourly intervals. | | `ret_30d` computed | fraction 1d · 1h | Cumulative return over the trailing 30 days. | | `ret_4h` computed | fraction 1h | Compounded close-to-close return over exactly 4 completed hourly intervals. | | `ret_7d` computed | fraction 1d · 1h | Cumulative return over the trailing 7 days (widened when window\_days is passed). | | `sell_vol` | base units 1d · 1h | The slice of volume where the aggressor was selling (hitting the bid). Supply pressure. | | `taker_close_long_vol` | base units 1d · 1h | Aggressive volume that closed existing longs — longs taking profit or cutting. | | `taker_close_short_vol` | base units 1d · 1h | Aggressive volume that closed existing shorts — shorts covering. | | `taker_fees` | USD 1d · 1h | Fees paid by the aggressive side (takers). | | `taker_imbalance_7d` computed | ratio 1d · 1h | Net aggressive pressure over the trailing 7 days as a share of the volume that produced it (widened when window\_days is passed): buy-minus-sell taker flow divided by total traded volume. Runs from -1 (every trade a taker sell) to +1 (every trade a taker buy), and is price- and size-independent, so it compares across markets. It weights every completed interval equally — see taker\_imbalance\_vw\_7d for the notional-weighted form. | | `taker_imbalance_vw_24h` computed | ratio 1h | Notional-weighted taker imbalance over exactly 24 completed hourly intervals: summed aggressor\_delta × vwap divided by summed usd\_volume. | | `taker_imbalance_vw_4h` computed | ratio 1h | Notional-weighted taker imbalance over exactly 4 completed hourly intervals: summed aggressor\_delta × vwap divided by summed usd\_volume. | | `taker_imbalance_vw_7d` computed | ratio 1d · 1h | The same net aggressive pressure over the trailing 7 days, weighting each completed interval by the notional that traded in it rather than by base units (widened when window\_days is passed): the imbalance of the window's flow rather than the mean of its intervals. The two are different quantities, not two estimates of one — they separate on a market whose aggression concentrates into a few heavy intervals — and this is the form the taker-flow research book ranks on. | | `taker_open_long_vol` | base units 1d · 1h | Aggressive volume that opened new long positions — fresh long risk entering. | | `taker_open_short_vol` | base units 1d · 1h | Aggressive volume that opened new short positions — fresh short risk entering. | | `top10_long_share` | ratio 1d · 1h | How much of the long side is held by its ten biggest accounts — high means the longs are a few whales, not a broad crowd. | | `top10_short_share` | ratio 1d · 1h | The same concentration measure for the short side. | | `total_fees` | USD 1d · 1h | All trading fees paid during the completed interval. | | `trade_count` | count 1d · 1h | How many individual trades happened during the completed interval — a proxy for activity and fragmentation. | | `usd_volume` | USD 1d · 1h | Traded notional during the completed interval: each source bar's vwap multiplied by its volume and summed. | | `usd_volume_7d_avg` computed | USD 1d · 1h | Average traded notional per completed interval over the trailing 7 days (widened when window\_days is passed). | | `vol_30d` computed | fraction 1d · 1h | Standard deviation of interval returns over the trailing 30 days, annualized by the grain-derived square root of 365 daily intervals or 8,760 hourly intervals. | | `volume` | base units 1d · 1h | How much traded during the completed interval, in coin size (base units). | | `vwap` | USD 1d · 1h | The completed interval's volume-weighted average price (usd\_volume / volume) — a fairer 'where did it actually trade' than the close. | [The intelligence layer](https://tesseralytics.dev/mcp-server) [Read the research](https://tesseralytics.dev/blog/mcp-cross-section) --- Source: https://tesseralytics.dev/mcp-server Model Context Protocol # The Hyperliquid MCP server for cross-sectional market intelligence Point Claude — or any MCP client — at one endpoint and ask market questions in plain language. Nine tools: discover the catalog and the field vocabulary, then rank the cross-section, screen on several conditions, measure funding divergence, pull per-coin series and read the live market. POST https://tesseralytics.dev/mcp [Get an API key](https://tesseralytics.dev/account) [Open the playground](https://tesseralytics.dev/playground) No card required — a free key ranks every market over the trailing week. tessera.mcp · claude 9 tools · 3 open { day: "2026-09-15", columns: \["ret\_1d", "funding\_rate\_mean"\], order\_by: "ret\_1d", descending: false, top\_n: 5 } #CoinDayFunding /h 1 XRP −-9.89% +0.00123% 2 LIT −-8.39% +0.00125% 3 XLM −-8.21% +0.00075% 4 VVV −-7.83% +0.00189% 5 CRV −-7.76% +0.00116% 33 of 234 markets ranked as of 2026-09-15 { window\_days: 30, benchmark: "ETH", metric: "rate", top\_n: 5 } → the widest spread in each direction — the most expensive carry and the cheapest · markets with no funding in the window are dropped, not zeroed { bar: "1h", coins: \["BTC"\], window\_days: 1, columns: \["ret\_1h", "usd\_volume", "net\_taker\_open", "d\_open\_interest"\] } → one row per completed hour — hourly return, volume, taker flow and open-interest change · the exact completed hour and source are named { coins: \["BTC"\] } → mark price, funding, open interest, 24-hour volume, premium — as of the moment you ask · a market the venue can’t return is noted, not fatal Every historical answer names the completed daily or hourly grain it covers and the slice it ranked. The ranked rows above are a real capture of the venue’s public API on 2026-09-16 — 234 markets listed, 33 clearing $5M daily notional on 2026-09-15. The other replies state the call’s arguments and the shape of what comes back. ## What you can ask, and what comes back Eight questions the intelligence layer answers today. Each maps to one shipped tool, and each response names the completed grain it covers, its source and the population it evaluated. You ask ### Which coins are most crowded on funding? query\_cross\_section The model calls it with `order_by` on funding, descending, and `top_n` — no day given, so it resolves to the last complete day and the response says which day that is. Add `stat=percentile` to rank by the percentile within your eligible population instead of the raw rate. → one row per market, ranked · the day it covers · how many markets were ranked You ask ### Which coins are crowded relative to their own liquidity? query\_cross\_section Same call, a second factor: rank on `oi_over_volume` — open-interest notional per unit of the day’s traded notional — and a quiet market carrying a heavy book moves ahead of a busy one the same size. Ask for `stat=zscore` as well and each row carries how far that ratio sits from the rest of your eligible population, in standard deviations, which is what makes the number comparable across markets. → one row per market, ranked by crowding · the z-score of that ratio · the day it covers You ask ### Show me coins with top-decile funding but bottom-decile changes in open interest. screen\_universe A multivariate screen: one call with two conditions — funding in the top decile and the change in open interest in the bottom decile. Deciles use the eligible population after any coin or liquidity filter, and the response separates visible, eligible and matched counts. → only the matches · visible / eligible / matched population counts You ask ### Which coins’ funding has diverged most from ETH this month? funding\_divergence A 30-day window with ETH as the benchmark, ranked by divergence: either the average rate spread or the cumulative spread, your choice. Coins with no funding in the window are excluded from the ranking rather than shown as zero. → ranked spreads · coins with no funding in the window dropped, not zeroed You ask ### Find potential short squeezes — open interest climbing while funding goes negative. screen\_universe Another screen: open interest rising over the trailing week, paired with funding in the bottom decile. A positioning screen like this is exactly what the daily grain is for — the crowded side shows up in the cross-section before it shows up in price. → the crowded side of the book, named You ask ### How much of the market do you actually cover? get\_universe The coverage picture: the latest completed daily or hourly grain, how many coins are represented for each scope, row density and completeness facts. The default scope is crypto; pass `hip3` for HIP-3 markets, which carry a venue prefix like `xyz:NVDA` and, because they track an underlying that closes, come with a session caveat — their weekend flow isn’t comparable. → latest completed grain · represented coins by scope · row density · completeness facts You ask ### Is BTC’s move over the past week backed by real flow? query\_series A 7-day trailing window for BTC, returning return, volume, taker flow and open-interest change per day. The response always notes how many days the trailing-window figures were computed over, and asks for fewer coins or a shorter window rather than silently truncating if the payload would blow the row cap. → one row per day · the number of days actually covered You ask ### What’s BTC trading at right now? live\_market Mark price, current funding, open interest, 24-hour volume and premium, as of the moment you ask. This is the only tool that answers a “right now” question; everything else is a complete day or completed hour. Pass up to 25 coins and any coin the venue can’t return is dropped with a note explaining why, rather than failing the whole call. → as of now · any market the venue can’t return is noted, not fatal And because MCP composes ### Plug in a second server and ask across both MCP tools compose, so you can add a *second* MCP server or skill — say one that reads a venue like Boros or Derive — and ask things like “given Tessera Analytics’ cumulative BTC funding for the past month, which Boros funding markets look mispriced?” The model pulls the funding series from Tessera Analytics and cross-references the other tool. *This is a usage example only — the venue connector is yours to bring; Tessera Analytics doesn’t ship or endorse one, and none of this is trading advice.* Runnable Every question above is one tool call. The playground runs them with no key at all — the server answers in this browser on the anonymous trial, and the reply is its own, not a capture. [Run one of them now →](https://tesseralytics.dev/playground) ## A raw-row wrapper is not an intelligence layer Most perp-data MCP servers hand the model rows and leave the thinking to it: a candle, a funding print, an open-interest number. That works for “what’s the funding”, and collapses on “which coins are crowded relative to the rest of the market” — the model can’t rank a universe it can’t hold. Raw rows The model pages through per-coin endpoints, then tries to compute a cross-section in context — burning tokens on arithmetic it will get subtly wrong. Tessera intelligence layer The cross-section is computed where the data is: one call returns the ranked answer, its percentile or z-score, the day it covers and how many coins it was computed over. The intelligence layer cannot page raw rows, by design — row access stays on the [REST API](https://tesseralytics.dev/api-docs). Discovery tools need no key; the analytics tools take yours and rank only the slice your plan can see. ## Get connected First [create an API key](https://tesseralytics.dev/account). Then wire it into your client — replace `YOUR_TESSERA_API_KEY` with your key. Claude Code One command — native streamable-HTTP transport with a header. ``` claude mcp add --transport http tessera https://tesseralytics.dev/mcp \ --header "Authorization: Bearer $TESSERA_API_KEY" ``` Clients with native header auth For MCP clients that accept a remote URL plus custom headers, add this to your MCP config. ``` { "mcpServers": { "tessera": { "type": "http", "url": "https://tesseralytics.dev/mcp", "headers": { "Authorization": "Bearer YOUR_TESSERA_API_KEY" } } } } ``` Claude Desktop (via mcp-remote) Some desktop clients don't yet send custom headers to remote servers. The `mcp-remote` bridge proxies the connection and injects your key. Add this to `claude_desktop_config.json`, then restart the app. ``` { "mcpServers": { "tessera": { "command": "npx", "args": [ "-y", "mcp-remote", "https://tesseralytics.dev/mcp", "--header", "Authorization: Bearer ${TESSERA_API_KEY}" ], "env": { "TESSERA_API_KEY": "YOUR_TESSERA_API_KEY" } } } } ``` ## The nine tools Three open discovery tools, six keyed analytics tools. Discovery works without a key; the analytics tools take your API key and see only your plan's slice of the market. ### Open — no API key Discovery. These answer before you sign in, so an assistant can learn the vocabulary first. | Tool | Arguments | What it answers | | --- | --- | --- | | list\_datasets | — | Every dataset you can access, with a one-line summary and the plan it needs. | | describe\_dataset | asset | One dataset in full: each column’s type, nullability and plain-English meaning. | | list\_fields | | Every field the query tools accept, with its meaning, unit and exact daily/hourly availability. | ### Analytics — key or trial Analytics. These need a key, or answer on a small anonymous trial without one — your plan’s slice is enforced either way and cannot be widened. | Tool | Arguments | What it answers | | --- | --- | --- | | query\_cross\_section | bar? (1d | 1h on Pro), day (YYYY-MM-DD | RFC3339 hour | latest), columns\[\], order\_by, top\_n, scope? | Rank the whole market on one complete daily or hourly bar — top coins by funding, returns, volume and more. Add stat? for a percentile or z-score instead of the raw value. | | screen\_universe | bar? (1d | 1h on Pro), day (date | RFC3339 hour | latest), conditions\[\], columns\[\], max\_results, scope? | Screen on several conditions at once — e.g. top-decile funding with bottom-decile open-interest change. | | funding\_divergence | bar? (1d | 1h on Pro), window\_days, benchmark? (default ETH), metric?, top\_n, scope? | Which coins’ funding is diverging from a benchmark over a trailing window at the selected grain. | | get\_universe | bar? (1d | 1h on Pro), day? (date | RFC3339 hour | latest), scope?, top\_n? | The coverage picture for the latest completed grain: represented coin counts by scope, row density and completeness facts. | | query\_series | bar? (1d | 1h on Pro), coins\[\] (≤10), window\_days, columns\[\], ending\_day? (date | RFC3339 hour | latest) | A trailing daily or completed-hour series for one or a few coins — is this move backed by real flow? | | live\_market | coins\[\] (≤25) | Right now: price, funding, open interest, 24-hour volume and premium. The only “now” tool. | ## How an answer behaves ### Three clocks: live, hourly, daily The intelligence layer answers at three grains, and they are not the same freshness. `live_market` reads the venue *now*; the `1d` cross-section is the last complete UTC day; the `1h` cross-section is the newest *published* hour — which is not the newest hour, because the rollup lands roughly 1.5–2.5 hours behind the bar it describes. The hourly grain is **state, not timing**. Omit `bar` or pass `1d` for the last complete UTC day; the response says `bar: "1d"`, uses `tessera_daily`, and stamps `as_of` as `YYYY-MM-DD`. Pass `bar: "1h"` for the latest listed completed UTC hour; the response uses `tessera_hourly` and an RFC3339 `as_of` ending exactly at `:00:00Z`. Name a covered day or completed hour explicitly, or leave it as `latest`; requests outside the covered range return an explicit error rather than silent zeros. The hourly grain is the Pro one. A free key is answered at `bar: "1d"` and is told so by name if it asks for `bar: "1h"` — the daily cross-section is the whole free pitch, and the refused call is not counted against your daily allowance. Because the hourly feed publishes late, read it as a **state feed, not a timing feed**. Its durable value is 24-hour-horizon state — size, carry, positioning — plus *disconfirmation* of a thesis you already hold, not a fresh entry signal. The fast order-flow timing that decays within the hour is exactly what the publication lag leaves behind; the state that survives a 24-hour horizon is what the lag leaves intact. If you want 1h *timing*, that needs a lower-latency path, not this rollup. `live_market` is the only *now* tool — price, funding and open interest as of the moment you ask, stamped with the moment it was read. Every analytical response names the grain, source, completed timestamp and market scope. Its `visible_count` starts with the policy and scope population, `eligible_count` applies explicit coin and liquidity filters, and `matched_count` is the ranked or condition-satisfying result population. Rankings and screens are computed *within the eligible population*, so explicit filters change the denominator and a one-coin eligible slice is refused instead of returning a hollow percentile. ### Fields come from discovery Field names, meanings and units are not something you memorise: call `list_fields` (or ask for the vocabulary in plain language) and the model gets every column the query tools accept, each with a plain-English meaning, its unit and exact `1d` / `1h` availability. Discovery is free — pass those names straight into `columns`, a screen condition, or `order_by`. The whole vocabulary is also browsable on this site — the [field dictionary](https://tesseralytics.dev/datasets/fields). ## Free vs Pro ### Free Any valid API key can use the MCP server. A free key ranks every market over a trailing 7-day history, up to 20 tool calls a day — enough to explore the data end-to-end. No key at all? An anonymous trial answers up to 12 analytics calls an hour (20 a day) on the daily grain, with ranked lists clamped to 25 rows. ### Pro · $29/mo Full history, every market (incl. HIP-3), and the full funding and positioning record. Discovery tools show the whole catalog regardless of plan; a market the layer does not carry comes back empty with the reason stated — the slice is never widened to fill it. [Get an API key](https://tesseralytics.dev/account) [Compare plans](https://tesseralytics.dev/pricing) --- Source: https://tesseralytics.dev/playground MCP playground # Ask the intelligence layer a real question These are not screenshots. Each question is one real tool call to the shipped MCP server at tesseralytics.dev/mcp — the same endpoint your agent connects to. ## 7 questions, each a real call to /mcp tessera.mcp · playground anonymous trial No key, no signup — these run on the anonymous trial Every market at the daily grain over the trailing 7 days, ranked lists up to 25 rows, 12 calls an hour and 20 a day from this address. Each answer names its own limits; a free key raises the lists to 100 rows and Pro adds the hourly grain and full history. [Get a free key](https://tesseralytics.dev/signup) [See plans](https://tesseralytics.dev/pricing) 1. query\_cross\_section ### Which markets are paying the most to hold a long? Markets trading at least $5M a day, ranked by mean hourly funding on the last complete day and shown as an annualised rate. Funding is a step function, not a smooth score: the venue's neutral print is about 11%/yr and a large block of markets prints exactly that, so the list ties from the fifth row down. Only the head is actually crowded — which is the finding, not a gap in the data. Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_cross_section", "arguments": { "order_by": "funding_rate_mean", "descending": true, "top_n": 10, "min_usd_volume_7d_avg": 5000000, "columns": [ "coin", "funding_rate_mean", "usd_volume_7d_avg", "oi_usd" ] } } }' ``` 2. query\_cross\_section ### Which HIP-3 markets are trading the most? Markets that track an underlying trading elsewhere — equities, commodities, oil, semis — ranked by average daily notional over the last week, with their return and what longs are paying. They are 39% of the universe and invisible to a crypto-only view. Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_cross_section", "arguments": { "scope": "hip3", "order_by": "usd_volume_7d_avg", "descending": true, "top_n": 10, "columns": [ "coin", "usd_volume_7d_avg", "ret_1d", "funding_rate_mean" ] } } }' ``` 3. query\_cross\_section ### Where is open interest moving out of character? Ranked by how many standard deviations each market's open-interest change sits from its own last 30 days — a tell that a position is being built or unwound, not just a big book. The percentile column places that move against the other markets above $5M/day, which is what stat: percentile computes. Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_cross_section", "arguments": { "order_by": "oi_change_z_30d", "descending": true, "top_n": 10, "stat": "percentile", "min_usd_volume_7d_avg": 5000000, "columns": [ "coin", "oi_change_z_30d", "oi_usd", "usd_volume_7d_avg" ] } } }' ``` 4. screen\_universe ### Where are longs paying up while open interest drains? Two conditions, both required: funding in the top decile of the floored slice AND open-interest change per unit of traded notional in the bottom half. Longs paying up while the book empties is a squeeze forming — and the conditions are measured over the $5M/day population, not over the dust. Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "screen_universe", "arguments": { "min_usd_volume_7d_avg": 5000000, "conditions": [ { "column": "funding_rate_7d_avg", "op": "top_pct", "value": 10 }, { "column": "oi_change_over_volume_7d", "op": "bottom_pct", "value": 50 } ], "columns": [ "coin", "funding_rate_7d_avg", "oi_change_over_volume_7d", "usd_volume_7d_avg" ], "order_by": "funding_rate_7d_avg", "descending": true, "max_results": 10 } } }' ``` 5. funding\_divergence ### Which markets' funding is furthest from ETH's? Each market's mean hourly funding over the trailing week minus ETH's, both directions, within the $5M/day population — with the liquidity beside it, because the widest spread in the cross-section is usually one quiet day pulling a seven-day mean in a market nobody can size. Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "funding_divergence", "arguments": { "benchmark": "ETH", "metric": "rate", "window_days": 7, "top_n": 5, "min_usd_volume_7d_avg": 5000000 } } }' ``` 6. query\_series ### Is BTC's recent move backed by real flow? BTC's last seven complete days: close, return, traded notional, taker-side open interest and the change in open interest. Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_series", "arguments": { "coins": [ "BTC" ], "window_days": 7, "columns": [ "close", "ret_1d", "usd_volume", "net_taker_open", "d_open_interest" ] } } }' ``` 7. query\_series ### The last 24 completed hours of BTC flow Pro The same question at the hourly grain, which needs a Pro key because the hourly plane is Pro-only: return, volume, taker flow and open-interest change per completed hour. The hourly grain is Pro-only, so this one is not sent keyless. [See plans](https://tesseralytics.dev/pricing) Run it yourself ``` curl -sS https://tesseralytics.dev/mcp \ -H "Authorization: Bearer $TESSERA_API_KEY" \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_series", "arguments": { "bar": "1h", "coins": [ "BTC" ], "window_days": 1, "columns": [ "ret_1h", "usd_volume", "net_taker_open", "d_open_interest" ] } } }' ``` The counts under each answer are the server's own populations: `eligible` is what survives your filters, and every rank, percentile and decile is computed inside it — so raising a floor changes the ranking rather than trimming its tail. ## Take the same call to your agent Each card carries the exact request it makes, so the one you care about moves to your own terminal unchanged — and once a card has run, its request is pinned to the day the answer described (`day`), which is what makes a read reproducible. The playground is a convenience over the same API, not a wrapper around it. ``` curl -sS https://tesseralytics.dev/mcp \ -H "Content-Type: application/json" \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_cross_section", "arguments": { "order_by": "funding_rate_mean", "descending": true, "top_n": 10, "min_usd_volume_7d_avg": 5000000, "columns": [ "coin", "funding_rate_mean", "usd_volume_7d_avg", "oi_usd" ] } } }' ``` [Client configs for Claude, Cursor and mcp-remote](https://tesseralytics.dev/mcp-server) ## What a key adds The trial above ran without one. A free key is the same data on a stable identity and a longer leash: ranked lists up to 100 rows instead of 25, 20 calls a day per key rather than per address. Pro is a different question set — full history, the hourly grain, no call cap. All three cover the whole universe, crypto and HIP-3. [Get a free key](https://tesseralytics.dev/signup) [See plans](https://tesseralytics.dev/pricing) --- Source: https://tesseralytics.dev/api-docs REST · OpenAPI # Hyperliquid API reference List the catalog, read a dataset's columns, and download any partition as Parquet — the agentless path to the same data the MCP intelligence layer serves. Authenticate `/v1` requests with your API key as a bearer token. [Download OpenAPI spec](https://tesseralytics.dev/v1/openapi.json) [Get a free API key](https://tesseralytics.dev/account) Two auth paths `/v1` takes a raw API key; `/account` takes a signed-in session. The public `/v1/catalog` endpoints need neither. Generate a client Feed the spec to `openapi-generator` or `openapi-typescript` — or use the official [SDKs](https://tesseralytics.dev/sdks). ``` curl https://tesseralytics.dev/v1/datasets/gold_ohlcv_1m/BTC/2026-05/download \ -H "Authorization: Bearer $TESSERA_API_KEY" \ -o btc_2026-05.parquet ``` A closed month is one file; the current month is one file per day so far. Every download is a presigned URL behind that endpoint — there is no per-GB fee, so pull the history as often as you need. ## Endpoints Live operations, generated from the service itself. Try them with your key, or read them to generate a client. --- Source: https://tesseralytics.dev/pricing Pricing # Hyperliquid data pricing — subscribe for freshness, or buy the history once Free tier: the trailing month of minute OHLCV for BTC, ETH, SOL & HYPE. Pro unlocks every dataset and market. Or buy closed history once — from $19, no subscription. [Subscribe Pro · **$29/mo** — full history, every market, the intelligence layer ](#plans)[Buy once One-off bundles **from $19** — closed months, yours permanently ](#bundles) Free $0 /mo Get started with no card. - Order-flow-enriched minute OHLCV - BTC, ETH, SOL & HYPE — trailing month - REST API + Parquet downloads - MCP: every market, daily bars, last 7 days (20 calls/day) [Sign up for a free API key](https://tesseralytics.dev/signup) Pro Recommended $29 /mo Everything in Free, plus full history on every coin. - Everything in Free - Full funding history — every coin - Funding & positioning data, all coins incl. HIP-3 - MCP: the full record, daily + hourly state bars, unlimited calls Every plan is all-you-can-eat — unlimited downloads, no per-GB fees. Pull the whole history as often as you like. ## One-off downloads — the closed months, bought once Sometimes you want the history without a subscription — so the closed months of all three datasets are sold as one-off bundles, frozen at purchase and yours to keep. Pick the slice you need; the open month is never included. Tessera Majors $19 once The four majors — BTC, ETH, SOL and HYPE. - $19 once — the smallest slice, so the cheapest way in. Flat, no per-GB fee. Markets 4 coins Pro already includes this today — a bundle is a perpetual copy you keep. Tessera HIP-3 (xyz) $24 once The xyz deployer’s perps — NVDA, GOLD, JPY and more. - $24 once — bigger than Majors, still less than a month of Pro. Flat, no per-GB fee. Markets The xyz deployer Pro already includes this today — a bundle is a perpetual copy you keep. Tessera All Markets $29 once Every coin we carry — from majors to the long tail. - $29 once — every coin, the same price as one month of Pro. Markets Every coin Pro already includes this today — a bundle is a perpetual copy you keep. Perpetual and account-scoped — every API key on your account inherits it, and cancelling a Pro subscription does not affect it. ## What is actually different Three entitlements decide everything — datasets, markets, and history depth — and the API applies them to every request. This is the whole table. | | Free | Pro · $29/mo | | --- | --- | --- | | Datasets | gold\_ohlcv\_1m — 1-minute order-flow OHLCV | All three, including gold\_funding\_1h and gold\_positioning\_1h | | Markets | BTC, ETH, SOL & HYPE | Every market, including HIP-3 builder perps | | History | The trailing month | Full history — October 2025 onward | | Intelligence layer | Every market, daily bars only, trailing 7 days — 20 tool calls/day | The full published record on the daily grain, plus the hourly state bar — unlimited calls Rankings are computed within the coins your plan can see, so they are relative to your own slice. | | REST API + Parquet downloads | Included | Included | | Python & Rust SDKs | Included | Included | | Downloads | All-you-can-eat — no per-GB fee | All-you-can-eat — no per-GB fee | Looking for the dataset-level detail? Each dataset page lists every column and its meaning — start at the [data catalog](https://tesseralytics.dev/datasets). ## Questions worth asking Do I need a card to start? No. Signing up gives you a free key immediately. On the REST API the free tier is a real slice, not a counted trial — a month of minute OHLCV on four markets. The intelligence layer is scoped tighter: a week of daily bars over every market with 20 tool calls a day, which is there to explore with rather than to study on. What exactly changes when I upgrade? Three things, all enforced by the API on every request: which datasets you can reach, which markets, and how far back the history goes. A free key sees gold\_ohlcv\_1m for BTC, ETH, SOL and HYPE over the trailing month; Pro sees every dataset, every market including HIP-3, and the full record. The MCP intelligence layer is scoped separately and differently: free ranks every market on the daily grain over the trailing 7 days with 20 tool calls a day, and Pro lifts both limits and adds the hourly cross-section — which is a state feed at a 24-hour horizon, not a timing signal. What happens if I ask for something outside my plan? You get a clear answer rather than silent zeros. A partition outside your slice returns 404 so the catalog shape stays opaque, and the MCP tools say the request requires Pro. Ranking tools refuse a one-coin slice instead of returning a hollow percentile. Can I see the schema before I pay? Yes — the whole catalog and every column meaning are public. Read them on the data catalog or call describe\_dataset over MCP without a key. How do I cancel? Self-serve from your account page, which opens the Stripe billing portal. Your key keeps working until the end of the period you have paid for. What is a one-off download bundle? A flat-priced, one-time purchase of the closed months of all three datasets, frozen the moment you buy — the open month is never included, and the scope never grows afterwards. All three bundles carry the same three datasets and differ only in the markets they cover: the four majors (BTC, ETH, SOL and HYPE), the xyz deployer’s perps (one of ten live HIP-3 deployers), or every coin we carry. The entitlement is perpetual and lives on your account — every API key you hold inherits it, and cancelling a Pro subscription does not affect it. Pro already includes the same content today, so a bundle is really a perpetual copy of what you can already reach. All Markets sits at $29 — the same as one month of Pro, deliberately: above that, subscribing for a single month and pulling the archive strictly dominates buying the bundle. So the trade reads as it should — same price, no commitment, the archive frozen as it stood. Subscribe instead if you want it to keep growing. Does a bundle include the intelligence layer? No. A bundle covers the REST API and the Parquet downloads — the three datasets over the closed months finalised at purchase. The MCP intelligence layer stays subscription-only: a bundle grants no MCP entitlement, so its tools are reachable on free and Pro exactly as they are today. Is there a rate limit? No edge rate limit. The REST API is built for full-history pulls — every partition is one file and there is no per-GB fee, so pulls are meant to be repeated. The MCP intelligence layer is the one place with a plan quota: a free key gets 20 tool calls a day, and Pro removes the cap. Start on the free key No card Create an account, make a key, and pull the trailing month of BTC minute candles in a few minutes — over MCP or over REST. [Get a free API key](https://tesseralytics.dev/signup) [Run a real query on the free tier →](https://tesseralytics.dev/playground) Check the data before you decide The catalog, the column meanings and the tool reference are all public — no key, no account. [Data catalog](https://tesseralytics.dev/datasets) [MCP tool reference](https://tesseralytics.dev/mcp-server) --- Source: https://tesseralytics.dev/faq # Frequently asked questions How the datasets are built, the caveats worth knowing before you backtest, and how plans and the API work. Still stuck? Email [info@tesseralytics.dev](mailto:info@tesseralytics.dev). [Get a free API key](https://tesseralytics.dev/account) [Browse the catalog](https://tesseralytics.dev/datasets) ## The name Tessera is Latin for a small tile — one piece of a larger picture. The product is shaped the same way. Two large tiles are the ways in: the MCP intelligence layer, which answers cross-sectional questions in one call, and the REST API, which hands you the Parquet files. Every dataset beneath them is a small tile — one exact piece of the market. [Browse the catalog](https://tesseralytics.dev/datasets) to see them. ## Getting started Sign up with Google or email — no card required for the free tier. Then open your [Account](https://tesseralytics.dev/account) page and create an API key. The raw key is shown **exactly once** at creation, so copy it somewhere safe. You can create more keys or revoke old ones at any time; revoked keys stop working immediately. Pass your key as a bearer token. List what you can access with: ``` curl -H "Authorization: Bearer $TESSERA_API_KEY" \ https://tesseralytics.dev/v1/datasets ``` See the full reference on the [API Docs](https://tesseralytics.dev/api-docs) page. For a **closed month** the `…/download` endpoint returns a **302 redirect** to a temporary download URL. Follow redirects (`curl -L`) to stream the file straight to disk, then load it with Polars, pandas or DuckDB. If you'd rather receive the URL itself instead of being redirected, send `Accept: application/json` and you'll get a JSON body with the link. The **current month** is still being written, so it is a set of per-day files instead of one — the same endpoint answers with JSON listing one URL per day. Fetch each and concatenate them. ## The data The datasets are **sparse, not gap-filled**. A bucket only exists if there was activity in it — so in `gold_ohlcv_1m`, a one-minute bucket with **no trades has no row at all** (rather than a zero-volume/flat-price row). The same applies to the hourly datasets. If your model needs a continuous time grid, resample or forward-fill on your side after downloading — that way you stay in control of how gaps are treated. All timestamps are **UTC** with microsecond (`µs`) precision. Each row's time column is the *start* of its bucket (e.g. the minute or hour bucket start). Every dataset is partitioned per `(coin, month)`. A **closed month is a single Parquet file**: download one `(coin, month)` file per request and concatenate months locally to assemble a longer history. The **current month is one file per day** (it is still being written, and a new day should not mean rewriting a whole month). Requesting it from the same `…/download` endpoint returns a list of URLs, one per day so far — fetch each and concatenate them in date order. Running totals — cumulative volume delta (CVD), cumulative funding, and similar — are **spliced continuously across month boundaries**. The first row of a month carries on from where the previous month ended, so the series is already continuous; do **not** reset it to zero when you stitch consecutive months together. NULL means "not defined for this row," not zero. For example `account_ls_ratio` is NULL when there are no shorts to divide by, and several concentration metrics are NULL when a side is empty. Each column's exact semantics are documented on the [Datasets](https://tesseralytics.dev/datasets) page. HIP-3 (Hyperliquid Improvement Proposal 3) lets anyone deploy a perpetual futures market on Hyperliquid. Most HIP-3 markets track real-world assets — equity ETFs like `xyz:NVDA`, `xyz:TSLA`, `xyz:QQQ`, commodity ETFs like `xyz:GLD`, and crypto-native tokens deployed by third-party builders. They trade alongside core perps with the same full-depth order book, settlement and liquidation mechanics — but on assets Hyperliquid itself doesn't list. HIP-3 markets are **Pro-only** and available from **September 2025**, covering every HIP-3 launch from day one. Core perps use their plain symbol (e.g. `BTC`, `ETH`). HIP-3 (builder-deployed) markets are namespaced by their deployer in lowercase, e.g. `xyz:NVDA`. HIP-3 markets are Pro-only. Data is refreshed **every hour**: each hour's trades reach the gold datasets about half an hour after the hour closes, so a UTC day is complete by roughly **00:30 UTC** the following day and the current day's bars are already available. Partitions are per `(coin, month)`, and the current partial month is included — it's rewritten every hour alongside the closed months. The public `/v1/catalog` manifest says exactly what is there: `is_open` marks the month still being written and `last_time` is the newest row it holds. There's **no formal SLA or uptime guarantee** and we don't issue credits for delays. Occasionally, yes. When upstream Hyperliquid data is missing for a window, that window is absent downstream too — it isn't synthesised or interpolated. This is rare, but worth handling defensively if your pipeline assumes unbroken coverage. ## Plans & billing **Free** gives you order-flow-enriched minute OHLCV (`gold_ohlcv_1m`) — CVD, aggressor delta, VWAP, fees and more — for BTC, ETH, SOL and HYPE over the trailing month, with no card required. **Pro** ($29/mo) unlocks **full history**, adds the raw funding (`gold_funding_1h`) and positioning (`gold_positioning_1h`) datasets, and opens **all coins, including HIP-3 markets**. See [Pricing](https://tesseralytics.dev/pricing). No. Every plan is all-you-can-eat — unlimited downloads, no per-GB egress fees. Pull the whole history as often as you like. A flat-priced, one-time purchase of the closed months of all three datasets — the newest month sold is the last one finalised when you buy, the open month is never included, and the scope never grows afterwards. All three bundles carry the same three datasets and differ only in the markets they cover: the four majors (BTC, ETH, SOL and HYPE), the markets of the xyz HIP-3 deployer only (one of ten live HIP-3 deployers), or every coin we carry. The entitlement is perpetual and lives on your account — every API key you hold inherits it, and cancelling a Pro subscription does not affect it. Pro already includes the same content today, so a bundle is a perpetual copy of what you can already reach. A bundle grants no MCP entitlement: the intelligence layer stays subscription-only. See [Pricing](https://tesseralytics.dev/pricing#bundles). If a coin or month falls outside your plan, the API returns **404** rather than 403. That's deliberate: it keeps the shape of the full catalog opaque to lower tiers. Upgrade to Pro to unlock funding, positioning and all coins. Upgrade from your [Account](https://tesseralytics.dev/account) page — checkout is handled by Stripe. The same page links to the Stripe billing portal, where you can update your card or cancel. Cancelling stops the renewal; your Pro access continues until the end of the current billing period, then reverts to Free. Fees are non-refundable — there are no partial refunds for the unused part of a period. ## API & formats Send your API key as a bearer token on every `/v1` request: `Authorization: Bearer `. Account management endpoints use your signed-in browser session instead. Everything is **Apache Parquet** — columnar, typed and compressed. It drops straight into Polars, pandas (`pd.read_parquet`) or DuckDB (`SELECT * FROM 'file.parquet'`) with no conversion. Download URLs are **short-lived** by design. If a link has expired, just call the `…/download` endpoint again to mint a fresh one. Don't cache or share the URL itself — cache the dataset file, not the link. --- Source: https://tesseralytics.dev/sdks Client SDKs # Query Hyperliquid data in your language Two official clients wrap the same REST API in typed bindings, so you never hand-roll HTTP or manage downloads. Both read Parquet straight over the wire — no temp files, projection and predicate pushdown to object storage. ``` pip install "tessera-api[polars]" ``` [Get an API key](https://tesseralytics.dev/account) [Raw HTTP reference](https://tesseralytics.dev/api-docs) ## Python tessera-api 0.1.2[](https://github.com/tesseralytics/python-client "View the source on GitHub") Sync and async clients over `httpx`, with typed response models. The base install carries only the transport; the extras pull in the engine you actually want, and a missing one raises with the exact install line. Install ``` pip install "tessera-api[polars]" ``` Swap the extra for `[duckdb]`, `[pandas]` or `[all]`. Needs Python 3.10+. Authenticate ``` export TESSERA_API_KEY="sk_..." ``` `TesseraClient()` reads it, or pass `api_key=`. Set `base_url` to point at another deployment. First query One month of minute candles for one coin, into a pandas or Polars frame. ``` import tessera client = tessera.TesseraClient() # reads $TESSERA_API_KEY df = client.read("gold_ohlcv_1m", "BTC", "2026-05") print(df.select("time", "close", "cvd").tail()) ``` SQL instead of DataFrames Ask for a span of months and query it like a table. ``` rel = client.to_duckdb("gold_ohlcv_1m", ["BTC", "ETH"], "2026-05") rel.filter("close > open").aggregate( "coin, avg(cvd) AS mean_cvd, count(*) AS n", "coin" ).show() ``` Lazy over many months `MonthSpan` expands to every partition in the range; nothing is read until you collect. ``` lf = client.scan( "gold_ohlcv_1m", coin=["BTC", "ETH"], month=tessera.MonthSpan("2026-01", "2026-05"), columns=["time", "close", "aggressor_delta"], ) lf.filter(pl.col("cvd") > 0).collect() ``` Async `AsyncTesseraClient` mirrors every method with `await`. ``` async with tessera.AsyncTesseraClient() as client: df = await client.read("gold_ohlcv_1m", ["BTC", "ETH"], "2026-05") ``` ## Rust tessera-api 0.1.0[](https://github.com/tesseralytics/rust-client "View the source on GitHub") The crate is published as `tessera-api` but imports as `tessera`. Polars is the default feature; DuckDB is opt-in, and turning it on is what swaps the engine, so Cargo.toml has to say which one you want. Needs Rust 1.85+. Install ``` cargo add tessera-api ``` That gives you Polars. For DuckDB instead, replace the dependency line: ``` tessera-api = { version = "0.1", default-features = false, features = ["duckdb"] } ``` First query Same shape as Python: construct, read, print. The constructor is where the key comes from. ``` use tessera::TesseraClient; fn main() -> Result<(), tessera::TesseraError> { let client = TesseraClient::new(None)?; // reads $TESSERA_API_KEY let df = client.read("gold_ohlcv_1m", "BTC", "2026-05", None)?; println!("{} rows", df.height()); Ok(()) } ``` `AsyncTesseraClient` is the async mirror, for use inside a Tokio runtime — the sync client builds its own runtime for the Polars cloud reads, so it must not be constructed from one. ## The same six calls, in both clients Neither client has per-dataset methods. Everything is addressed by the same `(asset, coin, month, columns)` tuple, which is why the API surface stays small as datasets are added — call `datasets()` to discover the names. | Call | Python returns | Rust returns | What it gives you | | --- | --- | --- | --- | | datasets() | DatasetsResponse | DatasetsResponse | Every dataset your plan can reach, with its visible coins and month range. | | partitions(asset, coin?, month?) | PartitionsResponse | PartitionsResponse | Which (coin, month) files exist — the honest way to find the newest month. | | scan(asset, coin, month, columns?) | pl.LazyFrame | LazyFrame | A lazy frame over one partition or many. Predicates and projections push down to storage. | | read(asset, coin, month, columns?) | pl.DataFrame | DataFrame | The same, eagerly collected. | | to\_duckdb(asset, coin, month, columns?) | DuckDBPyRelation | duckdb::Connection | The same partition set as SQL — a relation to query, or a connection exposing a view. | | download\_url(asset, coin, month) | DownloadResponse | DayDownloadResponse | DownloadResponse | DayDownloadResponse | Short-lived presigned URLs to fetch a partition yourself. A closed month is one URL; the current month is one per day. | When a span covers more than one partition, both clients append `coin` and `month` columns so every row stays attributable. Presigned URLs are short-lived (~15 minutes) — collect a lazy frame promptly, or you will get a presign-expired error rather than stale data. ## What your key decides The client does not hold entitlements; the API applies your plan to every request and filters what comes back. A span that reaches outside your slice is an error, not a silent truncation. Free No card - gold\_ohlcv\_1m — 1-minute order-flow OHLCV - BTC, ETH, SOL & HYPE - The trailing month Pro $29/mo - Every dataset, including gold\_funding\_1h and gold\_positioning\_1h - Every market, including HIP-3 - Full history — October 2025 onward Errors you can catch `tessera.TesseraError` is the base; `ForbiddenError` means your plan does not cover the slice, `AuthenticationError` means the key is wrong or missing, `NotFoundError` means the partition does not exist, and `PresignExpiredError` means re-issue the read. Rust returns one `TesseraError` enum with the same distinctions. Retries are built in Both clients retry 429 and 5xx with exponential backoff and honour `Retry-After` — three attempts by default, 30-second timeout. Python exposes `max_retries` and `timeout`; Rust exposes the same on `ClientConfig`. Not using Python or Rust? Both clients are thin wrappers over the same REST API, which is documented from its live OpenAPI schema — generate a typed client in any language, or call it directly. [Browse the API reference](https://tesseralytics.dev/api-docs) Every partition is also a plain Parquet download. See the [data catalog](https://tesseralytics.dev/datasets) for the columns. --- Source: https://tesseralytics.dev/blog Blog # Research notes and product updates How the Hyperliquid datasets are built, what the data actually says, and how to put it to work. [Get a free API key](https://tesseralytics.dev/account) [Browse the catalog](https://tesseralytics.dev/datasets) [ The state Hyperliquid's cross-section carries — and what an agent can't do with it Research 5 November 2026 Carry, positioning and size in Hyperliquid's daily cross-section keep their edge after a publication lag — order-flow timing doesn't. Gross IC, one regime, and the honest split for an MCP-connected agent. Read post → ](https://tesseralytics.dev/blog/mcp-cross-section)[ Download Hyperliquid data to your local machine: a step-by-step tutorial Tutorial 7 October 2026 Buy a one-off bundle, write a small Python tool with the SDK, run it with uvx, and persist data locally as Parquet or DuckDB. No subscription, no commitment — the data is yours. Read post → ](https://tesseralytics.dev/blog/one-off-download-tutorial)[ Best Hyperliquid data providers (2026) Comparison 9 September 2026 Compare the eight Hyperliquid data providers — Tessera Analytics, Hydromancer, L1 Ticks, 0xArchive, CoinGlass, Pinax, Moon Dev and FundingPulse — side by side, and find the right CoinGlass or L1 Ticks alternative for your workflow. Read post → ](https://tesseralytics.dev/blog/hyperliquid-data-providers)[ Smart money doesn't stay smart Research 3 July 2026 On a DEX every trade is signed by a wallet, so we can ask the obvious question: can you just copy the winners? We scored ~100,000 Hyperliquid wallets a month to find out — and the answer is a lesson in luck, skill and style. Read post → ](https://tesseralytics.dev/blog/wallet-behaviour)[ Forecasting Hyperliquid funding: a 10-minute tutorial Tutorial 2 July 2026 Pull hourly Hyperliquid funding with the Python SDK, measure how sticky it is, and build the innovation series that actually carries the forecast. Requires a Pro API key. Read post → ](https://tesseralytics.dev/blog/funding-forecast) --- Source: https://tesseralytics.dev/blog/funding-forecast [← Blog](https://tesseralytics.dev/blog) Tutorial 2 July 2026 # Forecasting Hyperliquid funding: a 10-minute tutorial Pull hourly Hyperliquid funding with the Python SDK, measure how sticky it is, and build the innovation series that actually carries the forecast. Requires a Pro API key. Perpetual funding on Hyperliquid *looks* easy to forecast. It's sticky: today's hourly rate is a good guess for tomorrow's. But "tomorrow ≈ today" is a **base rate**, not a forecast — anyone can read it off the last price. The real question is what's left *after* you subtract that stickiness. This is a follow-along tutorial. You'll need the Python SDK and a **Pro** API key (funding is a Pro dataset). By the end you'll have pulled real hourly funding, measured exactly how sticky it is, and built the **innovation** series — funding minus its own trailing average — which is where any genuine forecast has to live. ## Set up Install the SDK and export your key: ``` pip install "tessera-api[polars]" export TESSERA_API_KEY="..." # from https://tesseralytics.dev ``` Funding is a **Pro** dataset — a free key raises `tessera.ForbiddenError` on the read below. Get a Pro key from [pricing](https://tesseralytics.dev/pricing). ## Pull hourly funding `gold_funding_1h` is hourly funding, partitioned per (coin, month). Read BTC, ETH and SOL for six months, projecting just the columns we need: ``` import polars as pl import tessera client = tessera.TesseraClient() # reads $TESSERA_API_KEY funding = client.read( "gold_funding_1h", coin=["BTC", "ETH", "SOL"], month=tessera.MonthSpan("2026-01", "2026-06"), columns=["time", "coin", "funding_rate"], ) # Autocorrelation of hourly funding at increasing lags, per coin. lags = [1, 6, 12, 24, 72, 168] # hours def autocorr(s: pl.Series, h: int) -> float: # Pearson correlation of the series against itself, lagged by h rows. df = pl.DataFrame({"x": s.slice(0, s.len() - h), "y": s.slice(h)}) return df.select(pl.corr("x", "y")).item() rows = [] for coin in funding["coin"].unique().to_list(): s = funding.filter(pl.col("coin") == coin).sort("time")["funding_rate"] rows.append({"coin": coin, **{f"{h}h": round(autocorr(s, h), 3) for h in lags}}) pl.DataFrame(rows) ``` Funding is sticky — autocorrelation of hourly funding against itself, averaged over BTC, ETH and SOL. Close to 0.9 at a one-hour lag, fading to almost nothing within a week. That slow decay is the base rate: "tomorrow ≈ today". ## Subtract the stickiness Define the **innovation** as funding minus its own 7-day trailing mean (168 hourly bars). Persistence lives in the level; strip it off and see how much survives: ``` d = ( funding.sort("coin", "time") .with_columns( pl.col("funding_rate") .rolling_mean(window_size=168, min_samples=1) .over("coin") .alias("trailing_7d") ) .with_columns( (pl.col("funding_rate") - pl.col("trailing_7d")).alias("innovation") ) .drop_nulls() ) for name in ("funding_rate", "innovation"): s = d.filter(pl.col("coin") == "BTC").sort("time")[name] print(f"{name:>13} 24h: {autocorr(s, 24):.3f} 72h: {autocorr(s, 72):.3f}") ``` At the one-day lag the subtraction barely moves the number — `0.285 → 0.234`: the innovation still carries a little momentum of its own. At three days the picture flips — the raw level still autocorrelates at `0.122`, while the innovation is `0.001`. Past a day or so, essentially all of the level's stickiness was the trailing average; strip it and nothing multi-day survives. ## What that means "Tomorrow ≈ today" is doing almost all of the work. Persistence is a free base rate anyone can compute; subtract it and the forecastable leftover is small — and short-lived, with the innovation's autocorrelation dead inside about three days. That near-zero number is the honest size of the surprise: a feature to stack on a model you already have, not a buy/sell button. Everything above runs on one dataset — [the funding tile](https://tesseralytics.dev/datasets/gold_funding_1h) — pulled through [the SDK](https://tesseralytics.dev/sdks). [← Back to blog](https://tesseralytics.dev/blog) --- Source: https://tesseralytics.dev/blog/hyperliquid-data-providers [← Blog](https://tesseralytics.dev/blog) Comparison 9 September 2026 # Best Hyperliquid data providers (2026) Compare the eight Hyperliquid data providers — Tessera Analytics, Hydromancer, L1 Ticks, 0xArchive, CoinGlass, Pinax, Moon Dev and FundingPulse — side by side, and find the right CoinGlass or L1 Ticks alternative for your workflow. There isn’t one best Hyperliquid data provider — the right choice depends on what you’re building. Tessera Analytics ships clean, model-ready, order-flow-enriched Hyperliquid datasets, self-serve from $29/mo; L1 Ticks and 0xArchive sell raw order-level data for quants who build their own features; CoinGlass is a free dashboard with a paid API. This guide matches each provider to a use case. ## The field, side by side | Provider | Price | What they sell | Notes | | --- | --- | --- | --- | | Tessera Analytics (that’s us) | Free tier; Pro $29/mo | Clean, model-ready, order-flow-enriched Hyperliquid datasets (1m OHLCV, hourly funding, hourly positioning), via a self-serve REST API and Parquet. | The order-flow layer raw-data sellers make you build yourself. | | Hydromancer | From $300/mo | Low-latency Hyperliquid infrastructure: WebSocket streams (fills, orders, builder events), L2/L4 orderbook streaming with per-order addresses, and batch reads for up to 1,000 wallets per call. | The live-infrastructure layer for apps, bots and market makers — 100+ teams by their own count, with named customers VALR, HyENA and Native Markets. Also publishes Reservoir, a free raw archive (Parquet on S3): every fill, 1-second candles, daily position snapshots and order book snapshots — raw files rather than model-ready datasets. | | L1 Ticks | Paid subscriptions (10-perp archive, historical batches, BTC high-frequency tier); free = Kaggle samples | Raw Hyperliquid order flow — fills, L2 book snapshots, funding; standard 10-perp dataset as Zstd-compressed Parquet files. | Closest direct competitor. Raw data for quants who engineer their own features — no built-in signals. | | 0xArchive | — | L2 + L4 order-level Hyperliquid/HIP-3 data (per-order, cancels, lifecycle), 180+ builder markets; core-perp history to Apr 2023. | Deep raw microstructure + heavy technical blog. | | Pinax / The Graph Token API | — | Hyperliquid open-interest time series via the Graph Token API. | High-authority infra provider — OI is their strong suit. | | CoinGlass | Free; API from $29/mo | Free web dashboard — Hyperliquid futures vol/OI/pairs; paid multi-exchange API with Hyperliquid whale/wallet/positioning endpoints. | Generalist positioning platform — not Hyperliquid-native datasets. | | Moon Dev Data Layer API | Paid (bundled into the membership — no free tier shown on site) | Trading-course/bot ecosystem; a Hyperliquid data layer + liquidation data API (prices/funding/OI, OHLCV, tick) sold as part of its paid all-access membership. | Data overlaps part of the catalog, but it’s an add-on to a course business, not a self-serve data product. | | FundingPulse (Apify) | Cheap / pay-per-event | Real-time funding/OI across 6 exchanges incl. Hyperliquid. | “CoinGlass alternative.” Commodity multi-exchange funding. | Provider positioning and prices as published by each vendor — checked July 2026, re-checked September 2026 (CoinGlass, Pinax, 0xArchive, FundingPulse, Moon Dev). Hydromancer’s entry was added at their request and verified against their own site and docs in October 2026, then corrected to their own wording in November 2026. No one pays for a place in this table — our own row is labelled as ours. L1 Ticks’ site was unreachable at the re-check, so its entry reflects July 2026 and omits specifics we could not re-verify. Dash marks no public list price. Check the vendor before you buy — prices move. For completeness, the rest of the field: **thunderhead-labs’ `hyperliquid-stats`** is a free, open-source stats API for funding and OI — self-hostable OSS more than a product. And the generalists — **CoinAPI, Kaiko** — sell broad multi-exchange coverage at enterprise prices, with Hyperliquid as one line item. ## The providers in one line - **Tessera Analytics** — clean, order-flow-enriched datasets through a self-serve API, from $29/mo. - **Hydromancer** — the live-infrastructure layer for apps and market makers: low-latency streams, L2/L4 orderbook feeds with per-order addresses, batch reads for up to 1,000 wallets per call, and the free raw Reservoir archive (Parquet on S3). From $300/mo — [hydromancer.xyz](https://hydromancer.xyz). - **L1 Ticks** — raw fills, L2 snapshots and funding for 10 perp markets as Parquet files; built for quants who engineer their own features. - **0xArchive** — the deepest raw microstructure: L2/L4 order-level data across 180+ HIP-3 builder markets, with core-perp history back to Apr 2023 and a strong technical blog. - **Pinax / The Graph** — open-interest time series through the Token API; the easy path if your stack already speaks The Graph. - **CoinGlass** — the free dashboard everyone checks; its paid API covers Hyperliquid positioning, but it’s a generalist multi-exchange platform. - **Moon Dev** — a course/bot ecosystem whose Hyperliquid data layer is bundled into its paid membership; overlaps part of the catalog. - **FundingPulse** — cheap real-time funding and OI across six exchanges via Apify. ## How to choose Pick by the job in front of you: - **“I want to look at Hyperliquid funding and open interest.”** CoinGlass — free and instant. For data inside your own code, CoinGlass sells a paid multi-exchange API (from $29/mo) with Hyperliquid whale/wallet/positioning endpoints; Hyperliquid-native alternatives are Tessera Analytics for clean datasets, Pinax for OI on The Graph, and FundingPulse for cheap real-time funding across exchanges. - **“I’m prototyping and want free data.”** L1 Ticks’ Kaggle samples or thunderhead-labs’ open-source stats API — free gets you started; depth and history are what you pay for. - **“I’m a quant building my own features from raw events.”** L1 Ticks or 0xArchive — this is the case where the raw sellers are genuinely the best fit. - **“I want clean, model-ready data without building the feature layer.”** Tessera Analytics. If you like raw L1 Ticks-style data but would rather not build the order-flow enrichment yourself — the buy/sell split, CVD, fees, PnL, funding alignment — that gap is exactly where we sit: the L1 Ticks alternative, at a self-serve price. - **“I need many exchanges under one contract.”** The generalists (CoinAPI, Kaiko). You pay enterprise pricing for breadth you may not need. - **“I'm building a live app, bot or market-making stack.”** Hydromancer — low-latency streams, L2/L4 orderbook with per-order addresses and batch reads for up to 1,000 wallets per call. That is real-time infrastructure; if what you want is a finished feature layer over history, it is not what they sell, and it is what we do. ## Where Tessera Analytics fits Tessera Analytics is the order-flow layer: clean, model-ready, order-flow-enriched Hyperliquid datasets (1-minute OHLCV, hourly funding, hourly positioning), served through a self-serve REST API and Python SDK. The free tier gets you started on the majors; Pro ($29/mo) unlocks the full catalog — including HIP-3 builder-perp markets like `xyz:NVDA`. Browse what’s actually in the catalog, or check the current price — then decide with the table above. [Browse the catalog](https://tesseralytics.dev/datasets) [See pricing](https://tesseralytics.dev/pricing) [← Back to blog](https://tesseralytics.dev/blog) --- Source: https://tesseralytics.dev/blog/mcp-cross-section [← Blog](https://tesseralytics.dev/blog) Research 5 November 2026 # The state Hyperliquid's cross-section carries — and what an agent can't do with it Carry, positioning and size in Hyperliquid's daily cross-section keep their edge after a publication lag — order-flow timing doesn't. Gross IC, one regime, and the honest split for an MCP-connected agent. An MCP server that hands an agent a row of candles is a JSON wrapper with extra steps. The interesting question is whether the Hyperliquid cross-section — every coin's funding, positioning, open interest and order flow, on one completed bar — carries anything a machine can actually *act on* after the lag it takes to publish. We measured it two ways, and the answer splits into three clean classes. Only one of them survives a delay, and it is not the one that looks like "fast flow." ## Three classes, not one Cross-sectional rank IC, univariate, computed on the full Hyperliquid universe. "Retention" is how much of the forward IC is left after entry is moved one hour later — the question a client actually cares about: *is the signal still there when I can trade it?* | Class | Examples | 1h IC | Retention | Read | | --- | --- | --- | --- | --- | | No signal | `net_taker_open_1h`, `taker_flip_net`, `pos_aggressor_delta_1h` | −0.001 … −0.003 | — | Not a decay story — there is no edge to lose. The order-flow *level* hypothesis, as measured, is unsupported. | | Same-bar microstructure | `taker_imbalance`, `close_vwap_dev`, `close_in_range`, `oi_change_pct_1h`, `buysell_imbalance`, `d_cvd` | −0.011 … −0.040 | 0.03–0.21 | Real 1h IC, but a large backward placebo — the bar's own move leaking into the label. Contemporaneous; after any entry delay it is gone. | | Durable state | `log_volume`, `log_open_interest`, `funding_rate` (+ windowed `funding_paid_7d` / `funding_rate_7d_avg`), `whale_long_account_share`, `whale_net_position`, `account_ls_ratio`, `d_open_interest` | −0.059 … +0.040 (24h) | 0.89–1.01 | The product. IC strengthens with horizon and survives the delay — hourly grain, 24-hour horizon. | The fast class doesn't "decay" like a slow alpha. It's *contemporaneous*: on the 13-month sample `close_vwap_dev` posts a forward IC of −0.029 but a *backward* IC of +0.049 — the "edge" is the bar's own move, gone to −0.0008 after a one-hour delay. `buysell_imbalance` and `d_cvd` are the same shape. A half-life curve fitted to the forward IC flatters this signal, because the forward window overlaps the mechanism that produced it. The delay test is the instrument that doesn't lie. The cross-section those numbers are measured on is the one the [playground](https://tesseralytics.dev/playground) ranks in your browser — one free key, no client to install. One factor sits awkwardly in the middle: `mom_1h` (`ret_1h`) is a real short-term reversal that survives delay — IC −0.013 at 24h with t −7.9 after the entry is moved — but it's small and likely below round-trip cost. Real, durable, and not worth the spread. ## What actually survives Here is the durable class at its proper horizon, from the 13-month sample. These are 24-hour forward ICs, and every one keeps essentially all of its edge after a one-hour entry delay. | Factor | 24h forward IC | t | What it is | | --- | --- | --- | --- | | `log_volume` | −0.059 | −27.8 | size / illiquidity | | `cum_funding` | +0.040 | 26.0 | funding carry (see note below) | | `log_open_interest` | −0.047 | −22.5 | size / illiquidity | | `whale_long_account_share` | +0.016 | 14.6 | positioning | | `funding_rate` | +0.014 | 12.2 | funding carry | | `account_ls_ratio` | +0.010 | 6.1 | positioning | | `whale_net_position` | +0.007 | 6.7 | positioning | | `d_open_interest` | +0.005 | 6.3 | the small OI build | Two honest caveats on that table, before anyone over-reads it. `log_volume` and `log_open_interest` have the largest IC but are a **size/illiquidity bias, not a harvestable edge** — the trade that collects them pays for it in costs and liquidity risk. And `cum_funding`, the strongest carry number in the table, is a **muddled size+carry mix, not clean carry**: its rank correlation with the funding rate is only +0.16 (daily) / +0.25 (hourly), while its correlation with open-interest size is +0.325 — it's partly a size/listing-age proxy. Use the windowed fields (`funding_paid_7d`, `funding_rate_7d_avg`) for a carry signal instead. Every field the intelligence layer can rank, screen or query — name, unit, grain and signal class — is defined in the [field dictionary](https://tesseralytics.dev/datasets/fields). ## The lag is the whole story Here's the part that usually gets glossed over. The published hourly cross-section is not "the last hour." The raw trade tape is readable within minutes of the hour closing — but the cross-section is built from the *settled* funding and position snapshots, which the venue only finalises about an hour after the hour, and assembling those snapshots into the per-hour cross-section adds roughly another hour and a half on top. So a 1h row is roughly **1.5–2.5 hours behind the bar it describes**, and the query tools return the last completed hour, one behind by design. The study's delay test moves entry only one hour, which is the *optimistic* case. For the microstructure class that's fatal: 79–97% of the IC is already gone at one hour, and at two-plus it's effectively zero. For the state class it's irrelevant, because retention is ~1 over 24h. Same grain, opposite verdict — which is exactly why the hourly feed should be read as *state*, not *timing*. ## What I actually run on it This isn't a thought experiment — I run a small **beta-neutral book** over this cross-section as my own dogfood. It rebalances once per completed daily bar, long and short the durable factors, kept **dollar-neutral, beta-neutral and cluster-neutral**. The mechanics are deliberately boring and honest: - **Rank, don't level.** Scores are rank-normalised, so a saturated factor (a wall of ties) collapses to one coefficient instead of a fabricated gradient. - **Neutrality is a projection, not a hope.** The weights are the minimum-norm projection of the signal onto dollar + beta + cluster neutrality, so the book holds as much of the signal as the constraints allow. - **The vol target only ever scales down.** It's the risk dial, never a way to force bigger legs. - **Refuse rather than paper over.** Fewer than three legs (a two-leg book can't be dollar- and beta-neutral at once — it's a geometric fact, not a policy), or a hedge that forces a leg against its own signal, both produce an explicit refusal. A refusal is a valid output. - **The one hourly input is a ±1 state flag at weight 0.03.** `pnl_imbalance` breaks ties; it cannot create a view, and a continuous factor always carries the ordering. And two findings I'd want you to have if you build the same thing. First, the **funding sign is easy to get backwards**: mild elevation is a *continuation* signal — you get paid to be long the side that's paying — and only the extreme tail (funding past ~25% annualised) starts to look like a fade candidate. "Funding up = fade" is wrong. Second, I tested a mean-reversion leg and **closed it**: over 13 months it didn't clear the bar, so the book is continuation-only. There is no fade mode, and I'm not hiding one behind a "regime" switch. It's profitable right now. I want to be precise about what that means: it's a first-person observation over a single market regime, not a validated strategy, and it says nothing about what *you* would make. I'm telling you what I run and what I've found, not selling you a signal — there isn't one to sell. ## The caveats, stated plainly - **Every IC here is gross.** No fees, funding, slippage or borrow. The best 1h spreads are inside round-trip cost; the 24h state factors survive better on turnover, but the number you'd actually keep is lower than the number printed. - **One regime.** The hourly study is 484 hours (18 days, 293 coins, one regime, Sep–Oct 2026). The 13-month sample is 9,057 hours and 207 coins, but its positioning features are computed on only 5 of 7 months (schema drift), and its t-statistics are the naive `ICIR·√n`, not block-bootstrap. - **Survivorship.** The universe is currently-listed coins; delisted markets are not in the sample. - **Coins move together.** Cross-sectional dependence means the effective sample is closer to the number of hours than the number of rows. ## What an agent can and cannot do with it | An agent can | An agent cannot | | --- | --- | | Rank and screen the daily cross-section on durable state — carry, positioning, size/liquidity — with percentiles and z-scores computed where the data lives. | Time entries off the hourly grain. The fast class is gone by the time it's published. | | Measure funding divergence, pull per-coin series, read the live market, and feed a daily-rebalanced neutral book — the thing I run. | Get a forecast, a "buy this" signal, or a get-rich-quick edge. None of those ship, because the data doesn't support them. | | Separate state from timing — treat the hourly feed as a state and disconfirmation feed, and the daily feed as the tradeable ordering. | Harvest the size/illiquidity bias as an edge — costs and liquidity risk eat it. | That split — durable state, not fast flow — is the whole design of the [intelligence layer](https://tesseralytics.dev/mcp-server). It ranks the cross-section, screens on the durable factors, and names the completed grain every answer covers, so an agent can't quietly mistake the newest published bar for a real-time one. [Get a key](https://tesseralytics.dev/account) and ask it yourself — a free key ranks every market over the trailing week. [← Back to blog](https://tesseralytics.dev/blog) --- Source: https://tesseralytics.dev/blog/one-off-download-tutorial [← Blog](https://tesseralytics.dev/blog) Tutorial 7 October 2026 # Download Hyperliquid data to your local machine: a step-by-step tutorial Buy a one-off bundle, write a small Python tool with the SDK, run it with uvx, and persist data locally as Parquet or DuckDB. No subscription, no commitment — the data is yours. Tessera's one-off download bundles give you a perpetual copy of Hyperliquid data — no subscription, no expiry. Three bundles are available: [Tessera Majors ($19)](https://tesseralytics.dev/pricing), [Tessera HIP-3 ($24)](https://tesseralytics.dev/pricing), and [Tessera All Markets ($29)](https://tesseralytics.dev/pricing). Each includes all three datasets — `gold_ohlcv_1m`, `gold_funding_1h`, and `gold_positioning_1h` — over all closed months. You can follow this tutorial without buying anything. A free account gives you `gold_ohlcv_1m` (minute candles) for BTC, ETH, SOL and HYPE over the trailing month — enough to run every example below. Buying a bundle unlocks all three datasets, every coin, and the full closed history back to October 2025. ## Get an API key Sign up at [tesseralytics.dev/account](https://tesseralytics.dev/account), create an API key, and copy it. The key is shown once — store it somewhere safe. Export it as an environment variable: ``` export TESSERA_API_KEY="sk_..." # from https://tesseralytics.dev ``` ## Buy a bundle Head to [/pricing](https://tesseralytics.dev/pricing), pick a bundle, and check out via Stripe. The purchase is a one-time payment — the data is yours forever. The open month is excluded; subscribe to Pro if you want freshness. ## Write the download tool The approach is a small Python script that uses the SDK to pull data and save it locally. The script uses inline dependencies (PEP 723) so it runs with `uvx` — no `pip install`, no venv: ``` # /// script # dependencies = ["tessera-api"] # /// import tessera client = tessera.TesseraClient() # reads $TESSERA_API_KEY # List what you can see datasets = client.datasets() for d in datasets.datasets: print(f"{d.name}: {d.description}") # Pull BTC minute candles for a specific month df = client.read("gold_ohlcv_1m", "BTC", "2026-09") print(f"Pulled {len(df)} rows") # Save as a single flat Parquet file df.write_parquet("btc_ohlcv_2026-09.parquet") print("Saved to btc_ohlcv_2026-09.parquet") ``` `datasets()` returns every dataset your plan can reach. `read()` pulls a partition as a Polars DataFrame. `write_parquet()` saves it as a single flat Parquet file — a columnar format that is faster and smaller than CSV, and readable by pandas, polars, DuckDB, and most modern tools. That pulled one partition. To download multiple coins or months at once, use `scan()` with a `MonthSpan`: ``` import tessera client = tessera.TesseraClient() # Pull BTC and ETH minute candles for three months lf = client.scan( "gold_ohlcv_1m", coin=["BTC", "ETH"], month=tessera.MonthSpan("2026-07", "2026-09"), columns=["time", "coin", "close", "volume"], ) # Collect and save as a single Parquet file df = lf.collect() df.write_parquet("btc_eth_ohlcv_2026-07_to_2026-09.parquet") print(f"Saved {len(df)} rows") ``` ## Install uv `uvx` is part of `uv`, a fast Python package manager. If you don't have it yet, install it: ``` curl -LsSf https://astral.sh/uv/install.sh | sh ``` Verify it works: ``` uv --version ``` ## Run it with uvx `uvx` runs the script in an isolated environment. First run takes a few seconds (it downloads the SDK); subsequent runs are instant: ``` uvx download_data.py ``` Prefer a permanent install? `pip install tessera-api` works too. ## Persist as DuckDB instead DuckDB is a local SQL database — like sqlite but with powerful analytics capabilities. You can query it with SQL, open it in tools, or connect from Python or R. DuckDB queries Polars DataFrames directly, so you can pull data with the SDK and insert it into a DuckDB file in a few lines: ``` # /// script # dependencies = ["tessera-api", "duckdb"] # /// import tessera import duckdb client = tessera.TesseraClient() # Create a local DuckDB file con = duckdb.connect("ohlcv.duckdb") # Pull data and insert it — DuckDB queries Polars DataFrames directly df = client.read("gold_ohlcv_1m", "BTC", "2026-09") con.execute("CREATE TABLE ohlcv AS SELECT * FROM df") con.close() print("Saved to ohlcv.duckdb") ``` ## Query your local data Read the Parquet file back with polars: ``` import polars as pl df = pl.read_parquet("btc_ohlcv_2026-09.parquet") print(df.head()) ``` Or query the DuckDB file with SQL: ``` import duckdb con = duckdb.connect("ohlcv.duckdb") result = con.execute( "SELECT close FROM ohlcv WHERE time > '2026-09-15' LIMIT 5" ).fetchall() print(result) con.close() ``` Or open it in the DuckDB CLI for interactive SQL: ``` duckdb ohlcv.duckdb ``` ## Where to go from here The [SDK reference](https://tesseralytics.dev/sdks) has the full API. The [data dictionary](https://tesseralytics.dev/datasets) explains every column. And if you haven't already, [buy a bundle](https://tesseralytics.dev/pricing) to unlock the full history. The data is yours — no subscription, no expiry. [← Back to blog](https://tesseralytics.dev/blog) --- Source: https://tesseralytics.dev/blog/wallet-behaviour [← Blog](https://tesseralytics.dev/blog) Research 3 July 2026 # Smart money doesn't stay smart On a DEX every trade is signed by a wallet, so we can ask the obvious question: can you just copy the winners? We scored ~100,000 Hyperliquid wallets a month to find out — and the answer is a lesson in luck, skill and style. A centralized exchange keeps its order flow to itself. Hyperliquid is a DEX, so every fill is public and *signed* by the wallet that made it. That's a strange and powerful thing: you can watch every trader on the venue, name by name, month after month. So the obvious question almost asks itself — **why not just find the wallets that make money and copy them?** We ran the experiment. Each month we score roughly **108,933 wallets** on BTC alone (and tens of thousands more across 260-odd other markets): how much they trade, how often they win, how much they make, and how *toxic* their flow is — how far the price runs against you in the minutes after they hit your quote. Then we asked the only question a copy-trader cares about: does any of it carry over to next month? ## Last month's hero, next month's goat Here's the same picture for three different wallet traits. Each grid sorts wallets into deciles by a trait *this* month (bottom-to-top) and asks where they land *next* month (left-to-right). A bright diagonal means "you stay where you were" — the trait persists. All-bright means it's a coin toss. Win rate A clean diagonal: a wallet’s win rate lands where it started. Style persists. Realized PnL An X, not a line: last month’s biggest winners are about as likely to crash to the bottom as to repeat. That’s variance, not skill. Toxicity (5-min markout) Almost flat: informed, toxic flow barely repeats at the wallet level month to month. Rows = this month's decile (low at bottom); columns = next month's decile. Brighter = higher probability. Pooled over 10 major markets, 2025-08..2026-06, wallets active in both months. Look at the middle panel. If trading profit were skill, big winners would stay winners and the grid would light up along the diagonal like the win-rate panel on the left. Instead it forms an **X**: the wallets with the largest realized PnL this month are almost as likely to plunge to the *bottom* decile next month as to repeat at the top. That's the fingerprint of **variance, not edge** — the same accounts take the biggest swings in both directions. The bright core in the centre is the quiet majority whose PnL hovers near zero and stays there. Toxicity (right) barely persists at all. ## What *does* persist is style, not skill Rank every trait by how strongly it carries month-to-month (Spearman correlation of a wallet with itself, one month later). The pattern is stark. The things that persist describe **who a wallet is and how it trades** — how much size it pushes, the fees it pays, its habitual win rate. The one thing that *doesn't* persist is the thing you'd actually want to copy: whether it makes money. Trading volume 0.81 Fees paid 0.80 Win rate 0.22 Markout coverage 0.19 Realized PnL 0.08 PnL per volume 0.04 Toxicity (5m markout) 0.01 Who they are How they trade Whether they profit Trading volume is almost perfectly sticky (ρ ≈ 0.81) — whales stay whales. Win rate is moderately sticky (ρ ≈ 0.22), but a high win rate is a *style*: scalpers bank many tiny gains and take rare large losses, so a wallet's win rate tells you how it trades, not whether it profits. Realized PnL (ρ ≈ 0.08) and 5-minute toxicity (ρ ≈ 0.01) are essentially memoryless. Copying last month's leaderboard is copying a coin flip. ## The shape of the crowd Two more facts explain *why* the leaderboard is so noisy. First, most wallets lose: in every full month, **54%** of the wallets trading BTC finish the month with negative realized PnL. The distribution is fat-tailed and roughly balanced around zero — a few big winners, a few big losers, and a huge pile clustered near break-even before fees. Monthly realized PnL per wallet · BTC (signed-log $ axis) \-$562K: 784 wallets \-$178K: 1,349 wallets \-$56K: 3,300 wallets \-$18K: 6,871 wallets \-$6K: 13,130 wallets \-$2K: 21,927 wallets \-$561: 35,694 wallets \-$177: 51,322 wallets \-$55: 67,832 wallets \-$17: 80,185 wallets \-$5: 87,606 wallets \-$1: 139,445 wallets +$1: 157,343 wallets +$5: 62,622 wallets +$17: 59,095 wallets +$55: 50,928 wallets +$177: 40,912 wallets +$561: 27,832 wallets +$2K: 17,446 wallets +$6K: 10,164 wallets +$18K: 5,633 wallets +$56K: 2,634 wallets +$178K: 1,133 wallets +$562K: 727 wallets \-$562K\-$561\-$1+$2K+$562K Lost money Made money Volume concentration · BTC, 2026-06 The dashed line is perfect equality. The gap below it is the reality: the top 1% of wallets drive 89% of volume; the bottom 98% together trade under 7%. Gini 0.987. Second, volume is extraordinarily concentrated. A handful of accounts do almost all the trading, and the long tail barely moves size. So a naive "top PnL" ranking is dominated by whoever happened to take the biggest position into the biggest move — survivorship and variance wearing the costume of skill. ## Where the edge actually is So is wallet data useless? The opposite — but the edge isn't in any single column, and it isn't in copying winners. It's in the **interaction** of many weak, orthogonal behaviours (they share a mean absolute correlation of only ≈0.11). No one of them forecasts next month; combined in a non-linear model, they do. That's the claim we validated: a tree that scores every wallet's next-month PnL and toxicity, out-of-sample the hard way. The validation survives the tests that kill most "smart money" claims. We measure **walk-forward**, only scoring months the model was fit before. We hold out whole coins — **leave-one-coin-out** — so the reported skill is on markets the model never trained on, and it replicates. A **no-shared-wallet** variant, where train and test wallets don't overlap, actually *strengthens* it: the model learns behaviour, not a memorized list of addresses. And the tell-tale **negative control** — whether the same signal predicts the coin's price return — comes back at `≈0`. This forecasts *wallet behaviour*, not the market. ## See it for yourself Everything above is built from Hyperliquid's public signed fills. We don't expose that per-wallet feed ourselves — it's public, if you'd rather wrangle it raw — but we do ship its market-level distillation: order-flow OHLCV, funding and positioning, cleaned, checked and served as Parquet or over the API. Browse the tiles [here](https://tesseralytics.dev/datasets); check [pricing](https://tesseralytics.dev/pricing) for full history on every coin. [← Back to blog](https://tesseralytics.dev/blog) --- Source: https://tesseralytics.dev/privacy # Privacy Policy Last updated: June 2026 ## What we collect When you sign up we collect your email address and authentication identifier via our identity provider (Amazon Cognito, optionally through Google sign-in). We store your API keys as one-way hashes (never the raw key), basic key metadata, and your subscription tier. Payment details are handled entirely by Stripe — we never see or store your card number. ## How we use it We use this information to authenticate you, provide and meter access to the Service, process subscriptions, and communicate about your account. We do not sell your personal data. ## Service providers We rely on a small number of processors to run the Service: Amazon Web Services and Amazon Cognito (hosting and authentication), Stripe (payments), and Tigris (object storage for the datasets). These providers process data on our behalf under their own terms. ## Cookies and local storage The web app stores your session tokens in your browser's `sessionStorage` so you stay signed in within a tab; these are cleared when the tab closes. We don't use third-party advertising or tracking cookies. ## Retention We keep account and key records (including revoked keys) for as long as your account exists, to maintain an audit trail. There is no automatic deletion — a lapsed paid account simply reverts to the free tier rather than being removed. If you'd like your account and associated personal data deleted, email us and we'll action it within five working days. ## Your rights and contact You can request access to, correction of, or deletion of your personal data by emailing [info@tesseralytics.dev](mailto:info@tesseralytics.dev). We'll respond within a reasonable timeframe. --- Source: https://tesseralytics.dev/terms # Terms of Service Last updated: June 2026 ## 1. Overview Tessera Analytics provides query-ready market datasets derived from public Hyperliquid DEX data, served over a REST API as presigned Parquet downloads ("the Service"). By creating an account or using the Service you agree to these terms. ## 2. Accounts and API keys You are responsible for activity under your account and API keys. Keep your keys secret; you can revoke and rotate them at any time from your account. Do not share keys or resell access without prior written agreement. ## 3. Subscriptions and billing Paid plans are billed in advance on a recurring monthly basis through our payment processor (Stripe). You can cancel at any time from the billing portal; cancellation stops future renewals, and paid access continues until the end of the current billing period, after which the account reverts to the free tier. Fees are non-refundable — we do not offer partial or pro-rata refunds for the unused portion of a billing period. ## 4. Acceptable use Don't attempt to disrupt, overload or circumvent access controls of the Service, and don't use it for any unlawful purpose. We may suspend access that threatens the integrity or availability of the Service. ## 5. Data accuracy and "as is" The datasets are derived from third-party on-chain data and are provided on an "as is" and "as available" basis, without warranties of accuracy, completeness or fitness for a particular purpose. Coverage gaps can occur where upstream data is missing. Nothing in the Service is financial advice; you are solely responsible for decisions made using the data. ## 6. Limitation of liability To the maximum extent permitted by law, Tessera Analytics is not liable for indirect or consequential losses, or for any trading or investment losses, arising from use of the Service. Our total liability is limited to the fees you paid in the preceding twelve months. ## 7. Changes We may update the Service and these terms from time to time. Material changes will be reflected by the "last updated" date above; continued use after a change constitutes acceptance. ## 8. Governing law These terms are governed by the laws of England and Wales. Any disputes arising out of or relating to these terms or the Service shall be subject to the exclusive jurisdiction of the courts of England and Wales. ## 9. Contact Questions about these terms? Email [info@tesseralytics.dev](mailto:info@tesseralytics.dev).