perpDexs
Get all third-party perpetual DEXs deployed on Hyperliquid's infrastructure, including their listed assets, open interest caps, funding parameters, and deployer configuration.
When to Use This Endpoint#
The perpDexs endpoint is essential for:
- DEX Discovery — Enumerate all perpetual DEXs deployed on Hyperliquid
- Asset Listing — Find which assets are available on each DEX and their open interest caps
- Funding Analysis — Query funding multipliers and interest rates across DEXs
- Deployer Verification — Verify deployer addresses and fee recipients for each DEX
- Permission Auditing — Inspect sub-deployer permissions and capabilities
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 "perpDexs" |
Example Request#
{
"type": "perpDexs"
}
Response#
Success Response#
Returns an array of DEX objects. The array may contain null entries at certain indices.
[
null,
{
"name": "xyz",
"fullName": "XYZ",
"deployer": "0x88806a71d74ad0a510b350545c9ae490912f0888",
"oracleUpdater": null,
"feeRecipient": "0x9cd0a696c7cbb9d44de99268194cb08e5684e5fe",
"assetToStreamingOiCap": [
["xyz:AAPL", "50000000.0"],
["xyz:GOLD", "500000000.0"],
["xyz:NVDA", "200000000.0"]
],
"subDeployers": [
["registerAsset", ["0x7d16f116d252db609c56d27d6c9605eb03e16657"]],
["setOracle", ["0x1234567890545d1df9ee64b35fdd16966e08acec"]]
],
"deployerFeeScale": "1.0",
"lastDeployerFeeScaleChangeTime": "1970-01-01T00:00:00",
"assetToFundingMultiplier": [
["xyz:AAPL", "0.5"],
["xyz:GOLD", "0.5"]
],
"assetToFundingInterestRate": []
}
]
Response Fields#
The response is an array where each non-null element is a DEX object.
DEX Object#
| Field | Type | Description |
|---|---|---|
name | string | Short identifier for the DEX (e.g., "xyz", "flx") |
fullName | string | Display name of the DEX (e.g., "XYZ", "Felix Exchange") |
deployer | string | Ethereum address of the DEX deployer |
oracleUpdater | string | null | Address authorized to update oracles, or null |
feeRecipient | string | null | Address that receives trading fees, or null |
assetToStreamingOiCap | array | List of [assetName, capValue] pairs |
subDeployers | array | List of [permission, [addresses]] pairs |
deployerFeeScale | string | Fee scale multiplier for the deployer |
lastDeployerFeeScaleChangeTime | string | ISO 8601 timestamp of last fee scale change |
assetToFundingMultiplier | array | List of [assetName, multiplier] pairs |
assetToFundingInterestRate | array | List of [assetName, rate] pairs |
Asset Streaming OI Cap Entry#
Each entry in assetToStreamingOiCap is a two-element array:
| Index | Type | Description |
|---|---|---|
0 | string | Asset name prefixed with DEX name (e.g., "xyz:GOLD") |
1 | string | Maximum open interest cap in USD |
Sub-Deployer Entry#
Each entry in subDeployers is a two-element array:
| Index | Type | Description |
|---|---|---|
0 | string | Permission type (e.g., "registerAsset", "setOracle", "setOpenInterestCaps") |
1 | array | List of Ethereum addresses granted this permission |
Known Permission Types#
| Permission | Description |
|---|---|
registerAsset | Register new trading assets |
setOracle | Configure oracle sources |
insertMarginTable | Insert margin table configurations |
haltTrading | Halt trading on specific assets |
setMarginTableIds | Assign margin table IDs to assets |
setOpenInterestCaps | Set open interest limits |
setFundingMultipliers | Configure funding rate multipliers |
setMarginModes | Set margin mode options |
setFeeRecipient | Change fee recipient address |
setFeeScale | Adjust fee scaling |
setGrowthModes | Configure growth modes |
setFundingInterestRates | Set funding interest rates |
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": "perpDexs"
}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info';
async function getPerpDexs() {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'perpDexs'
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const dexs = await getPerpDexs();
const activeDexs = dexs.filter(d => d !== null);
console.log(`Total DEXs: ${activeDexs.length}`);
activeDexs.forEach(dex => {
console.log(`${dex.fullName} (${dex.name}): ${dex.assetToStreamingOiCap.length} assets`);
});
import requests
from typing import List, Optional, Dict
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info'
def get_perp_dexs() -> List[Optional[Dict]]:
"""Get all perpetual DEXs deployed on Hyperliquid"""
response = requests.post(
ENDPOINT,
json={
'type': 'perpDexs'
},
headers={
'Content-Type': 'application/json',
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
dexs = get_perp_dexs()
active_dexs = [d for d in dexs if d is not None]
print(f"Total DEXs: {len(active_dexs)}")
for dex in active_dexs:
asset_count = len(dex['assetToStreamingOiCap'])
print(f"{dex['fullName']} ({dex['name']}): {asset_count} assets")
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const Endpoint = "https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info"
type PerpDexsRequest struct {
Type string `json:"type"`
}
type PerpDex struct {
Name string `json:"name"`
FullName string `json:"fullName"`
Deployer string `json:"deployer"`
OracleUpdater *string `json:"oracleUpdater"`
FeeRecipient *string `json:"feeRecipient"`
AssetToStreamingOiCap [][2]string `json:"assetToStreamingOiCap"`
SubDeployers []json.RawMessage `json:"subDeployers"`
DeployerFeeScale string `json:"deployerFeeScale"`
LastDeployerFeeScaleChangeTime string `json:"lastDeployerFeeScaleChangeTime"`
AssetToFundingMultiplier [][2]string `json:"assetToFundingMultiplier"`
AssetToFundingInterestRate [][2]string `json:"assetToFundingInterestRate"`
}
func getPerpDexs() ([]*PerpDex, error) {
reqBody, _ := json.Marshal(PerpDexsRequest{
Type: "perpDexs",
})
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 nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result []*PerpDex
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return result, nil
}
func main() {
dexs, err := getPerpDexs()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
for _, dex := range dexs {
if dex == nil {
continue
}
fmt.Printf("%s (%s): %d assets\n",
dex.FullName, dex.Name, len(dex.AssetToStreamingOiCap))
}
}
Common Use Cases#
1. List All DEXs and Their Assets#
Enumerate all deployed DEXs with their asset counts and total OI capacity:
async function listDexOverview() {
const dexs = await getPerpDexs();
console.log('=== Perpetual DEXs on Hyperliquid ===\n');
dexs.filter(d => d !== null).forEach(dex => {
const totalOiCap = dex.assetToStreamingOiCap.reduce(
(sum, [, cap]) => sum + parseFloat(cap), 0
);
console.log(`${dex.fullName} (${dex.name})`);
console.log(` Deployer: ${dex.deployer}`);
console.log(` Assets: ${dex.assetToStreamingOiCap.length}`);
console.log(` Total OI Cap: $${(totalOiCap / 1e6).toFixed(1)}M`);
console.log(` Fee Scale: ${dex.deployerFeeScale}`);
console.log('');
});
}
2. Find a Specific Asset Across DEXs#
Search for which DEXs list a specific asset:
async function findAssetAcrossDexs(assetSymbol) {
const dexs = await getPerpDexs();
const results = [];
dexs.filter(d => d !== null).forEach(dex => {
const match = dex.assetToStreamingOiCap.find(
([name]) => name.split(':')[1] === assetSymbol
);
if (match) {
const fundingEntry = dex.assetToFundingMultiplier.find(
([name]) => name === match[0]
);
results.push({
dex: dex.fullName,
dexPrefix: dex.name,
asset: match[0],
oiCap: match[1],
fundingMultiplier: fundingEntry ? fundingEntry[1] : 'N/A'
});
}
});
console.log(`\n=== "${assetSymbol}" across DEXs ===\n`);
results.forEach(r => {
console.log(`${r.dex}: OI Cap $${(parseFloat(r.oiCap) / 1e6).toFixed(1)}M | Funding: ${r.fundingMultiplier}`);
});
return results;
}
// Usage
await findAssetAcrossDexs('GOLD');
3. Analyze Funding Parameters#
Compare funding configurations across DEXs:
async function analyzeFunding() {
const dexs = await getPerpDexs();
console.log('=== Funding Analysis ===\n');
dexs.filter(d => d !== null).forEach(dex => {
if (dex.assetToFundingMultiplier.length === 0 &&
dex.assetToFundingInterestRate.length === 0) {
console.log(`${dex.fullName}: No custom funding config`);
return;
}
console.log(`${dex.fullName}:`);
if (dex.assetToFundingMultiplier.length > 0) {
const multipliers = dex.assetToFundingMultiplier.map(([, m]) => parseFloat(m));
const avg = multipliers.reduce((a, b) => a + b, 0) / multipliers.length;
console.log(` Funding multipliers: ${multipliers.length} assets, avg ${avg.toFixed(4)}`);
}
if (dex.assetToFundingInterestRate.length > 0) {
console.log(` Interest rates: ${dex.assetToFundingInterestRate.length} assets`);
}
console.log('');
});
}
4. Audit Sub-Deployer Permissions#
Review which addresses have administrative permissions:
async function auditPermissions(dexName) {
const dexs = await getPerpDexs();
const dex = dexs.find(d => d !== null && d.name === dexName);
if (!dex) {
console.log(`DEX "${dexName}" not found`);
return;
}
console.log(`=== Permission Audit: ${dex.fullName} ===\n`);
console.log(`Deployer: ${dex.deployer}`);
console.log(`Oracle Updater: ${dex.oracleUpdater || 'None'}`);
console.log(`Fee Recipient: ${dex.feeRecipient || 'None'}`);
console.log('\nSub-Deployer Permissions:');
dex.subDeployers.forEach(([permission, addresses]) => {
console.log(` ${permission}:`);
addresses.forEach(addr => console.log(` - ${addr}`));
});
}
// Usage
await auditPermissions('xyz');
5. Monitor OI Cap Utilization#
Build a dashboard showing available capacity:
async function getOiCapSummary() {
const dexs = await getPerpDexs();
const summary = dexs
.filter(d => d !== null)
.map(dex => {
const assets = dex.assetToStreamingOiCap.map(([name, cap]) => ({
asset: name,
oiCap: parseFloat(cap)
}));
const totalCap = assets.reduce((sum, a) => sum + a.oiCap, 0);
const topAssets = assets
.sort((a, b) => b.oiCap - a.oiCap)
.slice(0, 3);
return {
name: dex.fullName,
assetCount: assets.length,
totalOiCap: totalCap,
topAssets: topAssets
};
})
.sort((a, b) => b.totalOiCap - a.totalOiCap);
console.log('=== OI Cap Summary (by total capacity) ===\n');
summary.forEach(dex => {
console.log(`${dex.name}: $${(dex.totalOiCap / 1e6).toFixed(0)}M total (${dex.assetCount} assets)`);
dex.topAssets.forEach(a => {
console.log(` ${a.asset}: $${(a.oiCap / 1e6).toFixed(0)}M`);
});
console.log('');
});
return summary;
}
Error Handling#
Common Errors#
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid API key | Verify your API key is correct |
400 Bad Request | Invalid request format | Ensure valid JSON with type field |
429 Too Many Requests | Rate limit exceeded | Implement request throttling |
500 Internal Server Error | Server issue | Retry with exponential backoff |
Error Response Example#
{
"error": "Invalid request type",
"code": "INVALID_TYPE"
}
Robust Error Handling#
async function safeGetPerpDexs(maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getPerpDexs();
} catch (error) {
if (error.response?.status === 429) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
} else if (i === maxRetries - 1) {
throw error;
}
}
}
}
Best Practices#
- Filter null entries — The response array may contain
nullvalues at certain indices - Cache results — DEX configurations change infrequently, cache for 5-15 minutes
- Parse asset names — Asset names use the format
dexName:SYMBOL(e.g.,"xyz:GOLD") - Monitor fee changes — Check
lastDeployerFeeScaleChangeTimefor recent fee updates - Validate deployer addresses — Verify deployer and fee recipient addresses when integrating
Related Endpoints#
- meta — Get core Hyperliquid trading pair metadata |
- spotMeta — Get spot trading asset metadata |
- exchangeStatus — Monitor exchange health and status |
- clearinghouseState — Get account state for a specific DEX |
Discover perpetual DEXs on Hyperliquid with Dwellir's HyperCore Info Endpoint. Get your API key →