clearinghouseState
Get comprehensive account state for perpetual trading, including margin summary, open positions, unrealized PnL, and liquidation prices.
Why Hyperliquid? Build on the dominant perpetuals DEX with 70% market share, $2.7T+ lifetime volume, and $2B TVL with 200K orders/second throughput, zero gas fees, sub-second finality, and fully onchain Central Limit Order Book (CLOB).
When to Use This Endpoint#
The clearinghouseState endpoint is essential for derivatives traders, portfolio managers, and trading platforms who need to:
- Monitor Account Health — Track account value, margin usage, and withdrawable balance
- Risk Management — Monitor liquidation prices and position exposure
- Portfolio Analytics — Calculate unrealized PnL across all positions
- Trading Bots — Make automated trading decisions based on account state
Request#
Endpoint#
POST https://api-hyperliquid-mainnet-info.n.dwellir.com/info
Headers#
| Header | Value | Required |
|---|---|---|
Content-Type | application/json | Yes |
X-Api-Key | Your API key | Yes |
Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "clearinghouseState" |
user | string | Yes | User's Ethereum wallet address |
dex | string | No | Specific DEX identifier (optional) |
Example Request#
{
"type": "clearinghouseState",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}
Response#
Success Response#
{
"marginSummary": {
"accountValue": "10000.50",
"totalNtlPos": "5000.25",
"totalRawUsd": "10000.00",
"totalMarginUsed": "2000.00",
"withdrawable": "8000.50"
},
"crossMarginSummary": {
"accountValue": "10000.50",
"totalNtlPos": "5000.25",
"totalRawUsd": "10000.00"
},
"assetPositions": [
{
"position": {
"coin": "BTC",
"szi": "0.5",
"leverage": {
"type": "cross",
"value": 5
},
"entryPx": "40000.00",
"positionValue": "20000.00",
"unrealizedPnl": "500.00",
"liquidationPx": "35000.00"
}
}
]
}
Response Fields#
| Field | Type | Description |
|---|---|---|
marginSummary | object | Overall margin information |
crossMarginSummary | object | Cross-margin specific summary |
assetPositions | array | List of open positions with details |
Margin Summary Object#
| Field | Type | Description |
|---|---|---|
accountValue | string | Total account value in USD |
totalNtlPos | string | Total notional position value |
totalRawUsd | string | Raw USD balance |
totalMarginUsed | string | Total margin currently in use |
withdrawable | string | Amount available for withdrawal |
Cross Margin Summary Object#
| Field | Type | Description |
|---|---|---|
accountValue | string | Account value for cross margin |
totalNtlPos | string | Total notional position value |
totalRawUsd | string | Raw USD balance |
Asset Position Object#
| Field | Type | Description |
|---|---|---|
position | object | Position details |
Position Details#
| Field | Type | Description |
|---|---|---|
coin | string | Asset symbol (e.g., "BTC", "ETH") |
szi | string | Signed position size (positive for long, negative for short) |
leverage | object | Leverage information with type ("cross" or "isolated") and value |
entryPx | string | Average entry price |
positionValue | string | Current position value in USD |
unrealizedPnl | string | Unrealized profit and loss |
liquidationPx | string | Liquidation price |
Code Examples#
- cURL
- JavaScript
- Python
- Go
curl -X POST 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info' \
-H 'X-Api-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "clearinghouseState",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info';
const API_KEY = 'your-api-key-here';
async function getClearinghouseState(userAddress) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
body: JSON.stringify({
type: 'clearinghouseState',
user: userAddress
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const state = await getClearinghouseState('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Account Value: $${state.marginSummary.accountValue}`);
console.log(`Margin Used: $${state.marginSummary.totalMarginUsed}`);
console.log(`Withdrawable: $${state.marginSummary.withdrawable}`);
console.log(`Open Positions: ${state.assetPositions.length}`);
// Calculate total unrealized PnL
const totalPnl = state.assetPositions.reduce((sum, pos) => {
return sum + parseFloat(pos.position.unrealizedPnl);
}, 0);
console.log(`Total Unrealized PnL: $${totalPnl.toFixed(2)}`);
import requests
from typing import Dict
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info'
API_KEY = 'your-api-key-here'
def get_clearinghouse_state(user_address: str) -> Dict:
"""Get user's perpetual account state"""
response = requests.post(
ENDPOINT,
json={
'type': 'clearinghouseState',
'user': user_address
},
headers={
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
state = get_clearinghouse_state('0x63E8c7C149556D5f34F833419A287bb9Ef81487f')
margin = state['marginSummary']
print(f"Account Value: ${margin['accountValue']}")
print(f"Margin Used: ${margin['totalMarginUsed']}")
print(f"Withdrawable: ${margin['withdrawable']}")
print(f"Open Positions: {len(state['assetPositions'])}")
# Calculate total unrealized PnL
total_pnl = sum(
float(pos['position']['unrealizedPnl'])
for pos in state['assetPositions']
)
print(f"Total Unrealized PnL: ${total_pnl:.2f}")
# List all positions
for pos in state['assetPositions']:
p = pos['position']
side = "LONG" if float(p['szi']) > 0 else "SHORT"
print(f"{p['coin']}: {side} {abs(float(p['szi']))} @ ${p['entryPx']} | PnL: ${p['unrealizedPnl']}")
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
Endpoint = "https://api-hyperliquid-mainnet-info.n.dwellir.com/info"
APIKey = "your-api-key-here"
)
type ClearinghouseRequest struct {
Type string `json:"type"`
User string `json:"user"`
}
type MarginSummary struct {
AccountValue string `json:"accountValue"`
TotalNtlPos string `json:"totalNtlPos"`
TotalRawUsd string `json:"totalRawUsd"`
TotalMarginUsed string `json:"totalMarginUsed"`
Withdrawable string `json:"withdrawable"`
}
type Leverage struct {
Type string `json:"type"`
Value int `json:"value"`
}
type Position struct {
Coin string `json:"coin"`
Szi string `json:"szi"`
Leverage Leverage `json:"leverage"`
EntryPx string `json:"entryPx"`
PositionValue string `json:"positionValue"`
UnrealizedPnl string `json:"unrealizedPnl"`
LiquidationPx string `json:"liquidationPx"`
}
type AssetPosition struct {
Position Position `json:"position"`
}
type ClearinghouseState struct {
MarginSummary MarginSummary `json:"marginSummary"`
CrossMarginSummary MarginSummary `json:"crossMarginSummary"`
AssetPositions []AssetPosition `json:"assetPositions"`
}
func getClearinghouseState(userAddress string) (*ClearinghouseState, error) {
reqBody, _ := json.Marshal(ClearinghouseRequest{
Type: "clearinghouseState",
User: userAddress,
})
req, _ := http.NewRequest("POST", Endpoint, bytes.NewBuffer(reqBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Api-Key", APIKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result ClearinghouseState
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
state, err := getClearinghouseState("0x63E8c7C149556D5f34F833419A287bb9Ef81487f")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Account Value: $%s\n", state.MarginSummary.AccountValue)
fmt.Printf("Margin Used: $%s\n", state.MarginSummary.TotalMarginUsed)
fmt.Printf("Withdrawable: $%s\n", state.MarginSummary.Withdrawable)
fmt.Printf("Open Positions: %d\n", len(state.AssetPositions))
for _, assetPos := range state.AssetPositions {
pos := assetPos.Position
fmt.Printf("%s: %s @ $%s | PnL: $%s\n",
pos.Coin, pos.Szi, pos.EntryPx, pos.UnrealizedPnl)
}
}
Common Use Cases#
1. Check Account Health#
Monitor account health and margin utilization:
async function checkAccountHealth(userAddress) {
const state = await getClearinghouseState(userAddress);
const margin = state.marginSummary;
const marginUsed = parseFloat(margin.totalMarginUsed);
const accountValue = parseFloat(margin.accountValue);
const utilizationRate = (marginUsed / accountValue) * 100;
return {
healthy: utilizationRate < 80,
utilizationRate: utilizationRate.toFixed(2),
accountValue: accountValue,
marginUsed: marginUsed,
withdrawable: parseFloat(margin.withdrawable)
};
}
// Usage
const health = await checkAccountHealth('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
if (!health.healthy) {
console.warn(`High margin usage: ${health.utilizationRate}%`);
}
2. Monitor Liquidation Risk#
Track liquidation prices for all positions:
async function getLiquidationRisks(userAddress, currentPrices) {
const state = await getClearinghouseState(userAddress);
return state.assetPositions.map(pos => {
const position = pos.position;
const currentPrice = currentPrices[position.coin];
const liquidationPrice = parseFloat(position.liquidationPx);
const isLong = parseFloat(position.szi) > 0;
const distance = isLong
? ((currentPrice - liquidationPrice) / currentPrice) * 100
: ((liquidationPrice - currentPrice) / currentPrice) * 100;
return {
coin: position.coin,
side: isLong ? 'LONG' : 'SHORT',
currentPrice: currentPrice,
liquidationPrice: liquidationPrice,
distancePercent: distance.toFixed(2),
risk: distance < 10 ? 'HIGH' : distance < 25 ? 'MEDIUM' : 'LOW'
};
});
}
3. Calculate Portfolio Metrics#
Compute portfolio-wide metrics:
async function getPortfolioMetrics(userAddress) {
const state = await getClearinghouseState(userAddress);
const totalPnl = state.assetPositions.reduce((sum, pos) => {
return sum + parseFloat(pos.position.unrealizedPnl);
}, 0);
const totalPositionValue = state.assetPositions.reduce((sum, pos) => {
return sum + parseFloat(pos.position.positionValue);
}, 0);
const accountValue = parseFloat(state.marginSummary.accountValue);
const pnlPercent = (totalPnl / accountValue) * 100;
return {
accountValue: accountValue,
totalPnl: totalPnl,
pnlPercent: pnlPercent.toFixed(2),
positionCount: state.assetPositions.length,
totalPositionValue: totalPositionValue,
leverage: (totalPositionValue / accountValue).toFixed(2)
};
}
4. Position Summary Report#
Generate a detailed position summary:
async function getPositionSummary(userAddress) {
const state = await getClearinghouseState(userAddress);
console.log('\n=== Account Summary ===');
console.log(`Account Value: $${state.marginSummary.accountValue}`);
console.log(`Margin Used: $${state.marginSummary.totalMarginUsed}`);
console.log(`Withdrawable: $${state.marginSummary.withdrawable}`);
console.log('\n=== Open Positions ===');
state.assetPositions.forEach(pos => {
const p = pos.position;
const side = parseFloat(p.szi) > 0 ? 'LONG' : 'SHORT';
const size = Math.abs(parseFloat(p.szi));
console.log(`\n${p.coin} ${side}`);
console.log(` Size: ${size}`);
console.log(` Entry Price: $${p.entryPx}`);
console.log(` Position Value: $${p.positionValue}`);
console.log(` Unrealized PnL: $${p.unrealizedPnl}`);
console.log(` Liquidation Price: $${p.liquidationPx}`);
console.log(` Leverage: ${p.leverage.value}x (${p.leverage.type})`);
});
}
Error Handling#
Common Errors#
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid API key | Verify your API key is correct |
400 Bad Request | Missing or invalid user address | Ensure valid Ethereum address format |
429 Too Many Requests | Rate limit exceeded | Implement request throttling |
500 Internal Server Error | Server issue | Retry with exponential backoff |
Error Response Example#
{
"error": "Missing required parameter: user",
"code": "MISSING_PARAMETER"
}
Robust Error Handling#
async function safeGetClearinghouseState(userAddress, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getClearinghouseState(userAddress);
} catch (error) {
if (error.response?.status === 429) {
// Rate limit - exponential backoff
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
} else if (error.response?.status === 400) {
throw new Error('Invalid user address');
} else if (i === maxRetries - 1) {
throw error;
}
}
}
}
Best Practices#
- Poll responsibly — Don't poll more frequently than needed (every 5-10 seconds is usually sufficient)
- Handle empty positions — Account may have no open positions
- Validate addresses — Ensure user addresses are valid Ethereum addresses
- Monitor liquidation risk — Set alerts when positions approach liquidation
- Cache when appropriate — Cache data briefly to reduce API calls for dashboards
Related Endpoints#
- openOrders — Get user's open orders
- userFees — Get user fee rates and volume
- spotClearinghouseState — Get spot trading account state
- meta — Get trading pair metadata for validation
Access real-time Hyperliquid account state with Dwellir's HyperCore Info Endpoint. Get your API key →