> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dune.com/llms.txt
> Use this file to discover all available pages before exploring further.

# hyperliquid.perp_market_details

> Market dimension for Hyperliquid perpetual futures, one row per market with current registry state, margin parameters, and curated classification.

export const PremiumDatasetAccessCard = ({href = "https://dune.com/enterprise#contact-form", note = null}) => <Card title="Gated dataset" icon="lock" href={href}>
    Querying this dataset requires an entitlement on your workspace. See <a href="/data-catalog/overview#access-tiers-public-vs-gated-datasets">access tiers</a>, or contact the Dune team to enable access.
    {note && <><br /><br />{note}</>}
  </Card>;

`hyperliquid.perp_market_details` is the market dimension for the Hyperliquid perp dataset, covering first-party markets (`coin` unprefixed, e.g. `BTC`) and HIP-3 builder-deployed markets (`coin` = `dex:SYMBOL`, e.g. `xyz:TSLA`). Grain: one row per (`perp_dex`, `coin`), current state. `coin` is the join key used by every market-grained table in the dataset (`perp_accounts_daily` is per trader and carries none).

<PremiumDatasetAccessCard />

## Table schema

| Column | Type | Description |
| - | - | - |
| `coin` | `VARCHAR` | Primary key. Venue-native market id: `BTC` first-party, `xyz:TSLA` HIP-3. The join key used by every market-grained table in the dataset |
| `perp_dex` | `VARCHAR` | `hyperliquid` for first-party markets, otherwise the builder DEX code (`xyz`, `flx`, `vntl`, `para`, ...) |
| `market_symbol` | `VARCHAR` | `coin` with the `dex:` prefix stripped. Not unique across dexes — never join on it |
| `asset_id` | `BIGINT` | Numeric asset id used by the action tables. First-party: `asset_index`. HIP-3: `100000 + dex_index * 10000 + asset_index` |
| `asset_index` | `INTEGER` | Per-dex asset index, kept so the `asset_id` arithmetic is reproducible |
| `dex_index` | `INTEGER` | Registry index of the dex; 0 is first-party Hyperliquid |
| `perp_dex_type` | `VARCHAR` | `first_party` or `builder`. The cheap filter for native-only or HIP-3-only, without string-matching `coin` |
| `builder_name` | `VARCHAR` | DEX full name (XYZ, Felix Exchange, Ventuals, ...); `Hyperliquid` on first-party markets |
| `deployer` | `VARBINARY` | Address that deployed the DEX and staked the HYPE. Null for first-party |
| `oracle_updater` | `VARBINARY` | Address permitted to push oracle prices. Often null, first-party included |
| `fee_recipient` | `VARBINARY` | Address receiving the deployer's fee share. Null where the DEX has not set one |
| `size_decimals` | `INTEGER` | Decimal precision of order and fill size for the market (`sz_decimals`) |
| `max_leverage` | `INTEGER` | Top-tier maximum leverage. Lower for a large position when `is_tiered_margin` |
| `margin_table_id` | `INTEGER` | Pointer into the venue's margin tables, namespaced per dex — the same id means different tiers on different dexes. 1-50 is the implicit single-tier ladder, 51+ deployer-defined |
| `margin_tiers` | `VARCHAR` | Resolved margin table as JSON, ordered by notional bound: `[{"lowerBound": ..., "maxLeverage": ...}]` |
| `is_tiered_margin` | `BOOLEAN` | True when `margin_tiers` has more than one tier, i.e. the leverage cap depends on position size |
| `margin_mode` | `VARCHAR` | Deployer-set regime: `cross` (traders may still pick isolated), `noCross`, `strictIsolated`. Source nulls mean `cross` |
| `only_isolated` | `BOOLEAN` | True iff `margin_mode <> 'cross'` |
| `funding_multiplier` | `DOUBLE` | Per-coin funding multiplier (0.0 = funding disabled). HIP-3 only; null for first-party and for a HIP-3 coin its DEX has not mapped |
| `open_interest_cap_usd` | `DOUBLE` | Per-coin streaming open-interest cap, USD. HIP-3 only, same null rule |
| `growth_mode` | `VARCHAR` | HIP-3 growth-mode state (`enabled` or null), which caps the deployer fee share at 100% instead of 300% |
| `growth_mode_changed_at` | `TIMESTAMP(3) WITH TIME ZONE` | Last growth-mode change. Null when the source omits it and when it carries the source's 1970-01-01 never-changed sentinel |
| `is_delisted` | `BOOLEAN` | Latest polled delisting flag. Delisted markets keep their row |
| `is_halted` | `BOOLEAN` | Latest decoded `haltTrading` state. `false` means "no decoded halt action", which is weaker than "not halted" |
| `listed_at` | `TIMESTAMP(3) WITH TIME ZONE` | Block time of the market's `registerAsset` / `registerAsset2`. Null on most markets — always on first-party ones, where listing is not a `perpDeploy` action — so null means "not in the decoded action log", not "never registered" |
| `delisted_at` | `TIMESTAMP(3) WITH TIME ZONE` | First poll observing the market's current delisted spell; null while listed. Poll resolution, floored at 2026-06-29 |
| `market_category` | `VARCHAR` | Coarse category of the underlying family, maintained for every listing |
| `asset_class` | `VARCHAR` | Top-level class in the shared RWA vocabulary. Null on every crypto market |
| `asset_type` | `VARCHAR` | Finer classification within `asset_class`, same vocabulary. Null exactly where `asset_class` is null |
| `underlying_ticker` | `VARCHAR` | Underlying's symbol on its primary exchange, local codes included (`0700` = Tencent on HKEX). Null for indices, commodities, fx, pre-IPO names and crypto |
| `description` | `VARCHAR` | Curated description of the reference, with the contract unit where the DEX spec states one. Null on plain crypto tickers |
| `metadata_last_updated` | `DATE` | Date a curated cell on this row last changed. Says nothing about market activity |
| `_updated_at` | `TIMESTAMP(3) WITH TIME ZONE` | Newest poller write among this market's registry row, its dex row and its margin table. Neither a poll clock nor a change clock |

## A live view, current state only

The table is a VIEW over the deduped registry snapshots, so a newly listed market appears with no build and no refresh anywhere in the dataset — on the next registry write covering its dex, measured at a median of 32 minutes after the on-chain registration and 18.2 hours worst case. Coverage is every first-party and HIP-3 builder-dex market; Hyperliquid spot and HIP-4 outcome markets are out of scope.

There is no `valid_from` / `valid_to`: this is not an SCD. The upstream registry only has change history from 2026-06-29, and intervals would break the one-row-per-market contract that every join here assumes.

## Joins from fact tables drop nothing

Delisted markets stay tombstoned in the registry rather than disappearing, so every coin that has traded since the 2025-07-27 fills floor has a row here — verified by an unbounded all-history anti-join over every coin that had traded. An inner join from a fact table is therefore safe. The reverse is not a market list: registered-but-never-traded markets are here too.

## max\_leverage is not always the cap that applies

`margin_table_id` 1-50 is the implicit single-tier ladder where the id *is* the leverage value; there `margin_tiers` is synthesised from `max_leverage` and the two agree. Ids 51+ are deployer-defined and the only genuinely tiered markets. On those, `max_leverage` is a top-tier cap that a large enough position does not get, and the applicable cap is the last tier whose `lowerBound` the notional clears.

```sql theme={null}
-- Leverage cap actually available at $5M notional on tiered markets
SELECT
  d.coin,
  d.max_leverage AS top_tier_leverage,
  MIN(CAST(json_extract_scalar(t.tier, '$.maxLeverage') AS INTEGER)) AS leverage_at_5m
FROM hyperliquid.perp_market_details AS d
CROSS JOIN UNNEST(CAST(json_parse(d.margin_tiers) AS ARRAY(JSON))) AS t(tier)
WHERE d.is_tiered_margin
  AND CAST(json_extract_scalar(t.tier, '$.lowerBound') AS DOUBLE) <= 5e6
GROUP BY 1, 2
ORDER BY 3
```

Where a trader never set leverage, Hyperliquid's account default is `least(20, max_leverage)`.

## Classification is here and nowhere else

`market_category`, `asset_class`, `asset_type`, `underlying_ticker` and `description` are LEFT JOINed from `hyperliquid.perp_market_metadata` and stored on no fact table, so a reclassification rebuilds only that \~500-row table.

| `market_category` | Covers |
| - | - |
| `crypto` | Crypto-native references, single tokens and crypto aggregates alike (dominance, market-cap and NFT indices). Every first-party market |
| `equities` | Single-name equities, listed or pre-IPO, and equity funds and ETFs |
| `index` | A real-world index level: broad equity, sector or thematic, volatility |
| `commodities` | Metals, energy, agriculture |
| `fx` | Currency pairs and currency indices |
| `other` | Rates (`para:10Y`, `km:USBOND`) and GPU-compute prices (`H100`) |

`asset_class` takes `credit`, `fixed_income`, `cash_equivalent`, `equities`, `multi_asset`, `commodities`, `real_estate`, `fx` or `other` — the vocabulary the tokenized-RWA models use. It is null on every crypto market and on the compute markets, where no value in that vocabulary applies. `asset_type` names the exposure rather than a wrapper: a single-name perp is `equities_synthetic` whether the name is listed or pre-IPO, an index perp is `equities_index`, and a perp on an ETF is `equities_exchange_traded_funds` because there the reference genuinely is a fund.

```sql theme={null}
-- Traded volume by asset class, last 7 days
SELECT
  d.asset_class,
  d.asset_type,
  COUNT(DISTINCT d.coin) AS markets,
  SUM(t.notional_usd) AS volume_usd
FROM hyperliquid.perp_trades AS t
JOIN hyperliquid.perp_market_details AS d
  ON d.coin = t.coin
WHERE t.block_date >= current_date - INTERVAL '7' day
  AND t.is_taker
  AND (d.market_category IS NULL OR d.market_category <> 'crypto')
GROUP BY 1, 2
ORDER BY 4 DESC
```

`perp_trades` holds both legs of every match, hence the `is_taker` filter; `hyperliquid.perp_market_metrics_daily` is already taker-side if you only need the volume. The `IS NULL` arm matters: `market_category`'s `not_null` test runs at warning severity so a newly listed market keeps reporting while it is unclassified, and a bare `<> 'crypto'` would silently drop it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.