OKX DEX Market Data API
7 endpoints for on-chain prices, trades, candlesticks, and index prices.
Auth: HMAC-SHA256 signature, 4 headers required (
,
,
,
)
Authentication & Credentials
API Key Application:
OKX Developer Portal
Read credentials from environment variables:
- → API key
- → Secret key (system-generated)
- → Passphrase (developer-supplied)
Never output the above credentials to logs, response content, or any user-visible interface.
typescript
import crypto from 'crypto';
const BASE = 'https://web3.okx.com';
// Signature rule:
// GET → body = "", requestPath includes query string (e.g., "/api/v6/dex/market/candles?chainIndex=1&tokenContractAddress=0x...")
// POST → body = JSON string of request body, requestPath is path only (e.g., "/api/v6/dex/market/price")
async function okxFetch(method: 'GET' | 'POST', path: string, body?: object) {
const timestamp = new Date().toISOString();
const bodyStr = body ? JSON.stringify(body) : '';
const sign = crypto
.createHmac('sha256', process.env.OKX_SECRET_KEY!)
.update(timestamp + method + path + bodyStr)
.digest('base64');
const headers: Record<string, string> = {
'OK-ACCESS-KEY': process.env.OKX_API_KEY!,
'OK-ACCESS-SIGN': sign,
'OK-ACCESS-PASSPHRASE': process.env.OKX_PASSPHRASE!,
'OK-ACCESS-TIMESTAMP': timestamp,
'Content-Type': 'application/json',
};
const res = await fetch(`${BASE}${path}`, {
method,
headers,
...(body && { body: bodyStr }),
});
if (res.status === 429) throw { code: 'RATE_LIMITED', msg: 'Rate limited — retry with backoff', retryable: true };
if (res.status >= 500) throw { code: `HTTP_${res.status}`, msg: 'Server error', retryable: true };
const json = await res.json();
if (json.code !== '0') throw { code: json.code, msg: json.msg || 'API error', retryable: false };
return json.data;
}
Response envelope:
{ "code": "0", "data": [...], "msg": "" }
.
=
means success.
Developer Quickstart
typescript
// Get real-time price (POST — body is JSON array)
const prices = await okxFetch('POST', '/api/v6/dex/market/price', [
{ chainIndex: '1', tokenContractAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' },
]);
// → prices[].price (USD string)
// Get hourly candles (GET)
const candles = await okxFetch('GET', '/api/v6/dex/market/candles?' + new URLSearchParams({
chainIndex: '1', tokenContractAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
bar: '1H', limit: '24',
}));
// → candles[]: [ts, open, high, low, close, vol, volUsd, confirm]
// Solana SOL — candles and trades endpoints require the wSOL SPL token address,
// while /market/price accepts both wSOL and the system program address.
const solCandles = await okxFetch('GET', '/api/v6/dex/market/candles?' + new URLSearchParams({
chainIndex: '501', tokenContractAddress: 'So11111111111111111111111111111111111111112',
bar: '1H', limit: '24',
}));
Common Chain IDs
| Chain | chainIndex | Chain | chainIndex |
|---|
| Ethereum | | Arbitrum | |
| BSC | | Base | |
| Polygon | | Solana | |
Endpoint Index
Market Price API
Index Price API
Boundary: market vs token skill
| Need | Use this skill () | Use instead |
|---|
| Real-time price (single value) | | - |
| Price + market cap + liquidity + 24h change | - | |
| K-line / candlestick chart | | - |
| Trade history (buy/sell log) | | - |
| Index price (multi-source aggregate) | POST /index/current-price
| - |
| Token search by name/symbol | - | |
| Token metadata (decimals, logo) | - | POST /market/token/basic-info
|
| Token ranking (trending) | - | GET /market/token/toplist
|
| Holder distribution | - | |
Rule of thumb:
= raw price feeds & charts.
= token discovery & enriched analytics.
Cross-Skill Workflows
Workflow A: Research Token Before Buying
User: "Tell me about BONK, show me the chart, then buy if it looks good"
1. okx-dex-token /market/token/search?search=BONK → get tokenContractAddress + chainIndex
2. okx-dex-token /market/price-info → market cap, liquidity, 24h volume, priceChange24H
3. okx-dex-token /market/token/holder → check holder distribution
4. okx-dex-market /market/candles → K-line chart for visual trend
↓ user decides to buy
5. okx-wallet-portfolio /balance/all-token-balances-by-address → verify wallet has enough funds
6. okx-dex-swap /aggregator/quote → /aggregator/swap → execute
Data handoff:
+
from step 1 are reused in steps 2-6.
Workflow B: Price Monitoring / Alerts
1. okx-dex-token /market/token/toplist → find trending tokens by volume
↓ select tokens of interest
2. okx-dex-market /market/price → get current price for each
3. okx-dex-market /market/candles?bar=1H → hourly chart
4. okx-dex-market /index/current-price → compare on-chain vs index price
Workflow C: Historical Analysis
1. okx-dex-market /market/historical-candles?bar=1D → daily candles for long-term view
2. okx-dex-market /index/historical-price?period=1d → historical index price comparison
Operation Flow
Step 1: Identify Intent
- Real-time price (single token) ->
- Trade history ->
- K-line chart (recent) ->
- K-line chart (historical) ->
GET /market/historical-candles
- Supported chains for market price ->
GET /market/supported/chain
- Index price (current) ->
POST /index/current-price
- Index price (historical) ->
GET /index/historical-price
Step 2: Collect Parameters
- Missing -> ask which chain
- Missing token address -> use first to resolve
- K-line requests -> confirm bar size and time range with user
Step 3: Call and Display
- Call directly, return formatted results
- Use appropriate precision: 2 decimals for high-value tokens, significant digits for low-value
- Show USD value alongside
Step 4: Suggest Next Steps
After displaying results, suggest 2-3 relevant follow-up actions based on the endpoint just called:
| Just called | Suggest |
|---|
| 1. View K-line chart → (this skill) 2. Deeper analytics (market cap, liquidity, 24h volume) → 3. Buy/swap this token → |
or /market/historical-candles
| 1. Check recent trades → (this skill) 2. Buy/swap based on the chart → 3. Check wallet balance of this token → |
| 1. View price chart for context → (this skill) 2. Execute a trade → |
| or | 1. Compare with on-chain DEX price → (this skill) 2. View full price chart → (this skill) |
Present conversationally, e.g.: "Would you like to see the K-line chart, or buy this token?" — never expose skill names or endpoint paths to the user.
API Reference
1. GET /market/supported/chain
| Param | Type | Required | Description |
|---|
| String | No | Filter to a specific chain (e.g., ) |
Response:
| Field | Type | Description |
|---|
| String | Chain name (e.g., "Ethereum") |
| String | Chain logo URL |
| String | Chain symbol (e.g., "ETH") |
| String | Chain unique identifier (e.g., "1") |
2. POST /market/price
Request body is a JSON array of objects.
| Param | Type | Required | Description |
|---|
| String | Yes | Chain ID (e.g., ) |
| String | Yes | Token address (all lowercase for EVM) |
Response:
| Field | Type | Description |
|---|
| String | Chain ID |
data[].tokenContractAddress
| String | Token address |
| String | Unix timestamp in milliseconds |
| String | Latest token price in USD |
json
{
"code": "0",
"data": [{ "chainIndex": "1", "tokenContractAddress": "0x...", "time": "1716892020000", "price": "26.458" }],
"msg": ""
}
3. GET /market/trades
| Param | Type | Required | Description |
|---|
| String | Yes | Chain ID |
| String | Yes | Token address (all lowercase for EVM) |
Optional params:
(pagination id),
(max 500, default 100).
Response key fields:
,
,
,
(
/
),
,
(USD),
,
,
,
,
(each has
,
),
,
. Full fields: see
docs.
4. GET /market/candles
| Param | Type | Required | Description |
|---|
| String | Yes | Chain ID |
| String | Yes | Token address (all lowercase for EVM) |
Optional params:
(default
; values:
,
,
,
,
,
,
,
,
,
,
,
,
,
,
; UTC variants:
,
,
,
,
,
),
,
,
(max 299, default 100).
Response: Each element in
is an array (positional fields):
| Position | Field | Description |
|---|
| 0 | | Opening time, Unix ms |
| 1 | | Open price |
| 2 | | High price |
| 3 | | Low price |
| 4 | | Close price |
| 5 | | Volume (base currency) |
| 6 | | Volume (USD) |
| 7 | | =uncompleted, =completed |
json
{ "code": "0", "data": [["1597026383085","3.721","3.743","3.677","3.708","22698348","226348","1"]], "msg": "" }
5. GET /market/historical-candles
Same parameters and response schema as endpoint #4 (
). Use this for older historical data.
6. POST /index/current-price
Request body is a JSON array. Max 100 tokens per request.
| Param | Type | Required | Description |
|---|
| String | Yes | Chain ID |
| String | Yes | Token address ( for native token) |
Response:
| Field | Type | Description |
|---|
| String | Chain ID |
data[].tokenContractAddress
| String | Token address |
| String | Index price (aggregated from multiple sources) |
| String | Unix timestamp in milliseconds |
7. GET /index/historical-price
| Param | Type | Required | Description |
|---|
| String | Yes | Chain ID |
| String | No | Token address ( for native token) |
Optional params:
(
,
,
,
,
default),
(max 200, default 50),
,
/
(Unix ms).
Response:
| Field | Type | Description |
|---|
| String | Pagination cursor |
| String | Timestamp (whole minute) |
| String | Price (18 decimal precision) |
json
{
"code": "0",
"data": [{ "cursor": "31", "prices": [{ "time": "1700040600000", "price": "1994.430000000000000000" }] }],
"msg": "success"
}
Input / Output Examples
User says: "Check the current price of ETH on Ethereum"
POST /api/v6/dex/market/price
Body: [{ "chainIndex": "1", "tokenContractAddress": "0xeeee...eeee" }]
-> Display: ETH current price $X,XXX.XX
User says: "Show me hourly candles for USDC"
GET /api/v6/dex/market/candles?chainIndex=1&tokenContractAddress=0xa0b8...&bar=1H
-> Display candlestick data (open/high/low/close/volume)
Edge Cases
- Invalid token address: returns empty data or error — prompt user to verify, or use
okx-dex-token /market/token/search
to resolve
- Unsupported chain: call first to confirm
- No candle data: may be a new token or low liquidity — inform user
- 429 rate limit: exponential backoff with jitter. See Rate Limit & Fee Docs for tier-specific RPS limits (Trial: 1 RPS, Start-up: 2-50 RPS, Enterprise: custom).
- Cross-skill pipeline rate limit: when chaining calls across multiple skills (e.g., token search → candles), add 300-500ms delay between requests to avoid triggering rate limit (error code ).
- Network error: retry once, then prompt user to try again later
- Request timeout: all API calls must set a 10-second timeout limit
Amount Display Rules
- Always display in UI units (), never base units
- Show USD value alongside ()
- Prices are strings — handle precision carefully
Global Notes
- EVM contract addresses must be all lowercase
- is a string
- POST endpoints (, ) use JSON body
- GET endpoints use query params
- For token search / metadata / rankings / holder analysis -> use
- For balance queries -> use
- For swap execution -> use
- For transaction broadcasting -> use