APIHIP-4 ArchiveResources

Resources

All endpoints are GET, unauthenticated, under https://api.hypersight.xyz/v1. Every response includes generatedAt (epoch ms). See Freshness.

What each one weighs

Sizes decide how you call this. The aggregates are small enough to poll; one curve is not, and the bulk export is a download, not a request.

ResourceTypicalLargest seen
manifest.json1 KB
markets/{id}.json1.5 KB median3.9 KB
markets/{id}/price.json9 KB
governance.json10 KB
changes.json44 KBbounded at 500 entries
openapi.json62 KB
archive.json335 KBgrows daily
events.json700 KBgrows daily
markets/{id}/odds.json140 KB4.8 MB (145,048 points)
markets/{id}/trade-odds.json130 KB
bulk/markets.000.jsonl.gz247 KB gzippedthe whole archive
⚠️

A curve is the one thing that can surprise you. A busy market records a point per price change at the feed’s ~5-second cadence, so odds.json runs from a few KB to several MB. Read oddsMeta.points in the market document first — it is there so you can decide before you fetch.

manifest.json

The archive’s table of contents. Also served at the API root (/).

{
  "generatedAt": 1787000000000,
  "freshness": "regenerated on market settlement (~1 min) and nightly; not continuous",
  "license": {
    "name": "CC BY 4.0",
    "url": "https://creativecommons.org/licenses/by/4.0/",
    "attribution": "Hypersight (hypersight.xyz)"
  },
  "coverage": { "firstExpiryMs": 1777788000000, "lastExpiryMs": 1787000000000 },
  "counts": { "settledMarkets": 700, "settledEvents": 300, "marketFiles": 1000 },
  "resources": ["/v1/archive.json", "/v1/events.json", "/v1/governance.json", "/v1/markets/{outcomeId}.json"]
}

Counts and timestamps above are illustrative — the archive grows daily, and the live manifest is the only truthful copy of its own numbers.

archive.json

Every settled price market (crypto binaries and buckets), newest first.

FieldMeaning
outcomeIdHIP-4 outcome id (also the key for /v1/markets/{id}.json)
underlyingBTC, ETH, SOL, HYPE, …
periodMarket cadence, e.g. 1d
classpriceBinary (above/below target) or priceBucket (range)
expiryMsExpiry timestamp (epoch ms). Price markets always have one
targetPriceThe strike the question was asked about
settlePriceThe oracle price the market settled against
resultup (YES won) or down (NO won)
yesCoin / noCoinThe HIP-4 coin tickers, e.g. #10570 / #10571
bucketLabelRange label for bucket legs, null for binaries
totalVolumeLifetime volume in USDC, YES and NO legs summed — everything the chain counted, including what nobody traded. For the order book alone, add buyNotional + sellNotional; do not subtract (see completeness)
yesVolume / noVolumeThe same dollars, split by which side was bought. null means never captured — not zero (see completeness)
tradersDistinct wallets that traded this market, both legs unioned, from the on-chain index’s own fills. null means not swept yet — not zero
splitNotionalEverything in totalVolume that is not a taker buy or sell: the settlement payout, plus merges, negations and minting. Protocol mechanics — no counterparty chose a price. Across the archive it is $208.3M of $498.2M
buyNotional / sellNotionalTaker buys and sells, in USD, measured from the index’s own fill rows. Their sum is what changed hands. null until the fills sweep has covered the market — never 0
settleNotionalThe settlement payout alone, inside splitNotional: the protocol redeeming winners at $1. Exposed separately because it is the one member of the lump a reader usually wants back — trading is $290.0M, trading plus the payout is $378.1M, and the $120.3M of merges, negations and mints is in neither
tailNotionalThe post-settle tail: dollars traded after settlement (the winner converging to $1, the losers draining). Already included in totalVolume — subtract it to compare with trackers that cut at settlement. null until the fills sweep has covered the market
familyTradersDistinct wallets across every leg of the market’s family (bucket ladder), as a set union — not the sum of each leg’s traders, which double-counts wallets that traded several ranges. Identical on every row of the same family; null on standalone markets

events.json

Every resolved event market (macro decisions, sports fixtures, one-off questions), with the winning side and, for matches, the final score.

FieldMeaning
outcomeIdHIP-4 outcome id
outcomeLabelThe outcome’s own label, e.g. No change. Distinct from questionTitle, which names the parent question
side0 / side1The two sides as listed on-chain (usually Yes / No)
winnerSide0 or 1: index of the winning side
winnerLabelThe winning side’s label, resolved for you
expiryMsScheduled expiry (epoch ms). null on every event row today: HL publishes no scheduled expiry for these markets. An outright such as 2026 World Cup Champion resolves when the tournament does, and a fixture resolves when it is played, neither on a date fixed in advance. Date and sort on settledAt
settledAtWhen the market resolved (epoch ms). Always present. This is the event market’s only timestamp
questionTitleThe parent question, e.g. July Fed funds decision. null on standalone markets, where outcomeLabel is the market’s own name
questionDescriptionThe full resolution rules, verbatim. null when the market resolved before we captured it, or when it never had any
categorye.g. economics/N/A, sports/football. Read from the metadata tag Hyperliquid publishes in a market’s description. 14 markets carry a category we assigned ourselves: Hyperliquid listed them with a one-line description and no tag while naming it on their siblings in the same batch, so the value is taken from those siblings rather than left empty. Everywhere else it is Hyperliquid’s own
totalVolumeLifetime volume in USDC, YES and NO legs summed — everything the chain counted, including what nobody traded. For the order book alone, add buyNotional + sellNotional; do not subtract
yesVolume / noVolumeThe same dollars, split by which side was bought. null means never captured — not zero (see completeness)
tradersDistinct wallets that traded this market, both legs unioned, from the on-chain index’s own fills. null means not swept yet — not zero
familyTradersDistinct wallets across every outcome of the same parent question, as a set union — not the sum, which double-counts wallets that traded several outcomes. Identical on every row sharing a questionTitle; null on standalone markets
splitNotionalEverything in totalVolume that is not a taker buy or sell: the settlement payout, plus merges, negations and minting. Protocol mechanics — no counterparty chose a price. Across the archive it is $208.3M of $498.2M
buyNotional / sellNotionalTaker buys and sells, in USD, measured from the index’s own fill rows. Their sum is what changed hands. null until the fills sweep has covered the market — never 0
settleNotionalThe settlement payout alone, inside splitNotional: the protocol redeeming winners at $1. Exposed separately because it is the one member of the lump a reader usually wants back — trading is $290.0M, trading plus the payout is $378.1M, and the $120.3M of merges, negations and mints is in neither
tailNotionalThe post-settle tail: dollars traded after settlement (the winner converging to $1, the losers draining). Already included in totalVolume — subtract it to compare with trackers that cut at settlement. null until the fills sweep has covered the market
homeTeam / awayTeam / homeScore / awayScoreFinal score for sports fixtures, null otherwise

Every field above is always present on every event row. Optional ones carry null rather than disappearing, so the shape does not change from row to row.

archive/{YYYY-MM}.json and events/{YYYY-MM}.json

The same rows, sliced by the month a market resolved in. The whole-archive documents stay the simplest way in, but they grow with the archive; these let you fetch a slice, or backfill history once and never read it again. The manifest’s shards array lists every month that exists, with its counts.

Both files exist for every month the manifest lists, with count: 0 and an empty array when that month had none of that kind. So the obvious loop over shards never hits a 404.

curl https://api.hypersight.xyz/v1/archive/2026-07.json

changes.json

The most recent resolutions, newest first: outcomeId, type, settledAt and the market’s URL. Poll this instead of re-reading the aggregates.

It is deliberately bounded (500 entries). If your last sync is older than oldestSettledAt, the feed cannot tell you what you missed, and it says so in its own note field: re-read archive.json and events.json instead of assuming the gap is empty.

bulk/manifest.json

Gzipped JSON Lines covering the whole archive, one market per line. A line is the same document markets/{id}.json serves — market, dataQuality, deployer, family, flow, oddsMeta, the series URLs and the settlement — with outcomeId promoted to the top level, because a line has no URL to say which market it is. Regenerated nightly. Ingest it once, then follow changes.json.

The two heavy series ship beside it, one line per market, keyed by outcomeId: odds.*.jsonl.gz and price.*.jsonl.gz. They are separate files for the same reason they are separate resources: most callers want the results, not the tapes.

All three are split by size, so read files rather than guessing chunk names: marketChunks, oddsChunks and priceChunks say how many of each exist, and the counts move as the archive grows.

# Fetch every chunk the manifest lists, whatever it is called
curl -s https://api.hypersight.xyz/v1/bulk/manifest.json   | jq -r '.files[].url'   | xargs -I{} curl -O https://api.hypersight.xyz{}

openapi.json

An OpenAPI 3.1 description of this surface, generated with the live counts and coverage window. Every response is described field by field, and the two row shapes are named schemas (PriceMarket, EventMarket), so a generated client comes out typed rather than as a bag of any.

npx @openapitools/openapi-generator-cli generate \
  -i https://api.hypersight.xyz/v1/openapi.json -g typescript-fetch -o ./client

governance.json

Aggregated validator settlement activity: how many settlement actions were observed, vote counts, and the most active validators by address.

FieldMeaning
counts.byTypeOne entry per action type (register, settle) with its count
counts.actions / finalizedTotals over all observed actions
counts.votes / validatorsTotal votes recorded, and how many distinct validators cast them
counts.lastActionAtWhen the newest action was last observed. Published because a governance feed that STOPS looks identical to a healthy one from every count — a dead feed is finalized by definition, so “278 actions, 278 finalized” is both the picture of health and the signature of the failure. Only this date separates them
topValidatorsThe most active validators: address, actions voted on, and their own medianLagMs / lagSamples / lagBounded / openingBeatVotes
voteLagHow long validators take to vote, measured from the action’s opening (see below)
recentThe 30 latest actions: id, type, title, reason, quorumReached, finalized (0/1), lastSeen

voteLag

The zero of this axis is the action’s opening, which Hyperliquid does not publish: it is derived as expireTime - votingWindowMs. That makes one field load-bearing.

FieldMeaning
medianMsMedian lag across every measured vote. null below minSamples
samples / boundedMeasured votes behind the median, and votes excluded from it because they are upper bounds rather than measurements
lagResolutionMsSampling interval. Below it, vote ORDER is not observable — two validators inside one interval are not comparable
basisWhere the zero sits (actionOpening)
votingWindowMsThe assumed window between opening and expiry
windowViolationsActions that outlived that window. Must be 0 — anything else means the window changed and every lag here is off by the same amount, with nothing else looking wrong
minSamplesNo median is published below this many measured votes

This file also carries n, quorum_reached and last_seen as deprecated aliases of count, quorumReached and lastSeen. They are the raw column names, kept only because v1 promises nothing disappears. Read the camelCase ones; a future major version drops the others.

markets/{id}.json

One market in full: the page most builders want.

FieldMeaning
typeprice or event
marketThe market’s row, exactly as in archive.json / events.json
dataQualityThe document’s own report card: { complete, missing }. missing lists reason slugs — odds-none (no curve at all), price-series, volume-split, settlement-votes, fills. complete is simply missing.length === 0
deployerWho deployed the market: { address, name, protocol }. Protocol markets (every market until permissionless deployment opens) carry address: null, name: "Hyperliquid", protocol: true; third-party markets carry the deployer address and, when our registry names it, a display name. Docs written before the field shipped simply lack it — absence means protocol
familyThe other legs of the same question: totalVolume across all of them and outcomeIds listing every one. null when the market stands alone
priceMetaSummary of what the underlying did while the market was live, at 5-minute resolution: { interval, points, firstTs, lastTs }. null on event markets, which have no ticker, and on markets whose window predates this capture
priceUrlPath to that series, or null in the same two cases
oddsMetaSummary of the odds series: points, firstTs, lastTs, gaps (a count), maxGapMs, complete, captureRegime and source (see coverage)
oddsUrlPath to the series itself, or null when nothing was captured
tradeOddsMetaSummary of the TRADE odds: every real transaction price from the raw fills archive (YES coin, buys and sells only, consecutive identical prices collapsed). A different instrument from the sampled mid above, never blended with it — it exists even for markets that settled before the mid capture was born. null = no real trades to derive from
tradeOddsUrlPath to markets/{id}/trade-odds.json, or null
flowFills-derived aggregates — traders, fees, notionals, the post-settle tail and four derived stats. The richest field of the doc, so it has its own section. null until the fills sweep has covered the market — not zero
settlementThe settlement action: reason, quorumReached, finalized, the timestamps, and voterCount. null when none was captured
settlementUrlPath to the voter roster, or null. See markets/{id}/settlement.json
settlementApplicableWhether this market class settles by validator vote at all. false on every price market: they settle from the oracle (see coverage)
settlementCapturedfalse means the votes were never captured, not that nobody voted. Only meaningful when settlementApplicable is true
curl https://api.hypersight.xyz/v1/markets/813.json
{
  "generatedAt": 1787097654338,
  "type": "event",
  "dataQuality": { "complete": true, "missing": [] },
  "market": {
    "outcomeId": 813,
    "questionTitle": "World Cup Semifinal: France vs Spain",
    "side0": "France", "side1": "Spain",
    "winnerSide": 1, "winnerLabel": "Spain",
    "homeTeam": "France", "homeScore": 0, "awayTeam": "Spain", "awayScore": 2,
    "expiryMs": null, "settledAt": 1784055600000,
    "totalVolume": 8121997,
    "yesVolume": 2301278, "noVolume": 5820719,
    "tailNotional": 4927922,
    "traders": 1403
  },
  "family": null,
  "oddsMeta": {
    "points": 1095, "firstTs": 1783754570921, "lastTs": 1784062640022,
    "gaps": [{ "fromTs": 1783756269650, "toTs": 1783757376985 }, "… 66 in total"],
    "complete": false, "captureRegime": "event-5s", "source": "book-archive"
  },
  "oddsUrl": "/v1/markets/813/odds.json",
  "tradeOddsMeta": { "points": 8189, "firstTs": 1783755987011, "lastTs": 1784070782196 },
  "tradeOddsUrl": "/v1/markets/813/trade-odds.json",
  "settlement": {
    "quorumReached": true,
    "voters": [{ "validator": "0x8a5d…", "name": "Hyperdash", "stakePct": 2.05, "firstSeen": 1784064279788 }, "… 14 in total"]
  },
  "settlementApplicable": true,
  "settlementCaptured": true
}

A verbatim snapshot of the live document (19 Aug 2026), trimmed where marked — not a cleaned-up ideal. This market is complete: false on purpose: an archive that claims completeness it does not have is worse than one that reports its own holes, and dataQuality exists so you never have to guess.

The flow object

Every figure below is measured per fill from our raw archive, deduplicated per trade: the index serves one row per participant, two per trade.

{
  "fills": 8697,
  "traders": 1016,
  "fee": 4.97,
  "builderFee": 4.97,
  "buyNotional": 1615840.34,
  "sellNotional": 391210.73,
  "splitNotional": 1366973,
  "tailNotional": 1979720.84,
  "tailFills": 1886,
  "deduplicated": true,
  "vwapYes": 0.66,
  "vwapNo": 0.26,
  "biggestFill": 99999.99,
  "bestEntryPx": 0.299
}
FieldMeaning
fillsDistinct trades across both legs, deduplicated by trade id — not raw participant rows
tradersDistinct wallet addresses across both legs
fee / builderFeeUSD. Charged on-chain in outcome-token shares and valued at each fill’s own price; buying is free on outcome markets, so fees are sell-side by construction. builderFee is the part routed through builder codes — the two were identical until Hyperliquid’s August fee change introduced a protocol share
buyNotional / sellNotionalNotional of taker-buy / taker-sell trades, USDC
splitNotionalEverything that is not a taker buy or sell — protocol mechanics rather than order-book matching. Measured across all 1,012 markets: settlement 43.5%, merge outcome 28.1%, negate outcome 14.9%, minting 10.2%, merge question 3.3%. Despite the field name, minting is its smallest meaningful part and settlement its largest. The three notionals sum to the market’s totalVolume; subtract this one for an order-book-only figure
tailNotional / tailFillsThe post-settle tail: dollars moving after settlement. Already included in the totals above — subtract it to compare with trackers that cut at settlement. Note that 44% of it is the protocol settling positions rather than late trading, so it is not a “post-settle trading” figure
deduplicatedtrue = per-trade figures with USD fees. false = an early sweep row not yet recomputed; treat its notional as inflated
vwapYes / vwapNoVolume-weighted average price per coin across its real trades, splits excluded. null until derived
biggestFillLargest single fill by notional, USD. null until derived
bestEntryPxCheapest real buy price of the winning side — what the best entry actually paid per share. Fills under Hyperliquid’s $10 order minimum are ignored as dust. Only derivable once the winner is known

markets/{id}/odds.json

The odds series on its own, because a long-running market carries tens of thousands of points (~1 MB uncompressed) that most consumers do not need. Fetch it only when oddsMeta.points > 0.

{
  "generatedAt": 1787097654338,
  "outcomeId": 813,
  "points": 1095,
  "odds": [ { "ts": 1783754570921, "px": 0.5 }, "…" ]
}

Each point is the YES side’s mid price on the 0 to 1 probability scale. How densely they were recorded, and by whom, is in oddsMeta.captureRegime and oddsMeta.source — see Resolution and provenance.

markets/{id}/trade-odds.json

The TRADE odds: every real transaction price of the YES coin, based on the fills archive (buys and sells only, consecutive identical prices collapsed). Same shape as odds.json plus one extra field: volumeBuckets, ~48 adaptive buckets of { t, yes, no } traded notional across the market’s life, from the same deduplicated fills (absent on files derived before the histogram shipped). Its own file and its own name: a different instrument from the sampled mid, never blended with it. Fetch it when tradeOddsMeta is non-null; it exists even for markets that settled before the mid capture was born.

curl https://api.hypersight.xyz/v1/markets/141/trade-odds.json

markets/{id}/settlement.json

Which validators voted the settlement, with the name and stake weight each carried at vote time.

{
  "generatedAt": 1787356995910,
  "outcomeId": 674,
  "found": true,
  "reason": "FIFA officially declared France the winner of the Game.",
  "quorumReached": true,
  "finalized": true,
  "voters": [
    { "validator": "0x0000…acb8", "name": "ValiDAO", "stakePct": 1.5, "firstSeen": 1784160139953 }
  ]
}

Fetch it when settlementUrl is non-null. The market document keeps the verdict and a voterCount; only the roster lives here.

⚠️

This is the only surviving copy. Hyperliquid serves votes while a settlement action is in flight and keeps nothing afterwards. One market settled before this capture existed and its roster is gone for good — no source anywhere can reconstruct it.

curl https://api.hypersight.xyz/v1/markets/674/settlement.json

markets/{id}/price.json

What the underlying did over the window the market was live, at 5-minute resolution — Hyperliquid’s own price, the one the market settled against, not another venue’s. Frozen at settlement and never recomputed.

{
  "generatedAt": 1787330633626,
  "outcomeId": 3,
  "interval": "5m",
  "points": [ { "t": 1777960800000, "c": 1823.4 }, "…" ]
}

Fetch it when priceUrl is non-null. It is null in two cases, and they are different: event markets have no ticker at all, and a handful of price markets closed before this capture existed.

curl https://api.hypersight.xyz/v1/markets/3/price.json

Anything outside /v1 on this hostname returns a JSON 404.

A 403 applies to a caller, not to a resource: an address lands there after abuse and every path answers the same way. There is nothing to retry, and it is never about authentication — this surface needs no credentials.