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

Hyperliquid Vault Equity over the Info API

Read Hyperliquid vault state and account vault positions over the info API, reconcile shares against total value, and derive share-price performance instead of raw equity.

TL;DR

A Hyperliquid vault is a pooled account: depositors receive shares, and their economic position is shares multiplied by share price, not a stored dollar balance. The info API exposes this through two distinct read paths: an account-scoped read that returns a user's share count and attributable equity, and a vault-scoped read that returns the vault's aggregate state including total value and depositor set. Because deposits, withdrawals, and trading PnL all move both total value and outstanding shares, a performance figure computed from raw equity alone conflates cash flows with returns; the only measure that isolates manager performance is share-price change. This article shows how to read both paths, reconcile shares against total shares, derive value per share, snapshot it over time, and separate the failure classes that produce empty results, missing rows, or internally inconsistent responses.

Vault Mechanics and the Share Accounting Model

A Hyperliquid vault is a pooled account that other users deposit into in exchange for shares. The depositor's economic position is shares times share price rather than a stored dollar balance, so the account-side read returns a share count and an equity figure that must be reconciled against the vault's own totals rather than treated as independent numbers. The Hyperliquid vaults Hyperliquid vault documentation describes this share model and the depositor accounting that follows from it.

This matters because the naive read of an account's vault row looks like a balance but is actually a derived quantity. If you treat the returned equity as a stored value and also sum it with perp or spot equity, you double-count collateral. The correct mental model is that the vault holds the collateral, and the depositor holds a claim on a fraction of it.

  • Vault = pooled account; depositor = share holder.
  • Depositor equity = shares × share price, not a stored balance.
  • Vault total value and outstanding shares both move with deposits, withdrawals, and trading PnL.
  • Field names and additional fields are documented / varies by API version; verify against the live response.

Two Read Paths: Account-Scoped vs Vault-Scoped

The info endpoint exposes two distinct read paths that answer different questions. The account-scoped read returns the caller's or a watched address's positions in vaults, including that address's share count and the equity attributable to it. The vault-scoped read returns the vault's aggregate state, including total value and the depositor set. A caller that wants 'how is this vault doing' and a caller that wants 'what is this user's exposure' must not use the same request.

The Hyperliquid info endpoint Hyperliquid info endpoint documentation lists the request types and their parameters. Treat the exact request names and response fields as documented / varies by API version, and confirm them against the live response before hard-coding. The Hyperliquid RPC endpoints (RPC Assistant) page is a useful starting point for endpoint selection, and the Hyperliquid clearinghouseState: margin and liquidation article covers the perp-side read that is often confused with vault equity.

  • Account-scoped read: user's vault positions, share count, attributable equity.
  • Vault-scoped read: vault aggregate state, total value, depositor set.
  • Do not use one request to answer both questions.
  • Confirm request names and fields against the live response.

Vault Equity vs Spot and Perp Account Equity

clearinghouseState reports perp account value and margin, spot balances are a separate surface, and a vault position is a third thing again. Summing them without deduplicating collateral double-counts and produces a wrong total, which is the single most common error in vault dashboards. The vault's collateral is already reflected in the vault's total value; the depositor's claim is a fraction of that, not an additional balance.

If you need a consolidated view, decide explicitly whether you are reporting the vault's total value, the depositor's attributable equity, or both side by side. Reporting both is fine as long as you label them and never add them. The Hyperliquid funding rate mechanics and Hyperliquid oracle price and builder auction info articles cover adjacent reads that are also easy to conflate with vault state.

  • clearinghouseState = perp account value and margin.
  • Spot balances = separate surface.
  • Vault position = third surface; do not sum without deduplication.
  • Label vault total value and depositor attributable equity separately.

Deriving Share Price and Isolating Manager Performance

The vault's value per share is total vault value divided by outstanding shares. Because both quantities move with deposits, withdrawals, and trading PnL, a performance figure computed from raw equity alone conflates deposits with returns. The reader must compute share-price change rather than equity change, which is the only measure that isolates manager performance from cash flows.

A deposit increases both total value and outstanding shares, so share price is unchanged at the moment of deposit. A trading gain increases total value without changing shares, so share price rises. That is why share-price change is the meaningful performance signal and equity change is not. The Hyperliquid vaults Hyperliquid vault documentation describes the share model that makes this true.

  • Share price = total vault value / outstanding shares.
  • Deposit: total value and shares both rise; share price unchanged.
  • Trading gain: total value rises, shares unchanged; share price rises.
  • Performance = share-price change, not equity change.

Reading Vault Aggregate State and Account Position in Node.js

The script below reads a vault's aggregate state and an account's vault position over the info endpoint, reconciles share count against total shares, derives value per share, snapshots it, and prints a table. It uses a single POST per request and keeps the two reads separate so the reconciliation is explicit. Replace the endpoint and request names with the values documented for your API version.

Because the info endpoint answers about current state, the script's snapshot store is the historian. Run it on a schedule and append each reading to a file or database; a single reading is not a performance measurement.

// Node.js 18+ (global fetch). Replace endpoint and request names with your API version.
const ENDPOINT = process.env.HL_INFO_ENDPOINT || 'https://api.hyperliquid.xyz/info';
const VAULT = process.env.HL_VAULT_ADDRESS || '0xVaultAddress';
const ACCOUNT = process.env.HL_ACCOUNT_ADDRESS || '0xAccountAddress';

async function info(body) {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(body)
  });
  if (!res.ok) throw new Error('HTTP ' + res.status + ' ' + (await res.text()));
  return res.json();
}

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

async function main() {
  // Vault-scoped read: aggregate state. Request name varies by API version.
  const vaultState = await info({ type: 'vaultDetails', vaultAddress: VAULT });
  // Account-scoped read: this address's vault positions.
  const accountState = await info({ type: 'userVaultEquities', user: ACCOUNT });

  const totalValue = num(vaultState?.totalValue ?? vaultState?.value);
  const totalShares = num(vaultState?.totalShares ?? vaultState?.shares);
  const sharePrice = (totalValue !== null && totalShares) ? totalValue / totalShares : null;

  const rows = Array.isArray(accountState) ? accountState : (accountState?.vaultEquities || []);
  const row = rows.find(r => (r.vaultAddress || r.vault || '').toLowerCase() === VAULT.toLowerCase());
  const accountShares = row ? num(row.shares ?? row.vaultShares) : null;
  const accountEquity = row ? num(row.equity ?? row.vaultEquity) : null;

  const reconciledEquity = (accountShares !== null && sharePrice !== null)
    ? accountShares * sharePrice : null;

  const snapshot = {
    ts: new Date().toISOString(),
    vault: VAULT,
    totalValue, totalShares, sharePrice,
    accountShares, accountEquity, reconciledEquity
  };

  console.log('vault | totalValue | totalShares | sharePrice | accountShares | accountEquity | reconciledEquity');
  console.log([
    snapshot.vault, snapshot.totalValue, snapshot.totalShares,
    snapshot.sharePrice, snapshot.accountShares,
    snapshot.accountEquity, snapshot.reconciledEquity
  ].join(' | '));

  // Append to your own snapshot store; this is the historian.
  const fs = require('fs');
  fs.appendFileSync('vault-snapshots.ndjson', JSON.stringify(snapshot) + '\n');
}

main().catch(e => { console.error(e); process.exit(1); });

Reconciling Share Count Against Total Shares

The reconciliation step is where most dashboards go wrong. The account-scoped read returns a share count and an equity figure; the vault-scoped read returns total value and total shares. If accountShares × sharePrice does not approximately equal accountEquity, either the two reads were taken across a state transition or the field names differ from the documentation. Treat a mismatch as a signal to re-read, not as a number to average.

Because the info endpoint answers about current state, a single snapshot should be taken as close to atomically as the API allows. If your client can issue the two reads back to back without other work in between, do so; if not, record the timestamps and discard snapshots where the gap is large enough to matter for your use case.

  • accountShares × sharePrice should approximately equal accountEquity.
  • Mismatch = re-read, not average.
  • Take both reads as close to atomically as the API allows.
  • Record timestamps and discard snapshots with large gaps.

Building a Time Series and Measuring Performance

A single share-price reading is not a performance measurement. The reader must sample and store readings, and because the info endpoint answers about current state, the reader's own snapshot store is the historian. The measurement method is reproducible: sample at a fixed cadence, store each snapshot, and compute share-price change over the window.

The table below is a template to fill with your own endpoint's results. Do not compare your numbers to anyone else's; derived performance depends on your sampling cadence and is not comparable across implementations.

  • Sample at a fixed cadence (for example, every 5 minutes).
  • Store each snapshot with a timestamp.
  • Compute share-price change over the window.
  • Report the cadence alongside the result.
Results Table (fill with your own endpoint's readings)

| Timestamp (UTC) | Vault | Total Value | Total Shares | Share Price | Account Shares | Account Equity | Reconciled Equity |
|-----------------|-------|-------------|--------------|-------------|----------------|----------------|-------------------|
|                 |       |             |              |             |                |                |                   |
|                 |       |             |              |             |                |                |                   |
|                 |       |             |              |             |                |                |                   |

Derived performance over the window:
  sharePriceChange = (lastSharePrice - firstSharePrice) / firstSharePrice
  cadence = <your sampling interval>
  note = not comparable across implementations

Failure Classes and Troubleshooting

Separate the failure classes before debugging. A vault identifier that does not exist returns an empty result rather than an error. An account with no position in a vault returns a missing row rather than a zero. An API version whose field names differ from the documentation returns a response that parses but yields nulls. A response that is internally inconsistent was read across two calls during a state transition, which is why a single snapshot should be taken as close to atomically as the API allows.

For order-level failures, the Hyperliquid API error handling and order rejections article covers the rejection surface. For endpoint selection and connectivity, see Hyperliquid RPC endpoints (RPC Assistant) and the Hyperliquid network page.

  • Empty result: vault identifier does not exist.
  • Missing row: account has no position in the vault.
  • Nulls after parse: field names differ from documentation.
  • Inconsistent response: reads taken across a state transition.
  • Re-read rather than average when reconciliation fails.

Limitations and Tradeoffs

Nothing here is investment advice. Derived performance depends on the reader's own sampling cadence and therefore is not comparable across implementations. Vault fees and manager share terms must be read from the vault's own configuration rather than inferred from equity or share-price movement. Field availability is provider- and version-dependent, so the request names and response fields shown here are documented / varies by API version and must be verified against the live response.

The info endpoint answers about current state, so any historical view is the reader's own construction. That construction is only as good as its cadence and its handling of gaps. If you need a consolidated portfolio view, decide explicitly how you will avoid double-counting collateral across perp, spot, and vault surfaces.

  • Not investment advice.
  • Derived performance is cadence-dependent and not comparable across implementations.
  • Vault fees and manager share terms come from the vault's own configuration.
  • Field availability is provider- and version-dependent.
  • Historical views are the reader's own construction.

Next Steps for Integration

Start by confirming the request names and response fields against the live response for your API version. Then wire the two read paths into your client, add the reconciliation check, and begin sampling on a fixed cadence. Once you have a few days of snapshots, compute share-price change over the window and report the cadence alongside the result.

For production access, review RPC pricing and the API service page, and browse the OnFinality Learn hub for adjacent Hyperliquid reads. The Hyperliquid network page lists the endpoints and network details you will need.

  • Confirm request names and fields against the live response.
  • Wire both read paths and add the reconciliation check.
  • Sample on a fixed cadence and store snapshots.
  • Compute share-price change and report the cadence.
  • Review pricing and API service pages for production access.

Never Worry about Infrastructure Again

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

Get Started