Of course! Here is a comprehensive guide on how to use the OKX (formerly OKCoin) API with Python. We'll cover everything from setup to making your first API call, and then dive into practical examples for trading.

Important Note: OKCoin vs. OKX
OKCoin rebranded to OKX. The API endpoints and authentication methods are largely the same, but it's crucial to use the official OKX documentation. All examples below will use the current OKX API.
Prerequisites
Before you start, you need:
- A Python Environment: Python 3.6+ is recommended.
- An OKX Account: You need to sign up for an account on the OKX website.
- API Keys:
- Log in to your OKX account.
- Go to Account -> API Management.
- Create a new API key. You will be given:
- API Key: Your public identifier.
- Secret Key: Your private key for signing requests. Never share this!
- Passphrase: An extra layer of security you set when creating the key. Never share this!
- For this guide, you can start with "Read & Trade" permissions. For trading, you'll need these permissions.
Setup Your Python Environment
First, you need to install the requests library, which is the standard for making HTTP requests in Python.
pip install requests
Authentication (The Most Important Part)
The OKX API requires you to sign your requests using your API Key, Secret Key, and Passphrase. The process involves creating a timestamp and a signature string.

Here is a reusable Python class to handle authentication. This is the recommended approach to keep your code clean and secure.
import base64
import hmac
import json
import time
import requests
class OKXAuth:
def __init__(self, api_key, secret_key, passphrase):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
def sign(self, timestamp, method, request_path, body=''):
# Create the message string
message = timestamp + method + request_path + body
# Create the signature
signature = base64.b64encode(
hmac.new(self.secret_key.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256)
.digest()
)
return signature.decode('utf-8')
# Example usage of the class (we'll use this in the next section)
# Replace with your actual keys
API_KEY = 'YOUR_API_KEY'
SECRET_KEY = 'YOUR_SECRET_KEY'
PASSPHRASE = 'YOUR_PASSPHRASE'
# Note: You need to import hashlib for the sign method to work
import hashlib
How it works:
- Timestamp: A UTC timestamp in ISO 8601 format (e.g.,
2025-01-01T00:00:00.000Z) is required for every request. - Message: The API concatenates the
timestamp,HTTP method(GET, POST, etc.),request path(e.g.,/api/v5/account/balance), and therequest body(if any) into a single string. - Signature: This message string is then signed using an HMAC-SHA256 algorithm with your
Secret Key. The resulting signature is Base64 encoded and sent as a header in your request.
Making Your First API Call (Public Data)
Let's start with a public endpoint that doesn't require authentication, like getting the ticker for BTC/USDT.
import requests
import json
# The base URL for the OKX API
BASE_URL = 'https://www.okx.com'
def get_public_data():
# Define the endpoint
endpoint = '/api/v5/market/ticker'
# Define the parameters for the request
params = {
'instId': 'BTC-USDT' # Instrument ID
}
try:
# Make the GET request
response = requests.get(f"{BASE_URL}{endpoint}", params=params)
# Check for HTTP errors
response.raise_for_status()
# Parse the JSON response
data = response.json()
# Print the result in a readable format
print(json.dumps(data, indent=2))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
if __name__ == '__main__':
get_public_data()
Expected Output:

{
"code": "0",
"msg": "",
"data": [
{
"instId": "BTC-USDT",
"last": "$42,150.5",
"lastSz": "0.0123",
"askPx": "$42,151.5",
"askSz": "0.456",
"bidPx": "$42,150.0",
"bidSz": "1.234",
"open24h": "$41,800.0",
"high24h": "$42,500.0",
"low24h": "$41,500.0",
"vol24h": "12345.678",
"volCcy24h": "520251498.123",
"ts": "1673891234567"
}
]
}
Making a Private API Call (e.g., Get Account Balance)
Now, let's use our OKXAuth class to make a private request to get your account balance.
import requests
import json
import time
import base64
import hmac
import hashlib
# --- Paste the OKXAuth class from section 3 here ---
class OKXAuth:
def __init__(self, api_key, secret_key, passphrase):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
def sign(self, timestamp, method, request_path, body=''):
message = timestamp + method + request_path + body
signature = base64.b64encode(
hmac.new(self.secret_key.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256)
.digest()
)
return signature.decode('utf-8')
# --- Configuration ---
BASE_URL = 'https://www.okx.com'
API_KEY = 'YOUR_API_KEY'
SECRET_KEY = 'YOUR_SECRET_KEY'
PASSPHRASE = 'YOUR_PASSPHRASE'
def get_account_balance():
# Initialize the authenticator
auth = OKXAuth(API_KEY, SECRET_KEY, PASSPHRASE)
# Define the private endpoint
endpoint = '/api/v5/account/balance'
# Generate timestamp
timestamp = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
# Define request details
method = 'GET'
request_path = endpoint
body = '' # No body for a GET request
# Generate the signature
signature = auth.sign(timestamp, method, request_path, body)
# Set the required headers
headers = {
'OK-ACCESS-KEY': API_KEY,
'OK-ACCESS-SIGN': signature,
'OK-ACCESS-TIMESTAMP': timestamp,
'OK-ACCESS-PASSPHRASE': PASSPHRASE,
'Content-Type': 'application/json'
}
try:
# Make the GET request
response = requests.get(f"{BASE_URL}{endpoint}", headers=headers)
# Check for HTTP errors
response.raise_for_status()
# Parse the JSON response
data = response.json()
# Print the result
print(json.dumps(data, indent=2))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
# Print response text for debugging if it's not a connection error
if hasattr(e, 'response') and e.response is not None:
print(f"Response body: {e.response.text}")
if __name__ == '__main__':
# Make sure you have 'Read & Trade' permissions for this endpoint
get_account_balance()
Expected Output (if you have funds):
{
"code": "0",
"msg": "",
"data": [
{
"details": [
{
"ccy": "BTC",
"bal": "1.234567",
"availBal": "1.234567",
"frozenBal": "0",
"ordFrozen": "0",
"feeFrozen": "0",
"iu": "0",
"it": "0"
},
{
"ccy": "USDT",
"bal": "12345.6789",
"availBal": "12345.6789",
"frozenBal": "0",
"ordFrozen": "0",
"feeFrozen": "0",
"iu": "0",
"it": "0"
}
],
"info": "account info"
}
]
}
Practical Example: Placing a Limit Order
This is a more complex example that shows how to place a trade. This requires the "Trade" permission on your API key.
import requests
import json
import time
import base64
import hmac
import hashlib
# --- Paste the OKXAuth class from section 3 here ---
class OKXAuth:
def __init__(self, api_key, secret_key, passphrase):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
def sign(self, timestamp, method, request_path, body=''):
message = timestamp + method + request_path + body
signature = base64.b64encode(
hmac.new(self.secret_key.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256)
.digest()
)
return signature.decode('utf-8')
# --- Configuration ---
BASE_URL = 'https://www.okx.com'
API_KEY = 'YOUR_API_KEY'
SECRET_KEY = 'YOUR_SECRET_KEY'
PASSPHRASE = 'YOUR_PASSPHRASE'
def place_limit_order():
auth = OKXAuth(API_KEY, SECRET_KEY, PASSPHRASE)
# Define the trading endpoint
endpoint = '/api/v5/trade/order'
# --- Order Details ---
# IMPORTANT: Replace these with your desired order parameters
instrument_id = 'BTC-USDT'
side = 'buy' # 'buy' or 'sell'
order_type = 'limit' # 'limit' or 'market'
price = '42000.0' # The price at which you want to buy/sell
size = '0.001' # The amount of the asset you want to trade
# Construct the request body as a JSON string
body = json.dumps({
"instId": instrument_id,
"tdMode": "cash", # 'cash' for spot trading, 'cross' or 'isolated' for futures
"side": side,
"ordType": order_type,
"px": price,
"sz": size
})
# Generate timestamp
timestamp = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
# Define request details
method = 'POST'
request_path = endpoint
# Generate the signature
signature = auth.sign(timestamp, method, request_path, body)
# Set the required headers
headers = {
'OK-ACCESS-KEY': API_KEY,
'OK-ACCESS-SIGN': signature,
'OK-ACCESS-TIMESTAMP': timestamp,
'OK-ACCESS-PASSPHRASE': PASSPHRASE,
'Content-Type': 'application/json'
}
try:
# Make the POST request
response = requests.post(f"{BASE_URL}{endpoint}", headers=headers, data=body)
# Check for HTTP errors
response.raise_for_status()
# Parse the JSON response
data = response.json()
# Print the result
print(json.dumps(data, indent=2))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Response body: {e.response.text}")
if __name__ == '__main__':
# WARNING: This will execute a real trade if you have sufficient funds.
# Ensure your parameters are correct before running.
place_limit_order()
Expected Output (if successful):
{
"code": "0",
"msg": "",
"data": [
{
"sCode": "0",
"sMsg": "",
"ordId": "4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"clOrdId": "",
"tag": "",
"state": "live",
"instId": "BTC-USDT",
"tdMode": "cash",
"ordType": "limit",
"side": "buy",
"posSide": "net",
"ccy": "",
"px": "42000.0",
"sz": "0.001",
"pnl": "0",
"feeCcy": "",
"fee": "",
"filledSz": "0",
"remSz": "0.001",
"accFillSz": "0",
"source": "api",
"rebateCcy": "",
"rebate": "",
"cancelling": "0",
"quickMgnType": "",
"algoClOrdId": "",
"algoId": "",
"category": "1",
"uTime": "1673891234567",
"cTime": "1673891234567"
}
]
}
Official OKX Python SDK
For more serious applications, using the official OKX Python SDK is highly recommended. It handles all the authentication, request signing, and parsing for you, making your code much simpler and less error-prone.
Installation:
pip install okx
Example using the SDK (Get Balance):
from okx import OkxClient
# --- Configuration ---
API_KEY = 'YOUR_API_KEY'
SECRET_KEY = 'YOUR_SECRET_KEY'
PASSPHRASE = 'YOUR_PASSPHRASE'
# Use '0' for Demo/Sandbox mode, '1' for Live trading
FLAG = '0'
# Initialize the client
client = OkxClient(
api_key=API_KEY,
secret_key=SECRET_KEY,
passphrase=PASSPHRASE,
flag=FLAG # Use '0' for testnet, '1' for mainnet
)
# Get account balance
result = client.get_account_balance()
# The SDK returns a dictionary, so you can access it directly
print(json.dumps(result, indent=2))
The SDK abstracts away all the complexity of headers and signing, allowing you to focus on your trading logic. It's the best choice for building a robust trading bot.
