Spot vs Perps: What Changes
A spot position tracks tokens bought and sold onchain. A perps position tracks a leveraged long or short on Hyperliquid. The API returns both through the same position-fetching endpoints. Perps positions are distinguished by three fields onmetadata (plus three new properties on metadata.positionStats, discussed later):
| Field | Type | Description |
|---|---|---|
perpPositionType | "long" | "short" | null | Position direction. Present only on perps. |
perpLeverage | number | null | Leverage multiplier (e.g. 2, 5, 10). |
positionAmountWithLeverage | number | Token amount with leverage applied. |
perpPositionType is null or absent, the position is spot.
Perps Fields in Detail
Position Direction and Leverage
perpPositionType tells you whether the trader is long or short. perpLeverage is the multiplier. positionAmount is the base amount (the margin denominated in the token), and positionAmountWithLeverage is the notional exposure (positionAmount * perpLeverage).
For shorts on Hyperliquid, positionAmount can be negative.
Position Stats
Perps positions add several fields topositionStats:
| Field | Type | Description |
|---|---|---|
holdingsCostBasisUSD | number | The margin (collateral) in USD |
holdingsCostBasisUSDWithLeverage | number | The leveraged cost basis in USD |
boughtUSDWithLeverage | number | Total USD entered with leverage applied |
soldUSDWithLeverage | number | Total USD exited with leverage applied |
holdingsCostBasisUSD is the total cost of the tokens currently held. For perps, it represents the margin posted. The WithLeverage variants reflect the full notional values.
Metadata vs Trade-Level Props
perpPositionType and perpLeverage exist in two places: on metadata (position-level) and on each object in the trades array. They serve different purposes.
Metadata-level (metadata.perpPositionType, metadata.perpLeverage) reflects the current state of the position. Use these for:
- Position cards, profile pages, and token screens
- PnL calculations
- Detecting whether a position is perps or spot
- Displaying the current direction and leverage
trade.perpPositionType, trade.perpLeverage) reflects what happened at the time of that specific trade. Use these when rendering individual trade activity. The trade-level leverage matters because it tells you the leverage that trade used, which is what you want when describing the action:
Computing Unrealized PnL
For spot positions, unrealized PnL is:holdingsCostBasisUSD) is what the trader actually put up. The leveraged cost basis is what determines PnL.
Perps Trade Actions
If you’re building activity feeds or notifications, you can use thetrades array to produce more descriptive copy than “entered” or “exited.” The Clicker app has copy for four different types of actions:
| Action | How to derive | Example copy |
|---|---|---|
open | intent is "enter" and it’s the first trade | ”opened a 5x long on ETH” |
add | intent is "enter" and prior trades exist | ”5x longed $2,000 more of ETH” |
partial-close | intent is "exit" and the position still has balance | ”closed $500 of their 5x long ETH” |
full-close | intent is "exit" and the position is fully closed | ”closed their 5x long ETH” |