meta
Get metadata for all available perpetual futures trading pairs on Hyperliquid, including leverage limits, decimal precision, and margin requirements.
This endpoint returns metadata for perpetual futures markets. For spot trading metadata, see spotMeta.
Why Hyperliquid? Build on the dominant perpetuals DEX with 70% market share, $2.7T+ lifetime volume, and $2B TVL with 200K orders/second throughput, zero gas fees, sub-second finality, and fully onchain Central Limit Order Book (CLOB).
When to Use This Endpoint#
The meta endpoint is essential for derivatives traders, trading platforms, and market data providers who need to:
- Validate Order Parameters — Ensure orders comply with leverage and size requirements
- Build Trading Interfaces — Display available markets with correct decimal precision
- Market Discovery — List all tradeable perpetual contracts
- Risk Management — Monitor leverage limits and margin requirements
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 "meta" |
dex | string | No | HIP3 perp DEX identifier. Valid values: "xyz", "flx", "vntl", "hyna", "cash". Omit for Hyperliquid mainnet perpetuals. |
Example Requests#
Hyperliquid Mainnet Perpetuals:
{
"type": "meta"
}
HIP3 Perp DEX (e.g., xyz):
{
"type": "meta",
"dex": "xyz"
}
HIP3 (Hyperliquid Improvement Proposal 3) enables permissionless perpetual futures DEXs built on Hyperliquid. Use the dex parameter to query metadata from specific HIP3 perp DEXs:
- xyz - XYZ perpetuals DEX
- flx - FLX perpetuals DEX
- vntl - VNTL perpetuals DEX
- hyna - HYNA perpetuals DEX
- cash - CASH perpetuals DEX
Omit the dex parameter to query Hyperliquid's mainnet perpetual markets.
Response#
Hyperliquid Mainnet Response#
{
"universe": [
{
"szDecimals": 5,
"name": "BTC",
"maxLeverage": 40,
"marginTableId": 56
},
{
"szDecimals": 4,
"name": "ETH",
"maxLeverage": 25,
"marginTableId": 55
},
{
"szDecimals": 2,
"name": "SOL",
"maxLeverage": 20,
"marginTableId": 54
},
{
"szDecimals": 1,
"name": "MATIC",
"maxLeverage": 20,
"marginTableId": 20,
"isDelisted": true
}
],
"marginTables": [
[
56,
{
"description": "tiered 40x",
"marginTiers": [
{
"lowerBound": "0.0",
"maxLeverage": 40
},
{
"lowerBound": "150000000.0",
"maxLeverage": 20
}
]
}
]
],
"collateralToken": 0
}
HIP3 DEX Response (e.g., xyz)#
{
"universe": [
{
"szDecimals": 4,
"name": "xyz:XYZ100",
"maxLeverage": 25,
"marginTableId": 25,
"onlyIsolated": true,
"marginMode": "noCross",
"growthMode": "enabled",
"lastGrowthModeChangeTime": "2025-11-23T17:37:10.033211662"
},
{
"szDecimals": 3,
"name": "xyz:TSLA",
"maxLeverage": 10,
"marginTableId": 10,
"onlyIsolated": true,
"marginMode": "strictIsolated",
"growthMode": "enabled",
"lastGrowthModeChangeTime": "2025-11-23T17:37:10.033211662"
},
{
"szDecimals": 4,
"name": "xyz:GOLD",
"maxLeverage": 20,
"marginTableId": 20,
"onlyIsolated": true,
"marginMode": "noCross"
}
],
"marginTables": [
[
50,
{
"description": "",
"marginTiers": [
{
"lowerBound": "0.0",
"maxLeverage": 50
}
]
}
]
],
"collateralToken": 0
}
Response Fields#
| Field | Type | Description |
|---|---|---|
universe | array | Array of trading pair objects |
marginTables | array | Array of margin table definitions with tier structures |
collateralToken | integer | Collateral token ID |
Trading Pair Object (Hyperliquid Mainnet)#
| Field | Type | Description |
|---|---|---|
szDecimals | integer | Decimal places for position size |
name | string | Asset symbol (e.g., "BTC", "ETH", "SOL") |
maxLeverage | integer | Maximum allowed leverage for this asset |
marginTableId | integer | ID referencing the margin table for this asset |
isDelisted | boolean | (Optional) true if the asset is delisted |
onlyIsolated | boolean | (Optional) true if only isolated margin is allowed |
Trading Pair Object (HIP3 DEX)#
HIP3 DEX responses include additional fields:
| Field | Type | Description |
|---|---|---|
szDecimals | integer | Decimal places for position size |
name | string | Asset symbol with DEX prefix (e.g., "xyz:TSLA", "xyz:GOLD") |
maxLeverage | integer | Maximum allowed leverage for this asset |
marginTableId | integer | ID referencing the margin table for this asset |
onlyIsolated | boolean | true if only isolated margin is allowed |
marginMode | string | Margin mode: "noCross", "strictIsolated" |
growthMode | string | (Optional) Growth mode status (e.g., "enabled") |
lastGrowthModeChangeTime | string | (Optional) ISO 8601 timestamp of last growth mode change |
isDelisted | boolean | (Optional) true if the asset is delisted |
Margin Table Entry#
Each margin table entry is a tuple [tableId, tableData]:
| Field | Type | Description |
|---|---|---|
tableId | integer | Unique identifier for this margin table |
tableData | object | Margin table configuration |
Table Data Object:
| Field | Type | Description |
|---|---|---|
description | string | Human-readable description of the margin table |
marginTiers | array | Array of margin tier objects defining leverage limits by position size |
Margin Tier Object:
| Field | Type | Description |
|---|---|---|
lowerBound | string | Minimum notional position size for this tier |
maxLeverage | integer | Maximum leverage allowed at this tier |
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":"meta"}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info';
const API_KEY = 'your-api-key-here';
async function getMeta() {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
body: JSON.stringify({ type: 'meta' })
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const meta = await getMeta();
console.log(`Available markets: ${meta.universe.length}`);
// Find specific market
const btcMeta = meta.universe.find(m => m.name === 'BTC');
console.log(`BTC max leverage: ${btcMeta.maxLeverage}x`);
import requests
from typing import Dict, List
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info'
API_KEY = 'your-api-key-here'
def get_meta() -> Dict:
"""Get trading pair metadata"""
response = requests.post(
ENDPOINT,
json={'type': 'meta'},
headers={
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
meta = get_meta()
print(f"Available markets: {len(meta['universe'])}")
# Find specific market
btc_meta = next(m for m in meta['universe'] if m['name'] == 'BTC')
print(f"BTC max leverage: {btc_meta['maxLeverage']}x")
print(f"BTC size decimals: {btc_meta['szDecimals']}")
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 MetaRequest struct {
Type string `json:"type"`
}
type TradingPair struct {
Name string `json:"name"`
SzDecimals int `json:"szDecimals"`
MaxLeverage int `json:"maxLeverage"`
OnlyIsolated bool `json:"onlyIsolated"`
}
type MetaResponse struct {
Universe []TradingPair `json:"universe"`
}
func getMeta() (*MetaResponse, error) {
reqBody, _ := json.Marshal(MetaRequest{Type: "meta"})
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 MetaResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
meta, err := getMeta()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Available markets: %d\n", len(meta.Universe))
// Find BTC
for _, pair := range meta.Universe {
if pair.Name == "BTC" {
fmt.Printf("BTC max leverage: %dx\n", pair.MaxLeverage)
break
}
}
}
Common Use Cases#
1. Validate Order Leverage#
Check if an order's leverage is within allowed limits:
async function validateLeverage(asset, leverage) {
const meta = await getMeta();
const assetMeta = meta.universe.find(m => m.name === asset);
if (!assetMeta) {
throw new Error(`Asset ${asset} not found`);
}
if (leverage > assetMeta.maxLeverage) {
throw new Error(
`Leverage ${leverage}x exceeds maximum ${assetMeta.maxLeverage}x for ${asset}`
);
}
return true;
}
2. Format Position Sizes#
Format position sizes with correct decimal precision:
function formatSize(asset, size, meta) {
const assetMeta = meta.universe.find(m => m.name === asset);
if (!assetMeta) return size.toString();
return size.toFixed(assetMeta.szDecimals);
}
// Usage
const meta = await getMeta();
console.log(formatSize('BTC', 0.123456, meta)); // "0.12345"
console.log(formatSize('ETH', 1.23456, meta)); // "1.2346"
3. Build Market Selector UI#
Create a market selector with leverage information:
async function getMarketList() {
const meta = await getMeta();
return meta.universe.map(market => ({
symbol: market.name,
maxLeverage: market.maxLeverage,
marginType: market.onlyIsolated ? 'Isolated Only' : 'Cross/Isolated',
decimals: market.szDecimals
}));
}
// Usage
const markets = await getMarketList();
markets.forEach(m => {
console.log(`${m.symbol}: ${m.maxLeverage}x leverage (${m.marginType})`);
});
4. Cache Metadata#
Cache metadata to reduce API calls:
class MetaCache {
constructor(ttl = 3600000) { // 1 hour default
this.cache = null;
this.timestamp = 0;
this.ttl = ttl;
}
async get() {
const now = Date.now();
if (this.cache && (now - this.timestamp) < this.ttl) {
return this.cache;
}
this.cache = await getMeta();
this.timestamp = now;
return this.cache;
}
invalidate() {
this.cache = null;
this.timestamp = 0;
}
}
const metaCache = new MetaCache();
Error Handling#
Common Errors#
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid API key | Verify your API key is correct |
429 Too Many Requests | Rate limit exceeded | Implement caching and backoff |
500 Internal Server Error | Server issue | Retry with exponential backoff |
Error Response Example#
{
"error": "Invalid API key",
"code": "UNAUTHORIZED"
}
Robust Error Handling#
async function safeGetMeta(maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getMeta();
} catch (error) {
if (error.response?.status === 429) {
// Rate limit - exponential backoff
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
} else if (i === maxRetries - 1) {
throw error;
}
}
}
}
Best Practices#
- Cache metadata for at least 1 hour as it changes infrequently
- Validate leverage before submitting orders to avoid rejections
- Use correct decimals when formatting position sizes
- Handle errors gracefully with retry logic and fallbacks
- Monitor rate limits to avoid service interruptions
Related Endpoints#
- spotMeta — Get spot trading asset metadata
- exchangeStatus — Check exchange health and status
- clearinghouseState — Get user account state with positions
Access real-time Hyperliquid market metadata with Dwellir's HyperCore Info Endpoint. Get your API key →