Archive API
Hyperliquid purges a HIP-4 market shortly after it settles: its coin, its candles, its order book and its settlement votes disappear from the node API. Hypersight indexes that data while the market is live and preserves it after resolution, and this API exposes the full archive, publicly and for free.
https://api.hypersight.xyz/v1- No authentication. Every endpoint is a plain
GET, with no query parameters: each resource is one whole document.HEADworks too (handy for ETags); anything else answers405. - CORS is open (
*): call it straight from a browser app. - Rate limit: 300 requests per minute per IP. Over it you get a
429withRetry-After: 60and anX-RateLimit-Limitheader, so a client can back off on its own. If you need more, reach out. - JSON only, served from pre-computed snapshots on Cloudflare’s edge.
Ordering, because it differs by resource. archive.json is sorted by
expiryMs descending and events.json by settledAt descending, so
the newest resolution comes first in both. A market’s odds array runs the
other way, ascending by ts, because it is a time series. Both are
stable: if you ingest incrementally, read the aggregates until you meet an id
you already hold.
Quickstart
# What's in the archive right now
curl https://api.hypersight.xyz/v1/manifest.json
# Every settled price market (BTC/ETH/SOL/HYPE binaries & buckets)
curl https://api.hypersight.xyz/v1/archive.json
# One market: result, final score, settlement voters
curl https://api.hypersight.xyz/v1/markets/813.json
# Its odds curve, in a separate file
curl https://api.hypersight.xyz/v1/markets/813/odds.jsonThe first call answers with the archive’s table of contents, which is the shortest way to see the shape of things:
{
"generatedAt": 1786619263075,
"freshness": "regenerated on market settlement (~1 min) and nightly; not continuous",
"coverage": { "firstExpiryMs": 1777788000000, "lastExpiryMs": 1786514400000 },
"counts": { "settledMarkets": 680, "settledEvents": 313, "marketFiles": 993 },
"resources": ["/v1/archive.json", "/v1/events.json", "…"]
}The root (https://api.hypersight.xyz/) also serves the manifest.
In your language
Pulling one market, its odds curve and its settlement voters:
const BASE = "https://api.hypersight.xyz/v1";
const market = await fetch(`${BASE}/markets/813.json`).then((r) => r.json());
console.log(market.market.outcomeLabel, "won:", market.market.winnerLabel);
// The curve is a separate file, and only exists when something was captured.
if (market.oddsUrl) {
const { odds } = await fetch(`https://api.hypersight.xyz${market.oddsUrl}`).then((r) => r.json());
console.log(odds.length, "points, first:", new Date(odds[0].ts), odds[0].px);
}
// Price markets settle from the oracle: settlementApplicable is false there,
// and the false next to it is not a gap in our capture.
if (market.settlementApplicable && market.settlementCaptured) {
console.log(market.settlement.voters.length, "validators voted");
}Ingesting the whole archive is two calls, archive.json and events.json,
plus one per market whose curve or voter set you want.
Freshness
The API serves static snapshots, not live queries. Snapshots are
regenerated when a market settles (within about a minute) and once a night
in full. Every response carries a generatedAt timestamp (epoch ms): read it
rather than assuming real time.
Edge caching adds a little on top: aggregate files can lag a few minutes after a settlement, and an already-cached per-market file up to an hour. A freshly settled market’s file is generated new, so it is fresh from its first read.
This is a deliberately modest guarantee: the archive is immutable data about
resolved markets, not a live feed. For live prices and order books, use
Hyperliquid’s own /info API.
Stability
The v1 schema is stable. Changes are additive only: new fields may
appear, existing fields will not change meaning or disappear. A breaking change
would ship as a new version prefix, with v1 kept serving.
Availability is a different promise, and the honest one is smaller: this runs best-effort, with no uptime guarantee and no SLA. It is maintained by an independent team as a public good for the Hyperliquid ecosystem. Cache what you depend on.
Using the data
The data is free to use, including commercially. No key, no quota beyond the rate limit, no strings. Attribution is appreciated rather than required: a credit to Hypersight with a link back helps other builders find the source, and helps justify keeping the indexer running.
If you are building something that needs more than this serves, say so: the gaps other people hit are the best guide to what to index next.
What’s inside
| Resource | What it holds |
|---|---|
/v1/archive.json | Every settled price market: target, settle price, result, volume |
/v1/events.json | Every resolved event market: sides, winner, final score, question rules |
/v1/governance.json | Validator settlement activity, aggregated |
/v1/markets/{id}.json | One market: result, settlement voters, completeness flags |
/v1/markets/{id}/odds.json | That market’s odds curve, kept separate because it can be large |
/v1/archive/{YYYY-MM}.json | One month’s slice, for fetching or backfilling part of the archive |
/v1/changes.json | Recent resolutions, newest first: poll this instead of re-reading everything |
/v1/bulk/manifest.json | Gzipped JSON Lines of the whole archive, to ingest it once |
/v1/openapi.json | OpenAPI 3.1 description, field by field, if you generate clients |
/v1/manifest.json | Counts, coverage window, shard index, freshness contract |
Polling without waste
Every response carries an ETag. Send it back as If-None-Match and an
unchanged artefact answers 304 with no body, so a poller costs almost
nothing:
ETAG=$(curl -sI https://api.hypersight.xyz/v1/changes.json | grep -i '^etag:' | cut -d' ' -f2)
curl -s -o /dev/null -w '%{http_code}\n' -H "If-None-Match: $ETAG" \
https://api.hypersight.xyz/v1/changes.json # 304This works from a browser too: ETag, Retry-After and X-RateLimit-Limit
are CORS-exposed, so res.headers.get("etag") reads them cross-origin instead
of returning null.
The pattern that scales: ingest bulk/ once, then poll changes.json with
an ETag and fetch only the markets it names.
Continue with the resource reference, or read coverage & completeness to understand exactly what the data does and does not claim.