Skip to main content

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#

HeaderValueRequired
Content-Typeapplication/jsonYes

Parameters#

ParameterTypeRequiredDescription
typestringYesMust 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#

FieldTypeDescription
namestringShort identifier for the DEX (e.g., "xyz", "flx")
fullNamestringDisplay name of the DEX (e.g., "XYZ", "Felix Exchange")
deployerstringEthereum address of the DEX deployer
oracleUpdaterstring | nullAddress authorized to update oracles, or null
feeRecipientstring | nullAddress that receives trading fees, or null
assetToStreamingOiCaparrayList of [assetName, capValue] pairs
subDeployersarrayList of [permission, [addresses]] pairs
deployerFeeScalestringFee scale multiplier for the deployer
lastDeployerFeeScaleChangeTimestringISO 8601 timestamp of last fee scale change
assetToFundingMultiplierarrayList of [assetName, multiplier] pairs
assetToFundingInterestRatearrayList of [assetName, rate] pairs

Asset Streaming OI Cap Entry#

Each entry in assetToStreamingOiCap is a two-element array:

IndexTypeDescription
0stringAsset name prefixed with DEX name (e.g., "xyz:GOLD")
1stringMaximum open interest cap in USD

Sub-Deployer Entry#

Each entry in subDeployers is a two-element array:

IndexTypeDescription
0stringPermission type (e.g., "registerAsset", "setOracle", "setOpenInterestCaps")
1arrayList of Ethereum addresses granted this permission

Known Permission Types#

PermissionDescription
registerAssetRegister new trading assets
setOracleConfigure oracle sources
insertMarginTableInsert margin table configurations
haltTradingHalt trading on specific assets
setMarginTableIdsAssign margin table IDs to assets
setOpenInterestCapsSet open interest limits
setFundingMultipliersConfigure funding rate multipliers
setMarginModesSet margin mode options
setFeeRecipientChange fee recipient address
setFeeScaleAdjust fee scaling
setGrowthModesConfigure growth modes
setFundingInterestRatesSet funding interest rates

Code Examples#

curl -X POST 'https://api-hyperliquid-mainnet-info.n.dwellir.com/API_KEY/info' \
-H 'Content-Type: application/json' \
-d '{
"type": "perpDexs"
}'

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#

ErrorCauseSolution
401 UnauthorizedInvalid API keyVerify your API key is correct
400 Bad RequestInvalid request formatEnsure valid JSON with type field
429 Too Many RequestsRate limit exceededImplement request throttling
500 Internal Server ErrorServer issueRetry 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#

  1. Filter null entries — The response array may contain null values at certain indices
  2. Cache results — DEX configurations change infrequently, cache for 5-15 minutes
  3. Parse asset names — Asset names use the format dexName:SYMBOL (e.g., "xyz:GOLD")
  4. Monitor fee changes — Check lastDeployerFeeScaleChangeTime for recent fee updates
  5. Validate deployer addresses — Verify deployer and fee recipient addresses when integrating
  • 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 →