Base URLs
Decibel API supports two environments: Mainnet:https://api.mainnet.aptoslabs.com/decibel
https://api.testnet.aptoslabs.com/decibel
Note about the API URL: The base URLs provide access to all Decibel
markets and trading functionality. This includes perpetual futures markets,
spot markets, and more.
Package Addresses
Each environment has its own package address: Mainnet Package Address:0x50ead22afd6ffd9769e3b3d6e0e64a2a350d68e8b102c4e72e33d0b8cfdfdb06
0xe7da2794b1d8af76532ed95f38bfdf1136abfd8ea3a240189971988a83101b7f
No authentication required: The endpoints in this guide are public and
don’t require authentication headers like OAuth or JWT. However, you do
still need a Decibel Node API key to access the node; simply pass it as
the
Authorization header on your requests, in the format:Authorization: Bearer <NODE_API_KEY>Base URL Variable: In the code examples below,
BASE_URL refers to
either: - https://api.mainnet.aptoslabs.com/decibel for Mainnet -
https://api.testnet.aptoslabs.com/decibel for Testnet Make sure to set this
variable in your code before making requests.Step 1: Get Available Markets
Let’s start by fetching the list of available markets. We’ll use the Get Markets endpoint to retrieve all active trading markets.import requests
BASE_URL = "https://api.mainnet.aptoslabs.com/decibel"
NODE_API_KEY = "YOUR_NODE_API_KEY"
headers = {"Authorization": f"Bearer {NODE_API_KEY}"}
# Make a GET request to the markets endpoint
response = requests.get(f"{BASE_URL}/api/v1/markets", headers=headers)
# Check if the request was successful
if response.status_code == 200:
markets = response.json()
print(f"Found {len(markets)} markets") # Print first 5 markets
for market in markets[:5]:
print(f"- {market.get('market_name', 'N/A')} (leverage: {market.get('max_leverage', 'N/A')}x, addr: {market.get('market_addr', 'N/A')})")
else:
print(f"Error: {response.status_code}")
print(response.text)
const BASE_URL = "https://api.mainnet.aptoslabs.com/decibel";
const NODE_API_KEY = "YOUR_NODE_API_KEY";
fetch(`${BASE_URL}/api/v1/markets`, {
headers: {
Authorization: `Bearer ${NODE_API_KEY}`,
},
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((markets) => {
console.log(`Found ${markets.length} markets`);
markets.slice(0, 5).forEach((market) => {
console.log(`- ${market.market_name || "N/A"} (leverage: ${market.max_leverage || "N/A"}x, addr: ${market.market_addr || "N/A"})`);
});
})
.catch((error) => {
console.error("Error:", error);
});
# Mainnet
curl -X GET https://api.mainnet.aptoslabs.com/decibel/api/v1/markets \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
# Testnet
curl -X GET https://api.testnet.aptoslabs.com/decibel/api/v1/markets \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
Step 2: Get Market Prices
After obtaining the list of markets, you can query price information for a specific market—including Oracle price, mark price, mid price, funding rate, and open interest—using its market address.import requests
BASE_URL = "https://api.mainnet.aptoslabs.com/decibel"
NODE_API_KEY = "YOUR_NODE_API_KEY"
headers = {"Authorization": f"Bearer {NODE_API_KEY}"}
# Replace 'market_address' with an actual market address from Step 1
# Example: "BTC/USD: 0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861"
market_address = "0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861"
# Get market details
response = requests.get(f"{BASE_URL}/api/v1/prices?market={market_address}", headers=headers)
if response.status_code == 200:
data = response.json()
if data:
market = data[0]
print(f"Market: {market.get('market', 'N/A')}")
print(f"Oracle Price: {market.get('oracle_px', 'N/A')}")
print(f"Mark Price: {market.get('mark_px', 'N/A')}")
print(f"Mid Price: {market.get('mid_px', 'N/A')}")
print(f"Funding Rate (bps): {market.get('funding_rate_bps', 'N/A')}")
print(f"Open Interest: {market.get('open_interest', 'N/A')}")
else:
print("No data returned")
else:
print(f"Error: {response.status_code}")
print(response.text)
const BASE_URL = "https://api.mainnet.aptoslabs.com/decibel";
const NODE_API_KEY = "YOUR_NODE_API_KEY";
const marketAddress = "0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861";
fetch(`${BASE_URL}/api/v1/prices?market=${marketAddress}`, {
headers: {
Authorization: `Bearer ${NODE_API_KEY}`,
},
})
.then((response) => response.json())
.then((data) => {
if (data && data.length > 0) {
const market = data[0];
console.log(`Market: ${market.market || "N/A"}`);
console.log(`Oracle Price: ${market.oracle_px || "N/A"}`);
console.log(`Mark Price: ${market.mark_px || "N/A"}`);
console.log(`Mid Price: ${market.mid_px || "N/A"}`);
console.log(`Funding Rate (bps): ${market.funding_rate_bps || "N/A"}`);
console.log(`Open Interest: ${market.open_interest || "N/A"}`);
} else {
console.log("No data returned");
}
})
.catch((error) => {
console.error("Error:", error);
});
# Mainnet
curl -X GET "https://api.mainnet.aptoslabs.com/decibel/api/v1/prices?market=0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
# Testnet
curl -X GET "https://api.testnet.aptoslabs.com/decibel/api/v1/prices?market=0x161b7b3f58327d057ee5824de0c1a4fc4fa3d121b847c138e921a255768a0dca" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
Step 3: Get Order Book Data
Now let’s retrieve the order book for a market, which shows the current buy and sell orders with their prices and sizes.import requests
BASE_URL = "https://api.mainnet.aptoslabs.com/decibel"
NODE_API_KEY = "YOUR_NODE_API_KEY"
headers = {"Authorization": f"Bearer {NODE_API_KEY}"}
ticker_id = "BTC-PERP"
# Get order book
response = requests.get(
f"{BASE_URL}/api/v1/orderbook",
params={"ticker_id": ticker_id},
headers=headers,
)
if response.status_code == 200:
orderbook = response.json()
print("Bids (Buy Orders):")
for bid in orderbook.get("bids", [])[:5]:
print(f" Price: {bid[0]}, Size: {bid[1]}")
print("\nAsks (Sell Orders):")
for ask in orderbook.get("asks", [])[:5]:
print(f" Price: {ask[0]}, Size: {ask[1]}")
else:
print(f"Error: {response.status_code}")
const BASE_URL = "https://api.mainnet.aptoslabs.com/decibel";
const NODE_API_KEY = "YOUR_NODE_API_KEY";
const tickerId = "BTC-PERP";
fetch(`${BASE_URL}/api/v1/orderbook?ticker_id=${tickerId}`, {
headers: {
Authorization: `Bearer ${NODE_API_KEY}`,
},
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((orderbook) => {
console.log("Bids (Buy Orders):");
orderbook.bids.slice(0, 5).forEach((bid: [string, string]) => {
console.log(` Price: ${bid[0]}, Size: ${bid[1]}`);
});
console.log("\nAsks (Sell Orders):");
orderbook.asks.slice(0, 5).forEach((ask: [string, string]) => {
console.log(` Price: ${ask[0]}, Size: ${ask[1]}`);
});
})
.catch((error) => {
console.error("Error:", error);
});
# Mainnet
curl -X GET "https://api.mainnet.aptoslabs.com/decibel/api/v1/orderbook?ticker_id=BTC-PERP" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
# Testnet
curl -X GET "https://api.testnet.aptoslabs.com/decibel/api/v1/orderbook?ticker_id=BTC-PERP" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
Step 4: Get Recent Trades
Finally, let’s fetch recent trades for a market to see the latest trading activity.import requests
BASE_URL = "https://api.mainnet.aptoslabs.com/decibel"
NODE_API_KEY = "YOUR_NODE_API_KEY"
headers = {"Authorization": f"Bearer {NODE_API_KEY}"}
# Replace 'market_address' with an actual market address from Step 1
# Example: "BTC/USD: 0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861"
market_address = "0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861"
# Get recent trades
response = requests.get(
f"{BASE_URL}/api/v1/trades",
params={"market": market_address, "limit": 20, "offset": 0},
headers=headers,
)
if response.status_code == 200:
data = response.json()
trades = data.get("items", [])
total_count = data.get("total_count", 0)
print(f"Recent Trades (Total: {total_count}):")
for trade in trades[:10]:
print(
f" Action: {trade.get('action')}, Price: {trade.get('price')}, "
f"Size: {trade.get('size')}, PnL: {trade.get('realized_pnl_amount')}, "
f"Fee: {trade.get('fee_amount')}"
)
else:
print(f"Error: {response.status_code}")
print(response.text)
const BASE_URL = "https://api.mainnet.aptoslabs.com/decibel";
const NODE_API_KEY = "YOUR_NODE_API_KEY";
const marketAddress = "0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861";
fetch(`${BASE_URL}/api/v1/trades?market=${marketAddress}&limit=20&offset=0`, {
headers: {
Authorization: `Bearer ${NODE_API_KEY}`,
},
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((data) => {
const trades = data.items || [];
const totalCount = data.total_count || 0;
console.log(`Recent Trades (Total: ${totalCount}):`);
trades.slice(0, 10).forEach((trade: any) => {
console.log(
` Action: ${trade.action}, Price: ${trade.price}, ` +
`Size: ${trade.size}, PnL: ${trade.realized_pnl_amount}, ` +
`Fee: ${trade.fee_amount}`,
);
});
})
.catch((error) => {
console.error("Error:", error);
});
# Mainnet
curl -X GET "https://api.mainnet.aptoslabs.com/decibel/api/v1/trades?market=0x5e0e16f34adfb4b316f8d532d68acbfa206826feaaa418d3938046bdc2044861&limit=20&offset=0" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
# Testnet
curl -X GET "https://api.testnet.aptoslabs.com/decibel/api/v1/trades?market=0x161b7b3f58327d057ee5824de0c1a4fc4fa3d121b847c138e921a255768a0dca&limit=20&offset=0" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
Step 5: Get User Fee Rates
Query a user’s current maker/taker fee rates, fee tier based on 30-day rolling volume, the full VIP fee schedule, and daily volume history. Fee-rate and discount fields are returned as decimal numbers (not strings).import requests
BASE_URL = "https://api.mainnet.aptoslabs.com/decibel"
NODE_API_KEY = "YOUR_NODE_API_KEY"
headers = {"Authorization": f"Bearer {NODE_API_KEY}"}
account = "0xYOUR_ACCOUNT_ADDRESS"
response = requests.get(f"{BASE_URL}/api/v1/user_fee_rates?account={account}", headers=headers)
if response.status_code == 200:
data = response.json()
print(f"Account: {data['account']}")
print(f"Fee Tier: {data['fee_tier']}")
print(f"Taker Rate: {data['user_taker_rate']}")
print(f"Maker Rate: {data['user_maker_rate']}")
print(f"Active Referral Discount: {data['active_referral_discount']}")
print(f"30-day daily volume entries: {len(data['daily_user_volume'])}")
print("\nVIP Fee Schedule:")
for tier in data['fee_schedule']['tiers']['vip']:
print(f" >= ${int(tier['volume_threshold']):,} USD -> taker {tier['taker']}, maker {tier['maker']}")
else:
print(f"Error: {response.status_code}")
print(response.text)
const BASE_URL = "https://api.mainnet.aptoslabs.com/decibel";
const NODE_API_KEY = "YOUR_NODE_API_KEY";
const account = "0xYOUR_ACCOUNT_ADDRESS";
fetch(`${BASE_URL}/api/v1/user_fee_rates?account=${account}`, {
headers: {
Authorization: `Bearer ${NODE_API_KEY}`,
},
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log(`Account: ${data.account}`);
console.log(`Fee Tier: ${data.fee_tier}`);
console.log(`Taker Rate: ${data.user_taker_rate}`);
console.log(`Maker Rate: ${data.user_maker_rate}`);
console.log(`Active Referral Discount: ${data.active_referral_discount}`);
console.log(`30-day daily volume entries: ${data.daily_user_volume.length}`);
console.log("\nVIP Fee Schedule:");
data.fee_schedule.tiers.vip.forEach(
(tier: { volume_threshold: string; taker: number; maker: number }) => {
console.log(
` >= $${Number(tier.volume_threshold).toLocaleString()} USD -> taker ${tier.taker}, maker ${tier.maker}`,
);
},
);
})
.catch((error) => {
console.error("Error:", error);
});
# Mainnet
curl -X GET "https://api.mainnet.aptoslabs.com/decibel/api/v1/user_fee_rates?account=0xYOUR_ACCOUNT_ADDRESS" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"
# Testnet
curl -X GET "https://api.testnet.aptoslabs.com/decibel/api/v1/user_fee_rates?account=0xYOUR_ACCOUNT_ADDRESS" \
-H "Authorization: Bearer YOUR_NODE_API_KEY"

