userRateLimit
Get rate limit information for a user on Hyperliquid, including current usage and remaining capacity.
When to Use This Endpoint#
The userRateLimit endpoint is essential for:
- Usage Monitoring — Track API usage against rate limits
- Optimization — Identify when to throttle requests
- Compliance — Ensure requests stay within allowed limits
- Planning — Understand user-specific rate limit allocations
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 "userRateLimit" |
user | string | Yes | User's Ethereum wallet address |
Example Request#
{
"type": "userRateLimit",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}
Response#
Success Response#
Returns rate limit information for the specified user.
{
"limit": 100,
"remaining": 95,
"reset": 1704067200000
}
Response Fields#
| Field | Type | Description |
|---|---|---|
limit | integer | Maximum number of requests allowed |
remaining | integer | Number of requests remaining in current period |
reset | integer | Unix timestamp (milliseconds) when rate limit resets |
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": "userRateLimit",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info';
const API_KEY = 'your-api-key-here';
async function getUserRateLimit(userAddress) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
body: JSON.stringify({
type: 'userRateLimit',
user: userAddress
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const rateLimit = await getUserRateLimit('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Remaining: ${rateLimit.remaining}/${rateLimit.limit}`);
console.log(`Resets: ${new Date(rateLimit.reset).toISOString()}`);
import requests
from datetime import datetime
from typing import Dict
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info'
API_KEY = 'your-api-key-here'
def get_user_rate_limit(user_address: str) -> Dict:
"""Get user rate limit information"""
response = requests.post(
ENDPOINT,
json={
'type': 'userRateLimit',
'user': user_address
},
headers={
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
rate_limit = get_user_rate_limit('0x63E8c7C149556D5f34F833419A287bb9Ef81487f')
print(f"Remaining: {rate_limit['remaining']}/{rate_limit['limit']}")
reset_time = datetime.fromtimestamp(rate_limit['reset'] / 1000)
print(f"Resets: {reset_time.isoformat()}")
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
const (
Endpoint = "https://api-hyperliquid-mainnet-info.n.dwellir.com/info"
APIKey = "your-api-key-here"
)
type UserRateLimitRequest struct {
Type string `json:"type"`
User string `json:"user"`
}
type UserRateLimitResponse struct {
Limit int `json:"limit"`
Remaining int `json:"remaining"`
Reset int64 `json:"reset"`
}
func getUserRateLimit(userAddress string) (*UserRateLimitResponse, error) {
reqBody, _ := json.Marshal(UserRateLimitRequest{
Type: "userRateLimit",
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 UserRateLimitResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
rateLimit, err := getUserRateLimit("0x63E8c7C149556D5f34F833419A287bb9Ef81487f")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Remaining: %d/%d\n", rateLimit.Remaining, rateLimit.Limit)
resetTime := time.Unix(rateLimit.Reset/1000, 0)
fmt.Printf("Resets: %s\n", resetTime.Format(time.RFC3339))
}
Common Use Cases#
1. Check Rate Limit Status#
Monitor current rate limit status:
async function checkRateLimitStatus(userAddress) {
const rateLimit = await getUserRateLimit(userAddress);
const percentUsed = ((rateLimit.limit - rateLimit.remaining) / rateLimit.limit) * 100;
const resetDate = new Date(rateLimit.reset);
console.log('=== Rate Limit Status ===\n');
console.log(`Limit: ${rateLimit.limit} requests`);
console.log(`Remaining: ${rateLimit.remaining} (${percentUsed.toFixed(1)}% used)`);
console.log(`Resets: ${resetDate.toISOString()}`);
if (rateLimit.remaining < 10) {
console.warn('WARNING: Approaching rate limit!');
}
}
2. Implement Smart Throttling#
Automatically throttle requests based on remaining capacity:
class RateLimitedClient {
constructor(userAddress) {
this.userAddress = userAddress;
this.lastCheck = null;
}
async shouldThrottle() {
const rateLimit = await getUserRateLimit(this.userAddress);
this.lastCheck = Date.now();
// Throttle if less than 20% remaining
const remainingPercent = (rateLimit.remaining / rateLimit.limit) * 100;
return remainingPercent < 20;
}
async makeRequest(requestFn) {
if (await this.shouldThrottle()) {
const rateLimit = await getUserRateLimit(this.userAddress);
const waitTime = rateLimit.reset - Date.now();
console.log(`Throttling: waiting ${waitTime}ms`);
await new Promise(r => setTimeout(r, waitTime));
}
return await requestFn();
}
}
// Usage
const client = new RateLimitedClient('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
const result = await client.makeRequest(() => someApiCall());
3. Build Rate Limit Monitor#
Create a monitoring system:
async function monitorRateLimit(userAddress, alertThreshold = 10) {
const rateLimit = await getUserRateLimit(userAddress);
const status = {
limit: rateLimit.limit,
remaining: rateLimit.remaining,
used: rateLimit.limit - rateLimit.remaining,
percentUsed: ((rateLimit.limit - rateLimit.remaining) / rateLimit.limit) * 100,
resetTime: new Date(rateLimit.reset),
timeUntilReset: rateLimit.reset - Date.now()
};
if (status.remaining <= alertThreshold) {
console.error(`ALERT: Only ${status.remaining} requests remaining!`);
console.log(`Resets in ${Math.ceil(status.timeUntilReset / 1000)}s`);
}
return status;
}
// Usage
const status = await monitorRateLimit('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log('Rate limit status:', status);
4. Calculate Optimal Request Rate#
Calculate safe request rate:
async function calculateOptimalRate(userAddress) {
const rateLimit = await getUserRateLimit(userAddress);
const timeUntilReset = rateLimit.reset - Date.now();
const secondsUntilReset = timeUntilReset / 1000;
// Calculate requests per second to use remaining capacity
const optimalRPS = rateLimit.remaining / secondsUntilReset;
// Add 20% buffer for safety
const safeRPS = optimalRPS * 0.8;
return {
remaining: rateLimit.remaining,
timeUntilReset: secondsUntilReset,
optimalRPS: optimalRPS,
safeRPS: safeRPS,
delayBetweenRequests: 1000 / safeRPS // milliseconds
};
}
// Usage
const optimal = await calculateOptimalRate('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Safe request rate: ${optimal.safeRPS.toFixed(2)} req/s`);
console.log(`Delay between requests: ${optimal.delayBetweenRequests.toFixed(0)}ms`);
5. Rate Limit Dashboard#
Create a comprehensive rate limit dashboard:
async function getRateLimitDashboard(userAddress) {
try {
const rateLimit = await getUserRateLimit(userAddress);
const now = Date.now();
const percentUsed = ((rateLimit.limit - rateLimit.remaining) / rateLimit.limit) * 100;
const timeUntilReset = rateLimit.reset - now;
return {
status: 'success',
metrics: {
limit: rateLimit.limit,
used: rateLimit.limit - rateLimit.remaining,
remaining: rateLimit.remaining,
percentUsed: percentUsed.toFixed(1) + '%',
resetTime: new Date(rateLimit.reset).toISOString(),
resetIn: `${Math.ceil(timeUntilReset / 1000)}s`
},
health: percentUsed < 80 ? 'healthy' : percentUsed < 95 ? 'warning' : 'critical'
};
} catch (error) {
return {
status: 'error',
error: error.message
};
}
}
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 | Wait for reset time |
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 safeGetUserRateLimit(userAddress, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getUserRateLimit(userAddress);
} catch (error) {
if (error.response?.status === 429) {
// Already rate limited - wait longer
await new Promise(r => setTimeout(r, Math.pow(2, i + 1) * 1000));
} else if (error.response?.status === 400) {
throw new Error('Invalid user address');
} else if (i === maxRetries - 1) {
throw error;
}
}
}
}
Best Practices#
- Check regularly — Monitor rate limits before making bulk requests
- Respect limits — Implement throttling when approaching limits
- Cache strategically — Cache rate limit data for 10-30 seconds
- Plan ahead — Check limits before starting long-running operations
- Implement backoff — Use exponential backoff when limits are reached
Related Endpoints#
- clearinghouseState — Get account state
- userFees — Get user fee information
- openOrders — Get user open orders
Monitor and optimize your Hyperliquid API usage with Dwellir's HyperCore Info Endpoint. Get your API key →