hyperliquid.perp_oracle_prices is the price-reference table for the Hyperliquid perpetual futures venue. Grain: one row per (coin, block_minute) on a fixed one-minute grid, carrying the last update published inside the minute rather than an average. It covers both first-party perps (coin = BTC) and HIP-3 builder-deployed markets (coin = dex:SYMBOL, e.g. xyz:TSLA), and price_source says which family a row belongs to and therefore which price columns are populated.
Table schema
price_source decides which columns are populated
The two families come from different upstream mechanisms, which is why coverage is asymmetric. First-party rows come from Hyperliquid’s own asset-contexts series, which carries no HIP-3 rows at all and is re-pulled in batches that trail the present by weeks; every HIP-3 row is reconstructed from deployer
setOracle actions, which land close to real time. Publishing is also not universal among builder dexes — nine of the ten had published prices as of 2026-08-21, and markets on the tenth have no rows here. So the two families do not reach the same latest minute: check MAX(block_minute) per price_source before comparing a recent window across them.
The split is exact on the coin prefix: asset_ctxs coins are never dex-prefixed and set_oracle coins always are, so filtering on price_source and filtering on the prefix select the same rows.
No carry-forward
A minute with no published update produces no row, so gaps are genuine absences of published prices rather than nulls to interpolate. Take the last row at or before your cutoff instead of matching a minute exactly, and boundblock_month alongside block_minute so the query prunes partitions:
Mark price means different things per family
On a first-party row,mark_price is Hyperliquid’s own published mark: a blend of the oracle, the drift of its book away from the oracle, its own bid/ask/last, and other venues’ perp mids. On a HIP-3 row it is the mark the dex deployer nominates. Some deployers derive it independently and some simply republish the oracle they just set — one dex has done both in different periods.
That carries straight into mark_oracle_spread_bps: a deployer echoing its oracle shows exactly zero, regardless of what the book did. Read mark_price before comparing spreads across dexes, and do not read a small spread on a HIP-3 market as a tight market. mark_price is never filled in from oracle_price where it is missing, so coalesce yourself if that assumption suits your analysis.
Premium and the impact prices
impact_bid_price and impact_ask_price are the volume-weighted fill prices of a hypothetical market sell and market buy of the market’s impact notional — 20,000 USDC on BTC and ETH, 6,000 USDC on every other market — against the resting book. The clip is deliberately small: large enough to average across several price levels so a token-sized quote at the top of the book cannot move it, small enough to still describe the price ordinary flow gets. It is not a slippage estimate for a large order.
premium is derived from that pair rather than from top-of-book, so it reflects where a real clip would trade. Its sign drives funding: an impact ask below the oracle pushes funding negative, an impact bid above it pushes funding positive.
Market classification
Nothing here classifies the market. Joinperp_market_details on coin for asset class, asset type, underlying ticker and leverage caps.