userAbstraction
Get the account abstraction mode for a user on Hyperliquid, indicating whether the account operates in unified, portfolio margin, or another mode.
When to Use This Endpoint#
The userAbstraction endpoint is essential for:
- Account Mode Detection — Determine how a user's account is configured
- Margin Logic — Adapt margin calculations based on unified vs portfolio margin mode
- UI Customization — Display the correct interface based on account abstraction type
- Trading Logic — Adjust order placement and risk management based on account mode
Request#
Endpoint#
POST https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info
Headers#
| Header | Value | Required |
|---|---|---|
Content-Type | application/json | Yes |
Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "userAbstraction" |
user | string | Yes | User's Ethereum wallet address |
Example Request#
{
"type": "userAbstraction",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}
Response#
Success Response#
Returns a string indicating the account abstraction mode for the specified user.
"unifiedAccount"
Possible Values#
| Value | Description |
|---|---|
unifiedAccount | Unified account mode — perps and spot share a single margin pool |
portfolioMargin | Portfolio margin mode — margin calculated across the full portfolio |
disabled | Account abstraction is disabled |
default | Default account mode |
Code Examples#
- cURL
- JavaScript
- Python
- Go
curl -X POST 'https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info' \
-H 'Content-Type: application/json' \
-d '{
"type": "userAbstraction",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info';
async function getUserAbstraction(userAddress) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'userAbstraction',
user: userAddress
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const mode = await getUserAbstraction('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Account abstraction mode: ${mode}`);
import requests
from typing import str
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info'
def get_user_abstraction(user_address: str) -> str:
"""Get user account abstraction mode"""
response = requests.post(
ENDPOINT,
json={
'type': 'userAbstraction',
'user': user_address
},
headers={
'Content-Type': 'application/json',
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
mode = get_user_abstraction('0x63E8c7C149556D5f34F833419A287bb9Ef81487f')
print(f"Account abstraction mode: {mode}")
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const Endpoint = "https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info"
type UserAbstractionRequest struct {
Type string `json:"type"`
User string `json:"user"`
}
func getUserAbstraction(userAddress string) (string, error) {
reqBody, _ := json.Marshal(UserAbstractionRequest{
Type: "userAbstraction",
User: userAddress,
})
req, _ := http.NewRequest("POST", Endpoint, bytes.NewBuffer(reqBody))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result string
if err := json.Unmarshal(body, &result); err != nil {
return "", err
}
return result, nil
}
func main() {
mode, err := getUserAbstraction("0x63E8c7C149556D5f34F833419A287bb9Ef81487f")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Account abstraction mode: %s\n", mode)
}
Common Use Cases#
1. Check Account Mode#
Determine the account abstraction mode before executing trades:
async function checkAccountMode(userAddress) {
const mode = await getUserAbstraction(userAddress);
console.log('=== Account Mode ===\n');
console.log(`Mode: ${mode}`);
return mode;
}
// Usage
const mode = await checkAccountMode('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
2. Adapt Trading Logic#
Adjust trading behavior based on account mode:
async function getTradeConfig(userAddress) {
const mode = await getUserAbstraction(userAddress);
const configs = {
unifiedAccount: {
marginShared: true,
spotAndPerpsLinked: true,
description: 'Perps and spot share a single margin pool'
},
portfolioMargin: {
marginShared: true,
spotAndPerpsLinked: true,
description: 'Margin calculated across the full portfolio'
},
disabled: {
marginShared: false,
spotAndPerpsLinked: false,
description: 'Standard isolated margin mode'
},
default: {
marginShared: false,
spotAndPerpsLinked: false,
description: 'Default account configuration'
}
};
return configs[mode] || configs['default'];
}
// Usage
const config = await getTradeConfig('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Mode: ${config.description}`);
console.log(`Margin shared: ${config.marginShared}`);
3. Display Account Mode Badge#
Show account mode in a dashboard:
async function getAccountModeBadge(userAddress) {
const mode = await getUserAbstraction(userAddress);
const badges = {
unifiedAccount: { label: 'Unified Account', color: 'green' },
portfolioMargin: { label: 'Portfolio Margin', color: 'blue' },
disabled: { label: 'Standard', color: 'gray' },
default: { label: 'Default', color: 'gray' }
};
return badges[mode] || { label: mode, color: 'gray' };
}
// Usage
const badge = await getAccountModeBadge('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Display badge: ${badge.label} (${badge.color})`);
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 safeGetUserAbstraction(userAddress, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getUserAbstraction(userAddress);
} catch (error) {
if (error.response?.status === 429) {
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#
- Cache mode data — Account mode changes infrequently, cache for 5-10 minutes
- Validate addresses — Ensure user addresses are valid Ethereum addresses
- Handle unknown modes — Have fallback logic for unrecognized mode values
- Check before trading — Query account mode before placing orders that depend on margin type
- Update on mode change — Invalidate cached data when users switch account modes
Related Endpoints#
- clearinghouseState — Get perpetual account state
- spotClearinghouseState — Get spot account balances
- userRole — Get user role information
- subAccounts — Get sub-account details
Check account abstraction modes with Dwellir's HyperCore Info Endpoint. Get your API key →