OKX API: Complete Guide to Automated Trading in 2026
Master the OKX API for algorithmic trading — from generating your first API key to executing trades with Python. Practical code examples and real endpoint walkthroughs included.
Master the OKX API for algorithmic trading — from generating your first API key to executing trades with Python. Practical code examples and real endpoint walkthroughs included.
Manual trading has a ceiling. You can only watch so many charts, react so fast, and stay awake so long. The OKX API removes those limits by giving you programmatic access to one of the largest crypto exchanges in the world — spot, futures, options, and swaps all through a single unified interface.
OKX API v5 is the current production version, and it's a significant step up from earlier iterations. The unified account model means you interact with one API layer regardless of the product you're trading. Compare that to Binance, where spot and futures APIs are separate endpoints with different authentication flows, or Bybit, which recently consolidated its own API but still carries some v3 legacy quirks. OKX got the unified approach right early, and it shows in the developer experience.
Whether you're building a market-making bot, pulling real-time data for a signal platform like VoiceOfChain, or simply automating your DCA strategy — the OKX API documentation covers every endpoint you'll need. Let's get into the practical stuff.
Before writing a single line of code, you need an OKX API key. Head to your OKX account, navigate to the API management section, and create a new key. You'll get three pieces of information: the API key, the secret key, and a passphrase you set yourself. All three are required for every authenticated request.
A common error traders hit: 'OKX API key doesn't exist.' This almost always means your key was created on the demo trading environment but you're hitting the live API (or vice versa). OKX maintains separate keys for live and demo. Double-check which environment your key belongs to before debugging further.
Store your credentials in environment variables, never in source code. Here's a minimal setup:
# Add to your .env or shell profile
export OKX_API_KEY="your-api-key-here"
export OKX_SECRET_KEY="your-secret-key-here"
export OKX_PASSPHRASE="your-passphrase-here"
OKX API authentication uses HMAC SHA256 signatures. Every authenticated request requires four headers: the API key, a signature, a timestamp, and the passphrase. The signature is computed over the timestamp, HTTP method, request path, and body. It sounds involved, but the OKX API doc lays it out clearly, and with a helper function, you never think about it again.
Here's a complete Python example using the OKX API to fetch your account balance — this is usually the first thing you'll test to confirm your key works:
import os
import time
import hmac
import hashlib
import base64
import requests
API_KEY = os.environ['OKX_API_KEY']
SECRET_KEY = os.environ['OKX_SECRET_KEY']
PASSPHRASE = os.environ['OKX_PASSPHRASE']
BASE_URL = 'https://www.okx.com'
def get_timestamp():
return time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime())
def sign_request(timestamp, method, path, body=''):
message = timestamp + method.upper() + path + body
mac = hmac.new(
SECRET_KEY.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
)
return base64.b64encode(mac.digest()).decode('utf-8')
def okx_request(method, endpoint, body=''):
timestamp = get_timestamp()
signature = sign_request(timestamp, method, endpoint, body)
headers = {
'OK-ACCESS-KEY': API_KEY,
'OK-ACCESS-SIGN': signature,
'OK-ACCESS-TIMESTAMP': timestamp,
'OK-ACCESS-PASSPHRASE': PASSPHRASE,
'Content-Type': 'application/json'
}
url = BASE_URL + endpoint
if method == 'GET':
resp = requests.get(url, headers=headers)
else:
resp = requests.post(url, headers=headers, data=body)
return resp.json()
# Fetch account balance
result = okx_request('GET', '/api/v5/account/balance')
if result['code'] == '0':
for detail in result['data'][0]['details']:
ccy = detail['ccy']
available = detail['availBal']
print(f'{ccy}: {available}')
else:
print(f"Error {result['code']}: {result['msg']}")
The OKX API endpoint pattern is consistent: /api/v5/{category}/{action}. Account endpoints live under /api/v5/account/, market data under /api/v5/market/, and trading under /api/v5/trade/. Once you internalize this structure, navigating the OKX API documentation becomes intuitive.
Reading data is useful, but the real power of OKX API trading is execution. Let's place a limit order on the BTC-USDT spot pair:
import json
def place_limit_order(inst_id, side, size, price):
endpoint = '/api/v5/trade/order'
body = json.dumps({
'instId': inst_id,
'tdMode': 'cash', # 'cash' for spot, 'cross'/'isolated' for margin
'side': side, # 'buy' or 'sell'
'ordType': 'limit',
'sz': str(size),
'px': str(price)
})
result = okx_request('POST', endpoint, body)
if result['code'] == '0':
order_id = result['data'][0]['ordId']
print(f'Order placed: {order_id}')
return order_id
else:
error_msg = result['data'][0].get('sMsg', result['msg'])
print(f'Order failed: {error_msg}')
return None
def check_order(inst_id, order_id):
endpoint = f'/api/v5/trade/order?instId={inst_id}&ordId={order_id}'
result = okx_request('GET', endpoint)
if result['code'] == '0':
state = result['data'][0]['state']
filled = result['data'][0]['fillSz']
print(f'Order {order_id}: state={state}, filled={filled}')
return result['data'][0]
else:
print(f'Query failed: {result["msg"]}')
return None
# Place a buy order for 0.001 BTC at $60,000
order_id = place_limit_order('BTC-USDT', 'buy', '0.001', '60000')
if order_id:
check_order('BTC-USDT', order_id)
Notice the tdMode parameter — this is where OKX's unified account model shines. The same order endpoint handles spot ('cash'), cross margin ('cross'), isolated margin ('isolated'), and even contract trading. On Gate.io or KuCoin, you'd need to hit completely different API paths for each of these. OKX keeps it clean.
Always test on OKX's demo trading environment first. Use https://www.okx.com with the header 'x-simulated-trading: 1' or create a separate demo API key. One bad loop in production and your account balance pays the price.
Production bots need to handle failures gracefully. The OKX API status page and the /api/v5/system/status endpoint tell you about scheduled maintenance or ongoing incidents. Check it before blaming your code.
Common error codes you'll encounter in practice:
| Error Code | Meaning | What To Do |
|---|---|---|
| 50001 | API key doesn't exist or is invalid | Verify key, check live vs. demo environment |
| 50011 | Request timestamp expired | Sync your server clock (NTP), ensure UTC |
| 50013 | IP not whitelisted | Add your server IP to the API key settings |
| 51008 | Insufficient balance | Check available funds before placing orders |
| 51010 | Order size too small | Check minimum order size for the instrument |
| 50026 | Rate limit exceeded | Implement exponential backoff, reduce request frequency |
Rate limits on OKX are per-endpoint and per-API-key. Most trading endpoints allow 60 requests per 2 seconds, while market data endpoints are more generous. If you're running multiple strategies on one key, consider splitting them across separate API keys to avoid rate limit collisions. Platforms like Binance and Bybit have similar per-endpoint rate limiting, so this discipline transfers across exchanges.
For real-time data without polling, use OKX's WebSocket API. The public channel gives you orderbook updates, trades, and candlestick data. The private channel streams your order updates and position changes. This is how platforms like VoiceOfChain ingest live market data at scale — WebSockets eliminate the latency and overhead of repeated REST calls.
Let's tie it all together with a practical workflow: a script that monitors BTC price on OKX and places a buy order when the price drops below a threshold. This is a simplified version of what real OKX API trading bots do in production.
import time
import json
def get_ticker(inst_id):
"""Fetch current price — public endpoint, no auth required."""
endpoint = f'/api/v5/market/ticker?instId={inst_id}'
url = BASE_URL + endpoint
resp = requests.get(url)
data = resp.json()
if data['code'] == '0':
return float(data['data'][0]['last'])
return None
def simple_dip_buyer(inst_id, threshold, buy_size, check_interval=30):
print(f'Monitoring {inst_id}, buy threshold: ${threshold:,.0f}')
while True:
try:
price = get_ticker(inst_id)
if price is None:
print('Failed to fetch price, retrying...')
time.sleep(check_interval)
continue
print(f'{inst_id}: ${price:,.2f}')
if price <= threshold:
print(f'Price below threshold! Placing market buy...')
body = json.dumps({
'instId': inst_id,
'tdMode': 'cash',
'side': 'buy',
'ordType': 'market',
'sz': str(buy_size)
})
result = okx_request('POST', '/api/v5/trade/order', body)
if result['code'] == '0':
print(f"Bought! Order ID: {result['data'][0]['ordId']}")
break
else:
print(f"Order error: {result['data'][0].get('sMsg')}")
time.sleep(check_interval)
except requests.exceptions.RequestException as e:
print(f'Network error: {e}')
time.sleep(check_interval * 2)
# Buy 0.001 BTC if price drops below $58,000
simple_dip_buyer('BTC-USDT', threshold=58000, buy_size='0.001')
This is intentionally simple. A production bot would add position tracking, multiple order types, proper logging, and integrate with a signal source. But it demonstrates the core OKX API Python pattern: fetch data, make decisions, execute trades, handle errors.
The OKX API is one of the better-designed exchange APIs in the crypto space. The unified v5 architecture, clear documentation, and consistent endpoint patterns make it a solid choice for automated trading — whether you're running a simple DCA script or a full market-making operation. Start with the demo environment, get comfortable with authentication and order placement, then scale up to more complex strategies as your confidence grows.