extraAgents
Get information about extra agents configured for a user, including trading agents, permissions, and delegated access settings.
When to Use This Endpoint#
The extraAgents endpoint is essential for:
- Agent Management — View all agents with access to the account
- Permission Tracking — Monitor agent permissions and access levels
- Security Auditing — Verify authorized agents and delegated access
- Access Control — Manage who can trade on behalf of the account
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 "extraAgents" |
user | string | Yes | User's Ethereum wallet address |
Example Request#
{
"type": "extraAgents",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}
Response#
Success Response#
[
{
"name": "pampit",
"address": "0xd0621288b7f42151d326442a950bb829703a343a",
"validUntil": 1785838333108
},
{
"name": "pampit2",
"address": "0x846d88dafbccd9524d674c1a6ac5d470273ff041",
"validUntil": 1778073895185
}
]
Response Fields#
The response is an array of agent objects. Each agent contains:
| Field | Type | Description |
|---|---|---|
name | string | Agent name/identifier |
address | string | Ethereum address of the agent |
validUntil | integer | Unix timestamp (milliseconds) when agent access expires |
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": "extraAgents",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info';
const API_KEY = 'your-api-key-here';
async function getExtraAgents(userAddress) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
body: JSON.stringify({
type: 'extraAgents',
user: userAddress
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const agents = await getExtraAgents('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Total agents: ${agents.agents.length}`);
import requests
from typing import Dict
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info'
API_KEY = 'your-api-key-here'
def get_extra_agents(user_address: str) -> Dict:
"""Get extra agent information"""
response = requests.post(
ENDPOINT,
json={
'type': 'extraAgents',
'user': user_address
},
headers={
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
agents = get_extra_agents('0x63E8c7C149556D5f34F833419A287bb9Ef81487f')
print(f"Total agents: {len(agents['agents'])}")
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 ExtraAgentsRequest struct {
Type string `json:"type"`
User string `json:"user"`
}
type ExtraAgentsResponse struct {
Agents []interface{} `json:"agents"`
}
func getExtraAgents(userAddress string) (*ExtraAgentsResponse, error) {
reqBody, _ := json.Marshal(ExtraAgentsRequest{
Type: "extraAgents",
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 ExtraAgentsResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
agents, err := getExtraAgents("0x63E8c7C149556D5f34F833419A287bb9Ef81487f")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Total agents: %d\n", len(agents.Agents))
}
Common Use Cases#
1. List All Agents#
Display all agents with access to the account:
async function listAgents(userAddress) {
const data = await getExtraAgents(userAddress);
console.log('=== Account Agents ===\n');
console.log(`Total agents: ${data.agents.length}`);
if (data.agents.length === 0) {
console.log('No extra agents configured');
} else {
console.log('Agents have access to this account');
}
}
// Usage
await listAgents('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
2. Security Audit#
Audit agent access for security:
async function auditAgentAccess(userAddress) {
const data = await getExtraAgents(userAddress);
const audit = {
timestamp: new Date().toISOString(),
agentCount: data.agents.length,
hasAgents: data.agents.length > 0,
securityStatus: data.agents.length === 0 ? 'no-agents' : 'agents-configured'
};
console.log('=== Security Audit ===\n');
console.log(`Agent count: ${audit.agentCount}`);
console.log(`Status: ${audit.securityStatus}`);
return audit;
}
// Usage
const audit = await auditAgentAccess('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
3. Monitor Agent Changes#
Track changes in agent configuration:
class AgentMonitor {
constructor(userAddress) {
this.userAddress = userAddress;
this.lastKnownCount = null;
}
async checkForChanges() {
const data = await getExtraAgents(this.userAddress);
const currentCount = data.agents.length;
if (this.lastKnownCount !== null) {
const change = currentCount - this.lastKnownCount;
if (change > 0) {
console.log(`⚠️ ${change} new agent(s) added`);
} else if (change < 0) {
console.log(`✓ ${Math.abs(change)} agent(s) removed`);
}
}
this.lastKnownCount = currentCount;
return {
currentCount: currentCount,
changed: this.lastKnownCount !== null && currentCount !== this.lastKnownCount
};
}
}
// Usage
const monitor = new AgentMonitor('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
setInterval(() => monitor.checkForChanges(), 60000); // Check every minute
4. Build Agent Dashboard#
Create agent management dashboard:
async function getAgentDashboard(userAddress) {
try {
const data = await getExtraAgents(userAddress);
return {
status: 'success',
agents: data.agents,
totalAgents: data.agents.length,
hasAgents: data.agents.length > 0,
lastUpdated: new Date().toISOString()
};
} catch (error) {
return {
status: 'error',
error: error.message,
agents: []
};
}
}
// Usage
const dashboard = await getAgentDashboard('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log('Agent Dashboard:', dashboard);
5. Verify Agent Authorization#
Check if agents are properly authorized:
async function verifyAgentAuthorization(userAddress) {
const data = await getExtraAgents(userAddress);
const verification = {
isConfigured: data.agents.length > 0,
agentCount: data.agents.length,
status: data.agents.length > 0 ? 'agents-active' : 'no-agents',
recommendation: data.agents.length > 0
? 'Review agent permissions regularly'
: 'No agents configured'
};
console.log('Agent Authorization:', verification);
return verification;
}
// Usage
const verification = await verifyAgentAuthorization('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
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 safeGetExtraAgents(userAddress, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getExtraAgents(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#
- Validate addresses — Ensure user addresses are valid Ethereum addresses
- Cache data — Cache agent data for several minutes
- Monitor changes — Track agent additions/removals for security
- Regular audits — Periodically review agent access for security
- Handle empty states — Account for users without extra agents
Security Considerations#
Regular Security Checks#
class SecurityChecker {
constructor(userAddress, checkIntervalMs = 300000) {
this.userAddress = userAddress;
this.checkIntervalMs = checkIntervalMs; // 5 minutes
}
async performSecurityCheck() {
const data = await getExtraAgents(this.userAddress);
const securityReport = {
timestamp: new Date().toISOString(),
agentCount: data.agents.length,
status: data.agents.length === 0 ? 'secure-no-agents' : 'review-required'
};
if (data.agents.length > 0) {
console.log(`⚠️ Security Review: ${data.agents.length} agent(s) have access`);
} else {
console.log('✓ Security Check: No extra agents');
}
return securityReport;
}
async startMonitoring() {
// Initial check
await this.performSecurityCheck();
// Periodic checks
setInterval(() => this.performSecurityCheck(), this.checkIntervalMs);
}
}
Related Endpoints#
- subAccounts — Get sub-account information
- userRole — Get user role information
- clearinghouseState — Get account state
- openOrders — Get orders placed by agents
Manage agent access and permissions with Dwellir's HyperCore Info Endpoint. Get your API key →