Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Integration & Development12 min read

Hyperliquid clearinghouseState: Reading Margin and Liquidation Risk

Learn to read Hyperliquid clearinghouseState over the info API, distinguish cross from isolated margin, and compute a liquidation distance you can act on.

TL;DR

Hyperliquid's clearinghouseState info request returns an account's margin summary, per-asset positions, and a cross-maintenance-margin figure. The info endpoint is a read-only POST with no authentication, so a monitoring process never needs a private key. Cross-margin accounts share collateral across positions, while isolated positions are margined on their own, so the account-level summary cannot be applied to a single isolated position. The liquidation price is derived from maintenance-margin requirements and leverage rather than returned directly, so distance should be computed from the maintenance-margin buffer. This article shows a runnable Node.js monitor, a results table to fill in, and the failure modes that make a stale or misread response look healthier than it is.

The clearinghouseState info request and its documented response shape

Hyperliquid exposes account state through the info API, a read-only surface that accepts a POST to the info path with a JSON body naming the request type. The clearinghouseState request takes a user address and returns the account's margin summary, its per-asset positions, and a cross-maintenance-margin field. The Hyperliquid documentation for the perpetuals info endpoint describes the response shape, including per-asset position entries with size, entry price, and position value, and a margin summary carrying account value, total margin used, and total notional position.

Treat exact field names and any additional fields as documented but subject to change across API versions. The correct habit is to log the raw response once, confirm the field names against the current documentation at Hyperliquid documentation: perpetuals info endpoint, and only then write code that reads them. Hard-coding a field name you saw in a blog post is how a monitor silently starts returning undefined and reports a healthy account.

The same account can be queried through the Hyperliquid RPC endpoints (RPC Assistant) if you prefer a managed path, but the request body and response shape are the protocol's, not the provider's. Provider-specific behavior such as caching, rate limits, and retry semantics is documented per provider and varies, so verify against the endpoint you actually call.

  • clearinghouseState is a read-only info request; it does not place or cancel orders.
  • The response carries an account-level margin summary plus per-asset position entries.
  • Field names are documented but should be verified against the current response before hard-coding.

Why the info API and the exchange API are different surfaces

The info endpoint is a read-only POST with no authentication. Order placement, cancellation, and any state-changing action are signed against the exchange endpoint using a private key. This separation is the single most important safety property of building liquidation alerts this way: a monitoring process that only reads clearinghouseState never needs a private key, so a compromised monitor cannot move funds.

That property is worth stating plainly because the alternative pattern, embedding a signing key in a dashboard or alerting service, turns a read-only risk tool into a custody risk. If your monitor needs to act on a breach, keep the signing key in a separate process with its own authorization boundary, and let the monitor emit an event rather than a transaction.

The API service page describes how OnFinality exposes these surfaces, and the Hyperliquid API error handling and order rejections article covers what happens on the signed side when a request is rejected. For monitoring, the read-only path is the one that matters.

  • Info endpoint: read-only POST, no authentication, no private key.
  • Exchange endpoint: signed requests, private key required, state-changing.
  • Keep the signing key out of any process that only needs to read account state.

Cross margin, isolated margin, and why the distinction changes every number

In a cross-margin account, collateral is shared across positions, so one position's health is a function of the whole account. In an isolated position, margin is assigned to that position alone, so its health depends only on its own collateral and size. The Hyperliquid margining documentation at Hyperliquid documentation: margining describes both modes and the maintenance-margin requirements that apply.

This distinction is the most common source of a wrong risk number. A caller that reads the account-level margin summary and applies it to a single isolated position computes a meaningless liquidation distance, because the account summary includes collateral that the isolated position cannot use. Before computing anything, determine which mode the position is in and which summary applies to it.

The account-mode vocabulary that readers search for next, portfolio margin, cross versus isolated, collateral assets, unified account, and hedge mode, all describe this same fork. If you are unsure which mode an account uses, the safest approach is to read the position entry and the account summary separately, label them in your output, and never blend them into one number.

  • Cross margin: collateral shared, position health depends on the whole account.
  • Isolated margin: collateral assigned per position, health depends on that position alone.
  • Never apply the account-level summary to an isolated position.

Field-by-field reading order that avoids the classic mistakes

Read the account-level fields first: account value and total margin used give a margin ratio, and the cross maintenance margin gives the buffer before liquidation. Then read the per-asset position entries, which describe the position rather than the account. Mixing the two is the most common source of a wrong risk number, because a position's notional value is not the account's total notional position.

A useful discipline is to print the account summary and the position entries in separate blocks, with explicit labels, so a reader of the output can see which number came from which level. When you compute a distance, state the formula in the output next to the result, so the number can be audited rather than trusted.

The Hyperliquid funding rate mechanics article explains how funding accrual moves account value between polls, which is why the account-level fields can drift even when no trade has occurred.

  • Account level: account value, total margin used, cross maintenance margin.
  • Position level: size, entry price, position value, per asset.
  • Label each block in output so the source of every number is visible.

Why liquidation price is derived rather than returned

The account endpoint does not promise a liquidation price. Liquidation price is a derived quantity: it depends on maintenance-margin requirements, leverage, position size, and the collateral available to that position or account. Because those inputs change with funding, with new positions, and with margin mode, a returned liquidation price would be a snapshot that goes stale immediately.

The practical consequence is that you should compute distance from the maintenance-margin buffer rather than trying to read a liquidation price. The buffer is the quantity the venue itself uses to decide when to act, so a distance derived from it is closer to the mechanism than a price derived from a formula you guessed.

If you want a price-like number for a dashboard, derive it and label it as an estimate with the formula shown. Do not present it as a venue-provided value.

  • Liquidation price is derived from maintenance margin, leverage, size, and collateral.
  • The maintenance-margin buffer is the quantity the venue acts on.
  • Any price-like output should be labelled as an estimate with its formula.

A runnable Node.js monitor for clearinghouseState

The monitor below POSTs the documented info request body for clearinghouseState, reads the response, and prints per-asset size and notional alongside the account's maintenance-margin buffer. It then prints a clearly-labelled computed distance to liquidation with the formula shown, so the reader can audit it. Replace the endpoint and address with your own.

The code reads field names defensively and prints the raw response once when a field is missing, which is the fastest way to discover that an API version has renamed something. It does not sign anything and does not need a private key.

// monitor.js — read-only Hyperliquid clearinghouseState monitor
// Run: node monitor.js
// No private key required. Info endpoint is read-only.

const ENDPOINT = process.env.HL_INFO_URL || 'https://api.hyperliquid.xyz/info';
const USER = process.env.HL_USER || '0xYourAccountAddress';

async function fetchClearinghouseState(user) {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ type: 'clearinghouseState', user })
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

function num(v) {
  const n = Number(v);
  return Number.isFinite(n) ? n : null;
}

function printState(state) {
  const summary = state.marginSummary || {};
  const accountValue = num(summary.accountValue);
  const totalMarginUsed = num(summary.totalMarginUsed);
  const totalNtlPos = num(summary.totalNtlPos);
  const crossMaint = num(state.crossMaintenanceMargin);

  console.log('--- ACCOUNT SUMMARY ---');
  console.log('accountValue        :', accountValue);
  console.log('totalMarginUsed     :', totalMarginUsed);
  console.log('totalNtlPos         :', totalNtlPos);
  console.log('crossMaintenanceMargin:', crossMaint);

  if (accountValue !== null && totalMarginUsed !== null && totalMarginUsed > 0) {
    console.log('marginRatio         :', (totalMarginUsed / accountValue).toFixed(4));
  }

  console.log('--- POSITIONS ---');
  for (const p of state.assetPositions || []) {
    const pos = p.position || {};
    const szi = num(pos.szi);
    const entry = num(pos.entryPx);
    const posValue = num(pos.positionValue);
    console.log({
      coin: pos.coin,
      szi,
      entryPx: entry,
      positionValue: posValue
    });
  }

  // Distance to liquidation, derived from the maintenance-margin buffer.
  // Formula: distance = (accountValue - crossMaintenanceMargin) / accountValue
  // This is an estimate, not a venue-provided liquidation price.
  if (accountValue !== null && crossMaint !== null && accountValue > 0) {
    const buffer = accountValue - crossMaint;
    const distance = buffer / accountValue;
    console.log('--- COMPUTED DISTANCE (estimate) ---');
    console.log('formula: (accountValue - crossMaintenanceMargin) / accountValue');
    console.log('buffer  :', buffer.toFixed(2));
    console.log('distance:', distance.toFixed(4));
  } else {
    console.log('Missing fields; dumping raw response for inspection:');
    console.log(JSON.stringify(state, null, 2));
  }
}

(async () => {
  try {
    const state = await fetchClearinghouseState(USER);
    printState(state);
  } catch (err) {
    console.error('monitor failed:', err.message);
    process.exitCode = 1;
  }
})();

A results table to fill in against your own account

Run the monitor against your own account at several points in time and record the account value, total margin used, maintenance margin, and the computed distance. This converts a vague 'how close am I' question into a trend you can threshold. The table below is a template; the values are yours to measure, not ours to assert.

Because funding accrual moves account value between polls, a single reading is not a trend. Take readings at a fixed interval, note any trades or transfers between them, and look at the direction of the distance column rather than its absolute value.

  • Results Table columns: timestamp, account value, total margin used, cross maintenance margin, computed distance, notes.
  • Take readings at a fixed interval so the trend is comparable.
  • Record trades and transfers in the notes column so a step change is explainable.

Failure modes: stale caches, indexing paths, funding drift, and alerting on the wrong field

A stale cached response makes the account look healthier than it is. If your provider caches info responses, a monitor that polls faster than the cache refreshes will see the same state repeatedly and miss a move. Verify cache behavior against your provider's documentation, and consider a cache-busting parameter or a second endpoint for confirmation.

A position can exist on one venue or asset indexing path and not another, so a monitor that reads only one path can report a flat account while a position is open elsewhere. Funding accrual moves account value between polls even with no trade, which is why a distance computed once and stored is not a distance. And alerting on account value alone is a trap: the maintenance-margin buffer is the quantity that actually predicts liquidation, so an account value that looks comfortable can sit on a thin buffer.

The Hyperliquid historical market data and Hyperliquid oracle price and auction info articles cover adjacent data surfaces that can help you cross-check what the account endpoint reports.

  • Stale cache: same state returned repeatedly, missed moves.
  • Indexing path: a position visible on one path and not another.
  • Funding drift: account value changes with no trade.
  • Wrong field: alerting on account value instead of the maintenance-margin buffer.

Troubleshooting a monitor that reports the wrong risk number

When the number looks wrong, first dump the raw response and compare field names against the current documentation. A renamed field returns undefined, and arithmetic on undefined produces NaN, which many dashboards render as zero. Second, confirm the margin mode: if the position is isolated, the account-level summary does not apply, and the fix is to read the position's own collateral rather than the account's.

Third, check the units. Some fields are strings, some are numbers, and some are scaled. Parse explicitly and log the parsed value next to the raw value. Fourth, check the timestamp of the response against your poll time; if the provider caches, the response may be older than you think.

If you are calling through a managed endpoint, the RPC pricing page describes plan-level behavior, and the OnFinality Learn hub collects the related Hyperliquid articles in one place.

  • Dump raw response and verify field names before trusting arithmetic.
  • Confirm margin mode before applying the account summary.
  • Parse and log units explicitly; strings and scaled integers are common.
  • Compare response timestamp against poll time to detect caching.

Limitations and tradeoffs of an observation-only risk tool

This is an observation tool. It reads state and computes a number; it does not predict liquidation timing, and it cannot see a position being closed by the venue's own engine between polls. A monitor that polls every minute has a one-minute blind spot, and no amount of formula precision removes that.

The tradeoff is between polling frequency and cost. Faster polling narrows the blind spot but increases request volume and the chance of hitting provider rate limits, which vary by provider and are documented per plan. A second tradeoff is between simplicity and completeness: a monitor that reads only clearinghouseState is easy to reason about but blind to positions on other indexing paths, while a monitor that reads everything is harder to audit.

State these limits in the tool itself. A distance number presented without its formula, its timestamp, and its blind spot invites overconfidence.

  • Observation only: no prediction of liquidation timing.
  • Blind spot between polls; frequency trades off against cost and rate limits.
  • Simplicity versus completeness: one path is auditable but partial.

Next steps: from a single reading to a thresholded trend

Start by running the monitor once and confirming the field names against the current response. Then run it on a fixed interval, fill in the results table, and set a threshold on the distance column rather than on account value. When the distance crosses the threshold, emit an event; keep any signing key in a separate process.

To go further, add a second data source for cross-checking, review the Hyperliquid funding rate mechanics article for how funding moves account value, and use the Hyperliquid RPC endpoints (RPC Assistant) reference to confirm the endpoint you call. The OnFinality Learn hub collects the full Hyperliquid set, and the API service page describes how to reach these surfaces through OnFinality.

  • Confirm field names once, then automate on a fixed interval.
  • Threshold the computed distance, not account value.
  • Keep signing keys out of the monitoring process.
  • Cross-check with a second data source before acting.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started