Free + premium tiers · CC0 data

API CATALOG

54 endpoints across history, asset analytics, arbitrage, movers, correlations, health, and account. All responses are JSON. Errors use the shape { ok: false, error } with appropriate 4xx/5xx codes and Cache-Control: no-store; success responses cache at the CDN for the per-endpoint TTL noted below. Each endpoint shows a tier badge — FREE needs no key.

Authentication & tiers

Most endpoints are FREE and need no key. Premium endpoints (PRO) require an API key when monetization is enabled — pass it as Authorization: Bearer <key> or X-API-Key: <key>. Keys carry a tier (free / pro / enterprise) with a monthly quota, a per-key rate limit, and a per-VENUE entitlement. Premium responses return X-Api-Tier, X-RateLimit-*, and X-Quota-*; denials are 401 (key) / 402 (tier) / 403 (venue) / 429 (rate or quota).

Check your own usage + quota at /api/account/usage. Full machine-readable policy is in the OpenAPI spec (x-monetization + per-operation security).

History store

/api/history/[venue]/[asset]PROcache 30s

Raw JSONL window from the sovereign history store

Return the recorded observations for one (venue, asset) over an optional time window. Records are sorted chronologically.

Query parameters

NameTypeRequiredDescription
fromMsintegernoInclusive lower-bound timestamp (epoch ms).
toMsintegernoInclusive upper-bound timestamp (epoch ms).
limitintegernoMax records returned. Default 1000, cap 50000.

Response shape

{ ok, venue, asset, count, records: [{t, p, v?, s?}] }

Sample curl

curl 'https://hypo.markets/api/history/hyperliquid/perp-btc?limit=10'

/api/history/[venue]/[asset]/csvENTERPRISEcache 30s

RFC 4180 CSV export of the JSONL window

Same record selection as /api/history/[venue]/[asset], but emits text/csv with a Content-Disposition header so browsers offer a download. Columns: t, p, v, s.

Query parameters

NameTypeRequiredDescription
fromMsintegernoInclusive lower bound (epoch ms).
toMsintegernoInclusive upper bound (epoch ms).
limitintegernoMax records, default 1000, cap 50000.

Response shape

text/csv with header row `t,p,v,s` + CRLF-terminated records (RFC 4180)

Sample curl

curl -OJ 'https://hypo.markets/api/history/hyperliquid/perp-btc/csv?limit=100'

/api/history/[venue]/[asset]/aggregateFREEcache 30s

OHLC + count + volume + VWAP bucketed downsampling

Group raw records into fixed-width time buckets aligned to the UNIX epoch. Buckets tile cleanly across adjacent fromMs/toMs windows.

Query parameters

NameTypeRequiredDescription
bucketMsintegeryesBucket width in milliseconds; must be > 0.
fromMsintegernoInclusive lower bound.
toMsintegernoInclusive upper bound.
openumnoOne of "all" (default), "ohlc", "vwap".

Response shape

{ ok, venue, asset, bucketMs, op, count, buckets: [{t, open?, high?, low?, close?, count?, volume?, vwap?}] }

Sample curl

curl 'https://hypo.markets/api/history/hyperliquid/perp-btc/aggregate?bucketMs=60000&op=ohlc'

/api/history/assetsFREEcache 60s

Sovereign store-wide (venue, asset) index

List every asset the store knows about with bytes-on-disk and firstMs/lastMs observation timestamps (both EXACT, O(1) head/tail reads). Each asset's `count` is a byte-derived ESTIMATE (countIsEstimate=true; perAssetCountIsEstimate=true at top level) so the index is constant-time regardless of store size — use recordCount for an exact value. Optional ?venue= filter.

Query parameters

NameTypeRequiredDescription
venueVenueIdnoRestrict to a single venue id.

Response shape

{ ok, count, totalBytes, perAssetCountIsEstimate, assets: [{venue, asset, bytes, firstMs, lastMs, count, countIsEstimate}] }

Sample curl

curl 'https://hypo.markets/api/history/assets?venue=hyperliquid'

Asset analytics

/api/asset/[asset]/riskFREEcache 30s

Realized vol + max drawdown + sharpe from the store

Log-return risk metrics computed inline from the sovereign history store. Falls back to an empty result when the store has fewer than `minBars` observations.

Query parameters

NameTypeRequiredDescription
minBarsintegernoDrop threshold for store→fallback switch. Default 30, cap 5000.

Response shape

{ ok, asset, kind, venue, storeKey, source: 'store' | 'fallback', periodsPerYear, minBars, metrics: {bars, returns, meanLogReturn, realizedVol, annualizedVol, annualizedReturn, sharpe, sharpeAdjAC, ulcerIndex, painIndex, modifiedVar95, martinRatio, cdar95, gainToPain, sterlingRatio, omega, rollSpreadBps, maxDrawdown, peakPrice, troughPrice, drawdownBars} }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/risk?minBars=30'

/api/asset/[asset]/slippageFREEcache 10s

Order-book walking simulator — avg fill, slippage in bp, tier breakdown

Walks the live order book (HL L2 or PM CLOB) and reports the volume-weighted average execution price, signed slippage versus mid, per-bp tier breakdown, and worst-fill level for the requested size.

Query parameters

NameTypeRequiredDescription
sizenumberyesQuote (USD) or base (contracts), per sizeUnit. > 0, ≤ 1B.
sideenumyes"buy" or "sell".
sizeUnitenumno"quote" (default, USD notional) or "base" (contracts).

Response shape

{ ok, asset, kind, venue, generatedAt, mode: 'live', params, result: {side, midPrice, topPrice, baseFilled, quoteFilled, remaining, fullyFilled, avgPrice, slippageBps, worstFillPrice, worstFillBps, levelsConsumed, tiers: [{bpsFrom, bpsTo, baseFilled, quoteFilled}]} }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/slippage?size=10000&side=buy'

/api/asset/[asset]/cascadesFREEcache 15s

Liquidation-cascade detector (price-only proxy)

Walks records and flags clusters where price falls (or rises with direction=up) by >= minDrawdownPct off a trailing windowMs peak/trough. Useful for spotting candidate forced-unwind events. CAVEAT: no exchange liquidation feed wired — purely a price-based proxy.

Query parameters

NameTypeRequiredDescription
windowMsintegernoTrailing window ms. Default 60000, cap 86400000.
minDrawdownPctnumbernoThreshold drawdown fraction, in (0, 1). Default 0.01.
directionenumno"down" (default) or "up".
fromMsintegernoInclusive lower bound (epoch ms).
toMsintegernoInclusive upper bound (epoch ms).
limitintegernoMax records read, default 5000, cap 50000.

Response shape

{ ok, asset, kind, venue, storeKey, params, summary: {clustersFound, deepestDrawdownFrac, totalCascadeBars, direction}, cascades: [{tStart, tEnd, bars, peakPrice, troughPrice, drawdownFrac}] }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/cascades?windowMs=60000&minDrawdownPct=0.005'

/api/asset/[asset]/streamPROcache 0s

SSE live data push for an asset (replaces client polling)

Server-Sent Events stream emitting one event per asset-pulse update — the live price/snapshot fanned out from a single upstream fetch to all subscribers. Premium realtime tier; charged per stream-connect when prepaid billing is enabled.

Response shape

text/event-stream: one JSON data: frame per pulse; ': connected' initial comment; ': heartbeat' every 25s

Sample curl

curl -N 'https://hypo.markets/api/asset/hl-BTC/stream'

/api/asset/[asset]/stream-flowPROcache 0s

SSE live order-flow delta (tick-rule classified)

Server-Sent Events stream emitting one event per asset-pulse update. Each event carries the new price, prev price, side (buy/sell/unclassified), signed weight, and per-connection cumulative. Per-client state — comparing cumulatives across clients is meaningless.

Response shape

text/event-stream: { t, p, prevP, v, weight, side, signed, cumulative } per event; ': connected' initial comment; ': heartbeat' every 25s

Sample curl

curl -N 'https://hypo.markets/api/asset/hl-BTC/stream-flow'

/api/asset/[asset]/flowFREEcache 15s

Order-flow imbalance via the tick rule (Lee-Ready 1991)

Classifies each recorded tick as buy- or sell-initiated using the price tick vs the previous record; zero ticks inherit the prior direction. Reports buy/sell volume, imbalance ratio, a VPIN-lite order-flow toxicity score in [0,1] (mean absolute imbalance across non-overlapping rollingWindow buckets — persistent one-sided pressure does not wash out the way it does in the net imbalance), full per-record series with cumulative delta, and a trailing rollingDelta array for charting.

Query parameters

NameTypeRequiredDescription
fromMsintegernoInclusive lower bound (epoch ms).
toMsintegernoInclusive upper bound (epoch ms).
limitintegernoMax records read, default 5000, cap 50000.
rollingWindowintegernoWindow size for rolling delta, default 60, max 5000.

Response shape

{ ok, asset, kind, venue, storeKey, params, summary: {bars, buyBars, sellBars, unclassifiedBars, buyVolume, sellVolume, netDelta, imbalance, vpin, hasRealVolume, impactLambda:number|null, impactLambdaBps:number|null, impactFromRealVolume}, series: [{t, side, weight, signed, cumulative}], rollingDelta, rollingWindow }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/flow?rollingWindow=120'

/api/asset/[asset]/volprofileFREEcache 30s

Volume profile + POC from the sovereign store

Builds a price-volume histogram from the recorded observations. For each price bin: bar count + cumulative volume (or count-weighted when records carry no volume). POC (point of control) is the highest-volume bin and gets isPoc:true.

Query parameters

NameTypeRequiredDescription
priceStepnumberyesBin width in price units; must be > 0.
fromMsintegernoInclusive lower bound (epoch ms).
toMsintegernoInclusive upper bound (epoch ms).
limitintegernoMax records read, default 5000, cap 50000.

Response shape

{ ok, asset, kind, venue, storeKey, params, recordsUsed, hasRealVolume, pocIdx, buckets: [{priceLow, priceHigh, count, volume, isPoc}] }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/volprofile?priceStep=100'

/api/asset/[asset]/carryFREEcache 60s

HL funding-rate carry — hourly + annualized + side breakdown

Per-hour funding rate, annualised rate, and per-side carry view (long + short) with days-to-1% and days-to-10% horizons. HL perps only; other kinds 404 with an explanatory message.

Response shape

{ ok, asset, kind: 'hl-perp', venue, coin, markPx, generatedAt, snapshotAgeMs, carry: {fundingHourly, fundingAnnualizedFrac, longSide, shortSide, flat} }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/carry'

/api/statsPROcache 15s

Tier-1 statistical metrics for the curated cross-venue asset set

Per-asset return/risk statistics over a 30d window. returnMode is LOG for HL perps (price levels, $) and DIFF for bounded probability series (PM/Kalshi/HL-pred) — Sharpe/Sortino/Calmar are SUPPRESSED on binary venues (√periodsPerYear annualisation is dimensionless; a `horizon` block with daysToResolve/perDayMove/terminalVariance is emitted instead). periodsPerYear is fixed at 8760. Results are cached ~20s in-process; `cached` + `resultsAgeMs` disclose staleness. `coverage`/`perVenue` describe which venues this engine actually has (a sovereign engine narrows). Each result carries `type` (the venue/kind discriminant, e.g. hl-perp) — there is no separate `venue` field and `stats` is FLAT (no nested `returns`). Shares the returnMode convention with the m2m bundle, but NOTE the window/cadence differ: this endpoint uses 30d of 1h candles (periodsPerYear 8760), while the bundle's risk block uses its own 24h history window annualised by a CADENCE-DERIVED periodsPerYear — so realizedVol is comparable in magnitude but not identical; don't cross-map the two as the same number.

Query parameters

NameTypeRequiredDescription
venuestringnoRestrict to one of hl/hl-pred/pm/kalshi.
maxintegernoCap the curated asset count.

Response shape

{ now, elapsedMs, cached, resultsAgeMs, requested, returned, venue, coverage, perVenue, snapshot, results: [{asset, type, name, markPx, changePct, stats: {n, returnMode, framing, annualisedVol, sharpe|null, sharpeSuppressedReason, sortino, var95, es95, maxDrawdown, hurst, autocorr1, halfLifeMR, verdict, horizon?}}] }

Sample curl

curl 'https://hypo.markets/api/stats?venue=kalshi&max=5'

/api/m2m/indexFREEcache 60s

M2M discovery — every asset a bot can query, grouped by venue

Returns the full asset universe a bot can pass to /api/m2m/[asset]/bundle or /api/m2m/batch. Each entry carries the asset id, venue, kind, lastPrice and isStale hint so a bot can pre-filter (e.g. 'only fresh hyperliquid perps') before committing to per-asset round-trips. Cached 60s — the universe changes slowly.

Response shape

{ ok, generatedAt, apiVersion, scope, summary:{total, byVenue, freshCount, staleCount}, generatedAtMs, filters:{kind:string[], fresh:boolean, minBasisBps:number|null, limit:number|null, offset}, returned, truncated, entries:[{asset, venue, kind, lastPrice, name:string|null, isStale, fairPrice:number|null, basisBps:number|null}] · params: ?kind=perp|binary|pred (CSV) ?fresh=true ?minBasisBps=N (perp |mark-vs-oracle basis| screen) ?limit=N ?offset=N, bundleEndpoint, batchEndpoint }

Sample curl

curl 'https://hypo.markets/api/m2m/index'

/api/m2m/batchFREEcache 0s

M2M batch — many bundles in one round-trip (portfolio scan)

POST {assets:[id, id, ...]} (max 50 per request) and get back an array of bundles. Server-side composition lets the snapshot fan-out and assetIndex cache reuse across all assets in the batch, saving disk reads vs N independent /bundle calls. Per-asset errors don't fail the batch: each item is either a successful bundle or {ok:false, asset, error}. CORS preflight (OPTIONS) supported for browser-based bots.

Response shape

{ ok, generatedAt, apiVersion, requestedCount, bundles:[ ...bundle | {ok:false, asset, error} ] } — each successful bundle has the same shape as /api/m2m/[asset]/bundle (freshness.historyLastEverMs included; series?:{...} when body.series=true)

Sample curl

curl -X POST -H 'Content-Type: application/json' -d '{"assets":["hl-BTC","hl-ETH"]}' 'https://hypo.markets/api/m2m/batch'  # add ,"series":true to bundle sparkline data on every item

/api/m2m/[asset]/stream-signalPROcache 0s

M2M SSE — push signal updates as the asset pulse refreshes

Server-Sent Events stream of freshly-composed M2M bundles. Bots subscribe once, get signal updates pushed every time the asset's pulse refreshes (cadence floor 1500ms, idle bump every 15s during quiet periods). Same bundle shape as the REST /bundle endpoint — bots can pipe both through the same parser. Per-connection state tracked server-side. Heartbeat comment every 25s for proxy keepalive.

Response shape

text/event-stream — each data: line is a JSON M2MBundle with an added `cause` field ("init"|"pulse"|"idle")

Sample curl

curl -N 'https://hypo.markets/api/m2m/[asset]/stream-signal'

/api/m2m/[asset]/bundlePROcache 15s

M2M unified bundle — one round-trip, every signal a bot needs

Machine-to-machine endpoint for AI agents and trading bots. Composes price, freshness, risk metrics, flow lean, carry hint, synthesized direction + confidence, and a venue-native URL with suggested side. HYPO is data-only — bots execute on the venue's native API via tradeHint.venueNativeUrl. Versioned: response always carries apiVersion. Sub-15s polling cached at the CDN; faster cadence consumers should use the per-asset SSE streams.

Response shape

{ ok, generatedAt, generatedAtMs, apiVersion, schema:{version, optionalBlocks[]}, asset, venue, storeKey, freshness:{feedAgeMs, historyLastMs, historyLastEverMs, isStale}, name:string|null, price:{last, bid, ask, spreadBps, change24hPct, unit:'usd'|'probability', change24hSource:'snapshot'|'store-delta'|null, fairValue:number|null, basisBps:number|null}, fairValue:{value:number|null, unit:'usd'|'probability', basisBps:number|null, source:'hl-oracle'|'consensus'|'none', confidence:number|null, dispersionBps:number|null, nVenues:number|null, isStale}, liquidity:{liquidityUsd, openInterestUsd, volume24hUsd, volumeTotalUsd, source:'snapshot'|null}, horizon:{endDate, daysToResolve, resolvedFrom:'closeTime'|'endDate'|null, terminalVariance}|null, risk:{realizedVolAnnualizedPct, maxDrawdownPct, sharpe, ulcerIndexPct, painIndexPct, modifiedVar95Pct, martinRatio, cdar95Pct, gainToPain, sterlingRatio, omega, rollSpreadBps, barsUsed, source:'store'|'fallback'|'insufficient', returnBasis:'log'|'diff'|null, windowMs, periodsPerYear}, flow:{imbalance, lean:'BID'|'ASK'|null}, carry:{fundingAprPct, side:'longs_pay'|'shorts_pay'|'flat'}, signals:{direction:'LONG'|'SHORT'|'NEUTRAL', confidence, reasons[]}, tradeHint:{venueNativeUrl, suggestedSide:'BUY'|'SELL'|null, notes[]}, series?:{prices[], points, windowMs} (opt-in via ?series=true) }

Sample curl

curl 'https://hypo.markets/api/m2m/[asset]/bundle'  # try hl-BTC, pm-trump-2024, or any other asset id

/api/feedFREEcache 4s

Apex feed: the full HL + PM + Kalshi snapshot with ages and stale flags

The same FeedSnapshot every server-side page reads via readFeed(). Includes per-venue snapshots, ages in ms, stale booleans (gated by STALE_THRESHOLD_MS = 120s), and the last error per venue. Force-dynamic; consumers should respect the cache-control header.

Response shape

{ ok, hyperliquid, polymarket, kalshi, limitless, ages:{hyperliquid, polymarket, kalshi, limitless}, stale:{hyperliquid, polymarket, kalshi, limitless}, errors:{hyperliquid, polymarket, kalshi, limitless}, bodyAgeMs }  // bodyAgeMs: age of this (≤1s micro-cached) body. Kalshi markets also carry volume24hUsd (price-weighted $) + volume24hContracts (raw count).

Sample curl

curl 'https://hypo.markets/api/feed'

/api/asset/[asset]FREEcache 10s

Per-asset dashboard payload — candles + book/history + snapshot

The composite payload powering /feed/[asset]'s server-rendered dashboard. Includes raw quote/market/prediction object, candles or price-history series, and the live order book (HL perps only). The shape varies by asset kind (hl-perp / hl-pred / pm / kalshi) — discriminate on the `type` field.

Query parameters

NameTypeRequiredDescription
assetstringyesPath parameter — asset id (hl-BTC, pm-{slug}, kalshi-{ticker}, hl-pred-{slug-or-outcomeId}).

Response shape

{ ok, asset, type: 'hl-perp'|'hl-pred'|'pm'|'kalshi', now, snapshot:{fetchedAt, ageMs, stale}, ...kindSpecificFields }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC'

/api/asset/[asset]/statsPROcache 15s

Pre-computed analytical statistics — Sharpe, Sortino, Calmar, Hurst, VaR, ES

Heavier statistical pack than /api/asset/[asset]/risk: includes Sharpe + Sortino + Calmar + AC-adjusted Sharpe (Lo 2002) + Omega + Hurst + ACF + ADF + KPSS + variance ratio + Jarque-Bera + Ljung-Box (+ a lag [1,2,3,5,10] LB profile) + Roll (1984) implied spread (bps) + Ulcer Index + multi-tail Expected Shortfall (es90/es95/es99 + tail-concentration) + Brier-on-self-history + drawdown summary. Computed from upstream candles (no store dependency). NOTE: for binary venues (PM, Kalshi, HL-pred) the response is HORIZON-FRAMED — annualised Sharpe/Sortino/Calmar/AC-Sharpe are suppressed (null, with returns.framing='horizon' + sharpeSuppressedReason) because √periodsPerYear scaling is dimensionless on a bounded [0,1] probability; a `horizon` block (daysToResolve, perDayMove, perHorizonMove, terminalVariance=p(1−p), resolvedFrom, available) keyed to time-to-resolution is returned instead. HL perps remain annualised (framing='annualised', horizon=null). Omega/Ulcer/Roll-spread/multi-tail-ES/LB-profile are emitted for BOTH framings (not √T-annualised).

Query parameters

NameTypeRequiredDescription
assetstringyesPath parameter — asset id.

Response shape

{ ok, asset, type, now, snapshot, stats:{...analyticalMetrics, returns:{sharpe:number|null, sortino:number|null, calmar:number|null, sharpeAdjAC:number|null, omega:number|null, gainToPain:number|null, annualisedVol, returnMode:'log'|'diff', framing:'annualised'|'horizon', sharpeSuppressedReason:string|null}, risk:{var95, var99, es95, es90, es99, esTailConcentration:number|null, ulcerIndex, cdar95, drawdownAtRisk95, sterling:number|null, tailIndex:number|null, tailIndexWide:number|null, maxDrawdown, ...}, structure:{hurst, autocorr1, autocorr2, trendT, halfLifeMR:number|null, permEntropy, permEntropyTieFrac, rollSpreadBps}, tests:{ljungBox, ljungBoxProfile:[{lag, stat, p, reject}], adf, kpss, runs, varianceRatio, jarqueBera}, horizon:{daysToResolve, barsPerDay, perDayMove, perHorizonMove, terminalVariance, resolvedFrom:'closeTime'|'endDate'|null, available}|null}, benchmark?:{benchmarkAsset, up:number|null, down:number|null, captureSpread:number|null, alignedBars}|null (HL perps only) }

Sample curl

curl 'https://hypo.markets/api/asset/hl-BTC/stats'

/api/book/[asset]FREEcache 4s

Live order book for an HL perp or PM market

Bid + ask ladders from the venue's depth API. HL perps return L2 levels; PM returns the CLOB's yes-side book. Use /api/asset/[asset]/slippage for size-aware execution simulation.

Query parameters

NameTypeRequiredDescription
assetstringyesPath parameter — asset id.

Response shape

{ ok, asset, kind, bids:[{price, size}], asks:[{price, size}], fetchedAt }

Sample curl

curl 'https://hypo.markets/api/book/hl-BTC'

/api/m2m/[asset]/quoteFREEcache 2s

Ultra-low-latency price tick — current price + freshness only

Micro-endpoint companion to /api/m2m/[asset]/bundle. Returns ONLY price (last/bid/ask/spreadBps/change24hPct) + freshness (feedAgeMs/isStale). No risk metrics, no signal synthesis, no history-store read by default. Warm latency ~1-2ms vs ~50ms for /bundle. Use for latency-sensitive bot scans across many assets. IMPORTANT for movement scanners: `change24hPct` is populated only for HL perps (snapshot-native); for Polymarket/Kalshi/Limitless it is ALWAYS null here (`change24hSource` is null) because the binary-venue 24h delta is a history-store computation done only in /bundle — to scan binary-venue movement use /movers or /bundle, not /quote. Optional ?activity=true adds historyLastEverMs (costs ~1-2ms of tail-read disk IO) for callers that want the 'last seen' signal alongside the live tick. Versioned: apiVersion='v1' (new optional fields are backwards-compatible).

Query parameters

NameTypeRequiredDescription
assetstringyesPath parameter — asset id (hl-BTC, pm-{slug}, kalshi-{ticker}, hl-pred-{slug-or-outcomeId}).
activitybooleannoQuery — set to 'true' to include freshness.historyLastEverMs (last write on disk). Costs ~1-2ms.
venueNativeUrlbooleannoQuery — set to 'false' to drop venueNativeUrl (~50-100 bytes) for byte-saving scans. Default true.

Response shape

{ ok, generatedAt, apiVersion, asset, venue, storeKey, price:{last, bid, ask, spreadBps, change24hPct (null on PM/Kalshi/Limitless — use /movers|/bundle), change24hSource:'snapshot'|null, fairValue:number|null, basisBps:number|null (perp HL-oracle, snapshot-local)}, freshness:{feedAgeMs, isStale, historyLastEverMs?} (opt-in ?activity=true), venueNativeUrl }

Sample curl

curl 'https://hypo.markets/api/m2m/[asset]/quote'  # try hl-BTC, pm-{slug}, or any other asset id

Arbitrage

/api/arb/simPROcache 15s

Cross-venue arb portfolio simulator with equal-split allocation

Allocates capital across the live cross-venue arb opportunities and reports total expected edge, capital efficiency, per-venue exposure, and a ranked top-N selection. Paper sim — no fees, slippage, or settlement risk modelled.

Query parameters

NameTypeRequiredDescription
capitalnumberyesTotal USD to deploy. (0, 1B].
maxSpreadnumbernoSpread filter ceiling, fraction. (0, 1]. Default 0.50.
minLegsintegernoMinimum venues per opportunity. Default 2.
topNintegernoCap on selected opportunities. Default 10, max 100.

Response shape

{ ok, generatedAt, snapshotAges, params, summary: {opportunitiesConsidered, opportunitiesSelected, capitalDeployed, expectedProfit, expectedEdgePct, capitalEfficiency, avgSpread, minSpread, maxSpread, venueExposure}, selected: [...] }

Sample curl

curl 'https://hypo.markets/api/arb/sim?capital=10000'

Movers

/api/moversFREEcache 60s

Top 24h gainers + losers across HL perps, PM, Kalshi

Ranks every live asset by absolute 24h change and splits into gainers / losers. HL perps derive from the feed's native percent change; PM and Kalshi use a store-delta computed from the sovereign history store over the trailing 24 hours. NOTE: each row's `changeFrac` is a FRACTION (0.366 = +36.6%) — deliberately distinct from /api/feed's `changePct` which is a PERCENT (they differ by 100x).

Query parameters

NameTypeRequiredDescription
topNintegernoCap per direction. Default 25, max 100.
minPriceChangePctnumbernoFilter floor as a fraction (0.05 = 5%). Default 0.
kindcsvnoComma-separated subset of hl-perp, hl-pred, pm, kalshi.

Response shape

{ ok, generatedAt, params, gainers: [{asset, name, kind, venue, changeFrac, currentPrice, source}], losers: [{asset, name, kind, venue, changeFrac, currentPrice, source}], totals: {considered, eligible, avgAbsChange} }

Sample curl

curl 'https://hypo.markets/api/movers?topN=5'

Correlations

/api/correlationsFREEcache 30s

Pairwise Pearson + Spearman matrix over log returns

Pulls log returns from the sovereign store for N (2..20) assets over a trailing window and computes the symmetric N×N correlation matrix. Both methods by default; assets with insufficient store data are dropped and surfaced in `dropped`.

Query parameters

NameTypeRequiredDescription
assetscsvyesComma-separated asset ids. 2..20 entries, no duplicates.
windownumbernoTrailing window in hours. Default 24, max 720 (30d).
methodenumno"both" (default), "pearson", or "spearman".

Response shape

{ ok, generatedAt, params, surviving, dropped, barsPerAsset, alignedReturnsLen, pearson: {labels, matrix} | null, spearman: {labels, matrix} | null }

Sample curl

curl 'https://hypo.markets/api/correlations?assets=hl-BTC,hl-ETH,hl-SOL&window=24'

Health probes

/api/health/endpointsFREEcache 30s

In-process probe aggregator for the 9 night-build endpoints

Invokes each route handler in-process (no HTTP loopback) and reports status code, latency, and last-checked ISO timestamp per probe. Cached for 30s globally.

Response shape

{ ok, generatedAt, summary: {healthy, degraded, errored, total, avgLatencyMs, maxLatencyMs, verdict}, probes: [{endpoint, sampleUrl, status, statusCode, sampleLatencyMs, lastChecked, error}] }

Sample curl

curl 'https://hypo.markets/api/health/endpoints'

/apiFREEcache 3600s

Endpoint index — minimal JSON list of every public route

Lightweight catalog endpoint. Returns `{ ok, count, catalog, endpoints }` where each endpoint carries path + method + summary + group + cacheSeconds. Useful for tooling that just needs the URL list without the full OpenAPI spec.

Response shape

{ ok, count, catalog: {docs, spec}, endpoints: [{path, method, summary, group, cacheSeconds}] }

Sample curl

curl 'https://hypo.markets/api'

/api/openapi.jsonFREEcache 3600s

OpenAPI 3.1 spec for every public read endpoint

Machine-readable schema describing every endpoint in this catalog. Generated from lib/api-catalog at request time so adding a new route auto-propagates to OpenAPI consumers. Static-cacheable; the spec only changes when the catalog does.

Response shape

OpenAPI 3.1.0 document: { openapi, info, servers, tags, paths, components }

Sample curl

curl 'https://hypo.markets/api/openapi.json'

/api/alerts/staleFREEcache 60s

JSON mirror of /alerts staleness dashboard

Returns the same data as /alerts in JSON so external monitors can poll without scraping HTML. Default threshold 5 minutes; configurable via ?thresholdMin=.

Query parameters

NameTypeRequiredDescription
thresholdMinnumbernoStaleness threshold in minutes. Default 5, max 1440.
limitintegernoCap on stale[] and neverRecorded[] arrays. Default 1000, max 10000. Summary tally reflects the full count regardless.
sortBystringnoSort key for the visible window: staleness | asset | venue. Defaults: staleness for stale[], asset for neverRecorded[]. Applied AFTER the limit slice.
venuestringnoRestrict to a single venue id (e.g. hyperliquid, polymarket, kalshi). 400 on unknown. Applied BEFORE detection — summary tally and limit cap reflect the filtered subset.

Response shape

{ ok, generatedAt, params: {thresholdMin, thresholdMs, limit, sortBy, venue}, summary: {totalAssets, staleCount, neverRecordedCount, byVenue}, truncated: {stale, neverRecorded}, stale: [...], neverRecorded: [...] }

Sample curl

curl 'https://hypo.markets/api/alerts/stale?venue=hyperliquid&thresholdMin=15&limit=100'

/api/alerts/stale.csvFREEcache 60s

RFC 4180 CSV mirror of /api/alerts/stale

Same query surface and validation envelope as the JSON endpoint, but emits text/csv with a download attachment. Columns: kind (stale|never_recorded), venue, asset, lastIso, staleForMs, count, bytes. Stale rows precede never-recorded rows. Summary tally is dropped; consumers wanting that should call /api/alerts/stale.

Query parameters

NameTypeRequiredDescription
thresholdMinnumbernoStaleness threshold in minutes. Default 5, max 1440.
limitintegernoCap per-block (stale and neverRecorded each capped). Default 1000, max 10000.
sortBystringnoSort key: staleness | asset | venue. Applied AFTER the per-block limit slice.
venuestringnoRestrict to a single venue id. 400 on unknown. Filter applied BEFORE detection; the filename also embeds the venue.

Response shape

text/csv with header row: kind,venue,asset,lastIso,staleForMs,count,bytes

Sample curl

curl -O 'https://hypo.markets/api/alerts/stale.csv?venue=hyperliquid&thresholdMin=15'

/api/alerts/stale/historyFREEcache 60s

Rolling-snapshot of the staleness verdict over the past N hours

Single-snapshot foundation today; future expansion will read a sovereign JSONL window so a dashboard can chart verdict drift over the last 6/12/24h. ?hours= is validated up-front so consumers can wire against the response shape now.

Query parameters

NameTypeRequiredDescription
hoursnumbernoWindow in hours. Default 6, max 48. Validated today; reserved for the future historical snapshotter.
thresholdMinnumbernoStaleness threshold in minutes. Default 5, max 1440.

Response shape

{ ok, generatedAt, params: {hours, thresholdMin, thresholdMs}, snapshots: [{ts, verdict, summary}], note }

Sample curl

curl 'https://hypo.markets/api/alerts/stale/history?hours=12'

/api/alerts/stale/snapshotFREEcache 0s

Cron trigger that persists one staleness snapshot

Computes the current verdict + summary and appends one record to the sovereign stale-snapshots JSONL store. Rate-limited to one write per 60s (returns 200 with skipped:true if called sooner). When the HYPO_SNAPSHOT_TOKEN env is set, requests must carry a matching X-Snapshot-Token header (401 otherwise); when unset, the endpoint is open (intended for fully-local dev).

Response shape

{ ok, skipped, written?: {ts, verdict, summary}, reason?, lastSnapshotAgeMs? }

Sample curl

curl -X POST -H 'X-Snapshot-Token: $TOKEN' 'https://hypo.markets/api/alerts/stale/snapshot'

/api/feed/healthFREEcache 5s

Feed-cache poller diagnostics (per-upstream counters + last error)

Surfaces the state of the in-process feed-cache poller: per-upstream ok/fail counters, last error message, snapshot age, pollersRunning boolean. Verdict OK when all three upstreams have snapshots, WARN when partial, DOWN when no poller is running OR every poll has failed since start (HTTP 503 on DOWN). Also a per-venue `venues` freshness map and a `degraded` map (+`anyDegraded`): a degraded venue is one actively erroring (failCount>0, lastError set) while its last snapshot is still fresh — a LEADING indicator (the pre-120s-stale-cliff window) that does NOT change the verdict, so transient 429s don't flap OK.

Response shape

{ ok, generatedAt, verdict, venues:{hyperliquid, polymarket, kalshi, limitless}, degraded:{hyperliquid, polymarket, kalshi, limitless}, anyDegraded, health:{ startedAt, uptimeMs, pollersRunning, hyperliquid:{lastFetchedAt, ageMs, okCount, failCount, lastError, pollIntervalMs, hasSnapshot}, polymarket:{...}, kalshi:{...}, limitless:{...} } }

Sample curl

curl 'https://hypo.markets/api/feed/health'

/api/health/anomaliesFREEcache 5s

Live data-integrity invariant checker (alertable verdict)

Runs detectAnomalies() over the current in-memory snapshot and surfaces invariant violations for an external alerting cron: stale/missing/empty venues, probabilities outside [0,1], non-positive HL prices, the Kalshi empty-no-book noProb=0.50 artifact, gross overround, and money-path health (billing write failures, low disk, held over-cap deposits). verdict is ok | degraded (a warning present) | critical. Sovereign-aware: an engine is only faulted for the venue(s) it serves (apex=all three). PAGE ON `alertable === true`, NOT `verdict !== 'ok'` — `verdict` flaps to degraded/critical during the ~90s post-restart warm-up grace while the first poll lands, but `alertable` is false during that grace (and true only on a real problem).

Response shape

{ ok, verdict, warming, alertable, scope, counts:{ total, critical, warning }, anomalies:[{ severity, code, venue, message, count? }], generatedAt }

Sample curl

curl 'https://hypo.markets/api/health/anomalies'

/api/health/snapshotterFREEcache 30s

Liveness check on the sovereign stale-snapshotter file

Returns the same stats /status renders plus a coarse verdict (OK / WARN / DOWN) classified by the age of the most recent snapshot. Returns HTTP 503 on DOWN so naive monitors (`curl --fail`, uptime-kuma's HTTP status mode) get the right signal without parsing the body. Thresholds: OK <= 10 min, WARN <= 30 min, DOWN beyond that or file absent.

Response shape

{ ok, generatedAt, verdict, reason, thresholds: {warnAfterMs, downAfterMs}, stats: {exists, sizeBytes, lastTs, lastTsMs, ageMs, count24h} }

Sample curl

curl --fail 'https://hypo.markets/api/health/snapshotter'

/api/health/upstreamFREEcache 30s

Network probe over HL, PM, Kalshi data sources

Goes over the wire to each upstream with a 5s AbortController timeout per probe. Surfaces network errors, rate-limit codes, and round-trip latency. Independent from /api/health/endpoints.

Response shape

{ ok, generatedAt, scope, summary: {healthy, degraded, errored, total, avgLatencyMs, maxLatencyMs, verdict}, probes: [{upstream, probedUrl, method, status, statusCode, latencyMs, lastChecked, error}] }

Sample curl

curl 'https://hypo.markets/api/health/upstream'

/api/healthFREEcache 0s

Apex liveness — quick yes/no whether the process is up + SSE fan-out telemetry

Minimal endpoint for liveness checks: returns ok + uptime + asset-pulse subscriber counts. Lighter than /api/feed/health (which goes deeper into per-upstream state). Use this for top-level uptime monitoring; /api/feed/health for the data-pipeline verdict.

Response shape

{ ok, uptimeMs, pulse:{assetsPolling, totalSubscribers, perAsset} }

Sample curl

curl 'https://hypo.markets/api/health'

Account & billing

/api/account/usageKEYcache 0s

Your API key's usage, quota, tier, and per-venue breakdown (this UTC month)

Self-service usage report for the caller's own API key. Authenticate with the key being reported on (Authorization: Bearer <key> or X-API-Key). Returns the tier, its limits (monthly quota, per-key rate, features, venue entitlement), and the current-month usage including the per-venue split that underpins per-venue billing.

Response shape

{ ok, tier, owner, venues, month, limits:{monthlyQuota, ratePerMin, maxConcurrentStreams, features, venues}, usage:{total, quotaRemaining, byVenue, byEndpoint, firstAt, lastAt}, key:{hash, createdAt, expiresAt} }

Sample curl

curl -H 'X-API-Key: k_live_…' 'https://hypo.markets/api/account/usage'

/api/account/keysADMINcache 0s

Admin key management — issue (POST), list (GET), revoke (DELETE)

Admin-only API-key lifecycle, gated by the HYPO_ADMIN_TOKEN bearer (fail-closed in production). POST {tier, owner, label?, venues?, expiresAt?} issues a key and returns the raw key ONCE (only its SHA-256 hash is stored). GET lists key metadata (hashes only). DELETE {keyHash} revokes.

Query parameters

NameTypeRequiredDescription
tierenumyesfree | pro | enterprise (POST body).
ownerstringyesAccount id / email (POST body).
venuescsvnoPer-key venue allow-list, or "all" (POST body).
expiresAtintegernoExpiry epoch-ms, or null (POST body).
keyHashstringnoKey hash to revoke (DELETE body).

Response shape

POST → { ok, rawKey, record }; GET → { ok, keys:[record] }; DELETE → { ok, revoked }

Sample curl

curl -XPOST -H 'Authorization: Bearer $HYPO_ADMIN_TOKEN' -H 'Content-Type: application/json' -d '{"tier":"pro","owner":"acme@x.com"}' 'https://hypo.markets/api/account/keys'

/api/account/balanceKEYcache 0s

Your prepaid USDC/USDT balance, recent ledger, and the price list

Self-service prepaid balance for the caller's API key (µUSD + USD). Includes the recent credit/debit ledger and the per-call price list. Top up by depositing USDC/USDT (see /api/account/wallets).

Response shape

{ ok, owner, balance:{microUsd, usd}, prepaidEnabled, priceListMicroUsd, ledger:[{ts, type, microUsd, balanceAfter, ref}] }

Sample curl

curl -H 'X-API-Key: k_live_…' 'https://hypo.markets/api/account/balance'

/api/account/walletsKEYcache 0s

Register the wallet(s) you pay FROM + discover deposit addresses

GET returns your registered pay-from wallets, the per-chain deposit addresses (USDC/USDT across the top-10 chains), and the price list. POST {address} registers an EVM/Tron/Solana wallet — a deposit from it credits your prepaid balance automatically.

Query parameters

NameTypeRequiredDescription
addressstringnoPay-from wallet (0x… EVM / T… Tron / base58 Solana) — POST body.

Response shape

GET → { ok, registeredWallets, depositTargets:[{chain, asset, depositAddress}], priceListMicroUsd }; POST → { ok, registeredWallets }

Sample curl

curl -XPOST -H 'X-API-Key: k_live_…' -H 'Content-Type: application/json' -d '{"address":"0xYourWallet"}' 'https://hypo.markets/api/account/wallets'

/api/account/deposit-addressKEYcache 0s

Your unique per-chain deposit address (CREATE2 forwarders)

Returns a deposit address UNIQUE to your account on each configured chain, derived deterministically (CREATE2) so it is byte-identical to where funds are swept. Send USDC/USDT on the matching chain to your address; confirmed deposits credit your prepaid balance automatically — no pay-from registration needed. Dormant (503) until per-customer deposits are configured.

Query parameters

NameTypeRequiredDescription
chainstringnoLimit to one chain (e.g. 'base'); default returns every configured chain.

Response shape

{ ok, owner, addresses:[{chain, address, assets}] }

Sample curl

curl -H 'X-API-Key: k_live_…' 'https://hypo.markets/api/account/deposit-address?chain=base'

/api/account/creditADMINcache 0s

Admin manual credit (fiat/Stripe bridge, adjustments)

Admin-only off-chain top-up gated by HYPO_ADMIN_TOKEN, idempotent by `ref`. On-chain USDC/USDT deposits are credited automatically by the watcher; this is the manual/fiat path.

Query parameters

NameTypeRequiredDescription
ownerstringyesAccount owner to credit (POST body).
usdnumbernoAmount in USD (or microUsd) — POST body.
refstringyesIdempotency key, e.g. stripe_pi_… (POST body).

Response shape

{ ok, owner, applied, microUsd, balanceMicroUsd }

Sample curl

curl -XPOST -H 'Authorization: Bearer $HYPO_ADMIN_TOKEN' -H 'Content-Type: application/json' -d '{"owner":"acme@x.com","usd":50,"ref":"stripe_pi_1"}' 'https://hypo.markets/api/account/credit'

/api/account/webhook/[provider]WEBHOOKcache 0s

PSP deposit webhook (Coinbase Commerce / Stripe / generic HMAC)

Signed deposit webhook sink. provider ∈ coinbase | stripe | hmac. The signature is verified over the RAW body (fail-closed if the provider secret is unset), then the deposit is credited to the account in metadata.hypo_owner — idempotent by the PSP event id. This is the no-custody path (the PSP attributes the payment + handles per-customer addresses + fiat); the on-chain watcher is the self-custody path. Both credit the same ledger.

Query parameters

NameTypeRequiredDescription
providerenumyesPath param: coinbase | stripe | hmac.

Response shape

{ ok, provider, owner, applied, microUsd, balanceMicroUsd }  (200); ignored events → { ok, ignored }; bad signature → 401; secret unset → 503

Sample curl

# configured in the PSP dashboard, not called by hand:
# Coinbase Commerce → https://hypo.markets/api/account/webhook/coinbase
# Stripe           → https://hypo.markets/api/account/webhook/stripe

/api/account/vouchersADMINcache 0s

Admin — issue prepaid voucher codes (one of the parallel funding paths)

Issue redeemable voucher codes worth a fixed amount, gated by HYPO_ADMIN_TOKEN. POST {usd|microUsd, count?, expiresAt?, label?} returns the raw codes ONCE (only SHA-256 hashes are stored). GET lists voucher metadata. Customers redeem at /api/account/redeem; the credit lands in the same prepaid balance as on-chain / PSP / admin top-ups.

Query parameters

NameTypeRequiredDescription
usdnumbernoVoucher value in USD (or microUsd) — POST body.
countintegernoHow many to issue (default 1, max 1000) — POST body.
expiresAtintegernoExpiry epoch-ms, or null — POST body.

Response shape

POST → { ok, count, microUsd, codes:["HYPO-…"] }; GET → { ok, vouchers:[record] }

Sample curl

curl -XPOST -H 'Authorization: Bearer $HYPO_ADMIN_TOKEN' -H 'Content-Type: application/json' -d '{"usd":25,"count":10}' 'https://hypo.markets/api/account/vouchers'

/api/account/redeemKEYcache 0s

Redeem a prepaid voucher code into your balance

Redeem a voucher (POST {code}) — single-use + idempotent — crediting the caller's prepaid balance. Authenticated by your API key. Works alongside on-chain deposits, PSP webhooks, and admin credits: all converge on one balance per account.

Query parameters

NameTypeRequiredDescription
codestringyesThe voucher code, e.g. HYPO-ABCDE-FGHJK-LMNPQ (POST body).

Response shape

{ ok, owner, microUsd, balanceMicroUsd } (200); invalid OR already-redeemed → 404 invalid_code (indistinguishable, anti-enumeration); expired → 410

Sample curl

curl -XPOST -H 'X-API-Key: k_live_…' -H 'Content-Type: application/json' -d '{"code":"HYPO-ABCDE-FGHJK-LMNPQ"}' 'https://hypo.markets/api/account/redeem'

/api/account/treasuryADMINcache 0s

Admin — prepaid float/treasury report (yield visibility)

Total prepaid liability held across all customers — the float you custody until usage consumes it, available for yield (T-bills / on-chain). Gated by HYPO_ADMIN_TOKEN.

Response shape

{ ok, float:{ totalMicroUsd, totalUsd, accounts, nonZeroAccounts } }

Sample curl

curl -H 'Authorization: Bearer $HYPO_ADMIN_TOKEN' 'https://hypo.markets/api/account/treasury'

/api/admin/flagsADMINcache 0s

Admin — live operational flag state + global kill toggle

The operator control surface (powers the /ops console). GET returns the LIVE state of every operational flag across bot (execMode, engineLoop, vaultEnabled, globalKill, tradeFee), monetization (paidGating, prepaidBilling), deposits (EVM, Solana), and security (trustProxy). POST {globalKill:true|false} toggles the runtime bot kill-switch (no restart). Env-driven flags are read-only (flip in the engine's env file + restart). Gated by HYPO_ADMIN_TOKEN (Bearer).

Response shape

{ ok, flags:{ bot:{execMode,engineLoop,vaultEnabled,globalKill,tradeFeeMicroUsd}, monetization:{paidGating,prepaidBilling}, deposits:{evm,solana}, security:{trustProxy}, dataVenues:[{venue,shipped,tier}], process:{venue,nodeEnv} }, engines:[{venue,port,verdict}] }

Sample curl

curl -H 'Authorization: Bearer $HYPO_ADMIN_TOKEN' 'https://hypo.markets/api/admin/flags'

Trading bot

/api/bot/statusKEYcache 0s

HYPO Bot — system + per-account status (free)

Status for the autonomous trading bot (bot.hypo.markets). Unauthenticated → public system status (execMode mock|live, global kill, engine-loop flag). Authenticated (API key) → adds the caller's config, kill state, prepaid balance, recent orders, and access-fee totals. NON-CUSTODIAL: the bot trades on the USER's OWN venue account; HYPO never holds trading funds — only the per-trade access fee billed from prepaid credit. Execution is DORMANT (execMode='mock') until live adapters + the credential vault ship.

Response shape

{ ok, authenticated, system:{execMode:'mock'|'live', globalKill, engineLoop, vaultEnabled}, killed?, balanceMicroUsd?, config?:{enabled, venues[], assets[], minConfidence, tradeSizeUsd, feeMicroUsd, maxStaleMs}, connectedVenues?:[{venue, kind, addedAt}], activity?:{orderRecords, filled, fills, accessFeesMicroUsd}, recentOrders?:[{t, clientOrderId, venue, venueAsset, side, sizeUsd, status, feeAccessMicroUsd}] }

Sample curl

curl -H 'X-API-Key: $HYPO_KEY' 'https://bot.hypo.markets/api/bot/status'

/api/bot/controlKEYcache 0s

HYPO Bot — configure the caller's bot + kill-switch

Update the caller's single bot. Body (all optional): enabled, venues (subset of hyperliquid|polymarket|kalshi|limitless), assets[], minConfidence (0..1 signal floor), tradeSizeUsd (per-trade notional — NO cap), maxStaleMs (stale-signal guard), kill (boolean — instant halt override that wins over enabled). feeMicroUsd is NOT user-settable (operator revenue). 1 bot per key; open more by provisioning more keys.

Response shape

{ ok, config:{enabled, venues[], assets[], minConfidence, tradeSizeUsd, feeMicroUsd, maxStaleMs, updatedAt}, killed }

Sample curl

curl -X POST -H 'X-API-Key: $HYPO_KEY' -H 'Content-Type: application/json' -d '{"enabled":true,"venues":["hyperliquid"],"assets":["hl-BTC"],"minConfidence":0.65}' 'https://bot.hypo.markets/api/bot/control'

/api/bot/tradeKEYcache 0s

HYPO Bot — place one order on the caller's own venue account (billed per trade)

Place ONE explicit order non-custodially on the caller's OWN venue account, billing the flat per-trade access fee from prepaid credit ONLY on a real fill. Body: { venue (hyperliquid|polymarket|kalshi|limitless), asset, side (buy|sell), sizeUsd>0, markPrice>0 (execution reference), clientOrderId? (idempotency) }. Idempotent on clientOrderId — a replay never double-places or double-bills. Live execution is double-gated (HYPO_BOT_EXEC_MODE=live AND the per-user credential vault); until then it returns 503 in live mode and executes against the deterministic MockVenue in mock mode. 402 on insufficient prepaid credit; 423 when the kill-switch is set.

Response shape

{ ok, execMode:'mock'|'live', outcome:{status:'filled'|'resting'|'rejected'|'duplicate'|'killed'|'insufficient_balance', clientOrderId, chargedMicroUsd, order?, reason?} }

Sample curl

curl -X POST -H 'X-API-Key: $HYPO_KEY' -H 'Content-Type: application/json' -d '{"venue":"hyperliquid","asset":"hl-BTC","side":"buy","sizeUsd":100,"markPrice":65000}' 'https://bot.hypo.markets/api/bot/trade'

/api/bot/credentialsKEYcache 0s

HYPO Bot — connect/list/disconnect your OWN venue credential (non-custodial)

Manage the credential the bot uses to place orders on YOUR OWN venue account — the non-custodial key. Secrets are AES-256-GCM encrypted at rest and NEVER returned or logged. POST {venue, kind:'apiKey'|'wallet'|'oauth', secret:{...}} to connect; DELETE {venue} to disconnect; GET to list connected venues (metadata only). 503 when the vault is not configured (HYPO_BOT_VAULT_KEY unset). STRONGLY recommend supplying trade-only / withdraw-disabled keys — even a vault breach can then only trade, never withdraw (HYPO never holds funds or withdrawal authority).

Response shape

{ ok, vaultEnabled?, connected:[{venue, kind, addedAt}] }  (secrets never returned)

Sample curl

curl -X POST -H 'X-API-Key: $HYPO_KEY' -H 'Content-Type: application/json' -d '{"venue":"hyperliquid","kind":"wallet","secret":{"privateKey":"0x..."}}' 'https://bot.hypo.markets/api/bot/credentials'

/api/bot/leaderboardFREEcache 0s

HYPO Bot — public anonymous leaderboard (realized P&L)

Public ranking of all bots by realized P&L (descending). FREE, no auth, no PII — each bot is a stable pseudonymous handle derived from its hashed ledger id; no owner, balance, or credential is ever exposed. The traction surface. ?limit (1-200, default 50).

Query parameters

NameTypeRequiredDescription
limitintegernoMax rows, 1-200, default 50.

Response shape

{ ok, leaderboard:[{handle, realizedPnlUsd, winRate, tradeCount, totalVolumeUsd, openPositions}] }

Sample curl

curl 'https://bot.hypo.markets/api/bot/leaderboard?limit=20'

/api/bot/tapeFREEcache 0s

HYPO Bot — public live-tape SSE (anonymous fills)

Server-Sent Events stream of recent fills across ALL bots, anonymised (pseudonymous handle, no PII). A 'snapshot' frame on connect, then 'fills' frames as new trades land (polls the durable ledger). ': heartbeat' every 25s. FREE, no auth. The live 'show parade'.

Response shape

text/event-stream: data:{type:'snapshot'|'fills', fills:[{t, handle, venue, venueAsset, side, filledUsd, avgPrice}]}; ': connected' + ': heartbeat' comments

Sample curl

curl -N 'https://bot.hypo.markets/api/bot/tape'