Skip to main content
Live in production, still flag-gated. Perpetuals are gated by PERPETUALS_PUBLIC_API_ENABLED, enabled in production and staging today; a deployment with the flag off returns 404 for every perpetual route. Read Overview before writing code.
How a perpetual instrument is identified, which asset plays which role, and what happens when you name an instrument that does not exist. Read this before you key any storage or join any two perpetual feeds. A symbol such as BTC, BTC-PERP, or xyz:BTC is not a primary key. It is a display label that can change. Identity is the canonical instrument id plus the venue, environment, and integration that scope it.
Beta: The full public InstrumentRef is carried by every v2 perpetual book. Private account and execution identities remain outside the public market-data beta.

Instrument reference

Every public and private record carries an instrument reference. These are the field names of kairos.v2.InstrumentRef, carried on every v2 book snapshot: An integration and environment are part of identity. Test and production data, or two independently configured venue connections, must never collide.

What the gateway refuses

The public gateway drops a snapshot whose:
  • instrument_type is not INSTRUMENT_TYPE_PERPETUAL
  • native_quantity_unit is neither BASE_ASSET nor CONTRACTS
  • venue_instrument_id, display_symbol, base_asset_id, quote_asset_id, collateral_asset_id, environment, or integration_id is empty
settlement_asset_id is the one asset role the schema marks optional and the gateway does not require.
The rejection is silent. An invalid message is dropped before fan-out. There is no client error frame. From the consumer’s side this is indistinguishable from an instrument that simply has no updates.
environment is per venue and is not uniform. Hyperliquid and Polymarket Perps report mainnet; Kalshi Margin reports production. Compare it exactly rather than assuming one spelling.

Asset roles are not interchangeable

Base, quote, collateral, and settlement assets can differ. A price may be quoted in one asset while collateral and realized PnL use another. Use the named role. Do not assume every market is base/USDC with USDC settlement. Market Data API snapshots expose these roles as base_asset_id, quote_asset_id, collateral_asset_id, and settlement_asset_id. All four are required there.

Extra fields from the instruments catalog

GET /perpetuals/instruments additionally carries price_increment, size_increment, contract_multiplier, max_leverage, isolated_only, and a status of active, inactive, closed, delisted, or unknown.
All five of those are nullable. A venue that does not publish a tick size, lot size, or multiplier leaves the field absent. A multiplier is never derived from observed prices or quantities — if it is absent, you do not have one.
Each instrument also carries a venue-discriminated metadata object — keyed by kind, which must equal the instrument’s venue — holding facts that have no cross-venue meaning:
Kalshi’s leverage is a sample, not a rule. It is labelled semantics: "sampled_estimate" because it is probed at a sample notional rather than published by the venue. Do not treat it as an enforceable venue limit.

Hyperliquid instrument ids

Hyperliquid’s standard main-dex perpetuals have a fixed canonical id:
The quote asset defaults to USDT, with per-symbol exceptions — currently HYPE and PURR, which quote in USDC. Collateral and settlement are USDC for all of them, so quote, collateral, and settlement roles must stay separate. This is one identifier used everywhere: the streamed book, the funding observations, the trade facts, and the Market Data API snapshot all key on it, which is what makes them joinable. The rule lives in a single shared contract file and is code-generated into every consumer rather than hand-copied — a drifted copy would change an instrument id and silently orphan every fact for it.

Venue coin names are case-sensitive; canonical ids are not

You cannot recover a venue coin from a canonical id by string manipulation. kPEPE is the venue’s spelling; KPEPE and kpepe are not coins the venue accepts. Because the canonical id lowercases the symbol, kPEPE and KPEPE both collapse to hl-mainnet-kpepe-usdt — and only one of them exists.
If you need the venue coin, resolve it from the venue’s own asset universe.
A wrong-cased coin fails invisibly. Subscribing to Hyperliquid’s WebSocket with one closes the socket with no error and no close frame, which is indistinguishable from a network drop. Handle it explicitly.

Native quantity

native_quantity_unit determines what the venue’s quantity means: The canonical model defines all three; the v2 gateway accepts only BASE_ASSET and CONTRACTS on a book snapshot, as listed above. Normalized base quantity and quote notional can be published alongside native quantity only when the conversion inputs and rules are known.

Lifecycle

Perpetuals do not have a scheduled expiry, but they still have lifecycle state. An instrument can be:
  • listed but not yet active
  • active
  • halted
  • close-only or reduce-only
  • delisted
Lifecycle state is time-varying. Delisting does not permit identifier reuse — historical records continue to reference the original instrument.

Alias resolution

Venue symbols and aliases are resolved at ingestion. The resolution result must include the venue, environment, and effective period. Silent alias fallback is unsafe: if a symbol is unknown or ambiguous, ingestion fails until metadata establishes the identity. The streamer implements exactly that for Hyperliquid. A canonical id is resolved back to a venue coin from the venue’s own asset universe, cached for five minutes with a thirty-second floor between refetches after a miss. In both cases the adapter refuses to subscribe rather than guessing a symbol.

What an unknown instrument looks like

Each surface fails differently. This table is worth memorizing before you debug a silent stream:
On the WebSocket, “acknowledged” does not mean “exists”. A misspelled instrument id produces a healthy-looking subscription that is silent forever. If you see no frames, verify the id against GET /perpetuals/instruments before suspecting the network.

Consumer invariants

  • Join on stable IDs, not display symbols.
  • Partition venue-native IDs by provider and environment.
  • Treat asset roles and quantity units as required.
  • Do not treat delisted instruments as expired prediction markets.
  • Keep venue-native metadata for audit and replay.
Next: Exact values and time.