Prerequisites: an active VOOI API token and at least one connected exchange. See API Tokens and Use your own keys if you don’t have them yet.
Positions
GET /exchange/positions — open positions across every connected exchange, including entry price, leverage, liquidation price, and unrealized PnL. fundingFee is a nullable position field returned on every venue. liquidationPrice is also nullable on every venue, and on every venue it is an estimate. VOOI normalizes it so that a cross-margin position’s figure reflects the rest of the account rather than that market in isolation, so it can differ from the number the venue’s own interface shows. Treat it as indicative — never as the exact price at which the venue will liquidate.
Account balances
GET /exchange/accounts — one row per sub-account with total balance, available margin, margin in use, withdrawable amount, and the quote token denominating those balances. Aster, Lighter, Robinhood, Extended, Binance, MEXC, and Ondo return a single "perps" row per connection. Bybit returns one "perps" row per settle coin it holds (USDT and USDC). Hyperliquid returns spot rows for USDC and USDH plus a row per perp DEX; the row set depends on the abstraction mode. Read type, token, and exchange together to identify a row.
Field semantics
Every amount is a decimal string in the quote token reported on the same row — readtoken to know which one.
totalBalance— the venue’s notion of account value: free funds plus funds locked by open orders and positions. This is the right field to show as the account’s bottom-line “equity”. The API does not expose a separateequityfield.marginInUse— the portion oftotalBalancecurrently locked as initial margin behind open positions and resting orders.availableMargin— what the venue will let you use to open new positions. RoughlytotalBalance − marginInUse, but each venue applies its own haircuts.withdrawable— what the venue will let you withdraw right now. This is usually smaller thanavailableMargin— venues reserve extra margin behind open positions, pending funding, and in-flight transfers. Showingwithdrawableas “free” in a portfolio UI overstates what the user can actually deploy into a new trade; useavailableMarginfor that and reservewithdrawablefor a withdraw screen.token— the quote token denominating the four balance fields above. Aster always reports"USDT"for the whole account (including positions on its USD1 pairs); Lighter and Robinhood report"USDC"; Extended reports"USD"; MEXC reports"USDT"; Ondo reports"USDC"; Bybit reports the settle coin of the row ("USDT"or"USDC"). Hyperliquid reports"USDC"for USDC-quoted buckets (default perp DEX and the HIP-3 DEXes it currently surfaces, plus USDC spot) and"USDH"for the USDH spot row. Don’t sum balances across rows with differenttokenvalues without converting — they’re different units.type— row classification within the exchange. Aster, Lighter, Robinhood, Extended, Binance, Bybit, MEXC, and Ondo return"perps". Hyperliquid returns"perps"(default USDC perp DEX),"perps:xyz"(trade.xyz),"perps:mkts", or"spot"for a Hyperliquid spot balance. Treat unknown values as opaque.
How many rows to expect on Hyperliquid
Any mode other than
unifiedAccount — including default (never explicitly set) — returns the per-DEX perp rows.
Unfunded buckets still appear with zero balances. The (exchange, type, token) triple uniquely identifies each row across both REST and SSE. To track “Hyperliquid total equity” across modes, sum totalBalance per token and treat the result as USDC-equivalent (USDH is pegged 1:1).
Unrealized PnL does not live on the account row — it’s a per-position figure, returned by GET /exchange/positions. Funding accruals are already reflected in the venue’s balance numbers by the time you read them; there is no separate funding-accrual field on the account.
Which venues appear
Only connected venues show up. A venue the user has not connected — via Use your own keys or one of the registration flows — contributes no rows at all, not a zero row. If your UI always wants a placeholder per supported venue, render the missing ones on the client.Account settings
GET /exchange/account-info — venue-shaped account configuration. Required exchange query parameter selects the venue; the response shape depends on the value:
- Aster — hedge-mode flag, multi-assets margin flag, and the per-market margin type map (
crossorisolated). - Hyperliquid —
abstractionModecontrolling spot + perp collateral. See Hyperliquid account for the four modes and how to change them. - Extended — the applied referral code.
- Lighter and Robinhood — the account’s fee tier (
accountTier) and the maker and taker fees that tier currently charges, in bps. See Account fee tier below. - Bybit — the margin mode applied to the whole unified account (
crossorisolated) andunifiedMarginStatus, Bybit’s account upgrade status. Only unified statuses are tradable.
Account fee tier
Lighter and Robinhood run their accounts on fee tiers. Read the current tier fromGET /exchange/account-info and change it with POST /exchange/lighter/account-tier, which takes { exchange, tier } — exchange selecting the deployment (lighter or robinhood).
The tier is tied to your L1 address, so sub-accounts inherit it.
A tier change the venue refuses — most often the 24-hour cooldown between changes, or a tier that deployment doesn’t run — comes back as a
503 with the venue’s reason in message, not a 400. A 404 means that deployment isn’t connected for this user.Market settings
GET /exchange/market-settings— current leverage and margin mode for one(exchange, asset)pair.POST /exchange/leverage— change leverage for a market.POST /exchange/margin-mode— switch betweencrossandisolatedmargin for a market. Not supported on Lighter — the call is rejected there.
POST /exchange/leverage accepts any positive number, not just an integer. Extended and Lighter honor fractional values (for example 12.5); Hyperliquid still requires an integer and rejects fractional leverage.
There is no
GET /exchange/leverage. Leverage and margin mode are read together from GET /exchange/market-settings. If you’re porting from Binance, Bybit, OKX, or another venue where reads and writes share the /leverage path, this is the only mapping that differs — the two writes (POST /exchange/leverage, POST /exchange/margin-mode) keep the names you expect.Next steps
Orders
Place and cancel orders
Quotes and slippage
Simulate trades before placing them