Binance API Documentation Futures: Complete Guide
Master Binance Futures API documentation — authentication, endpoints, code examples, and testnet setup for algorithmic traders ready to automate their strategies.
Master Binance Futures API documentation — authentication, endpoints, code examples, and testnet setup for algorithmic traders ready to automate their strategies.
If you're trading futures on Binance and still clicking buttons manually, you're leaving a lot on the table. The Binance Futures API is one of the most powerful and well-documented trading interfaces in crypto — giving you programmatic access to positions, orders, account data, and real-time market feeds. This guide walks you through everything you need to go from zero to live algorithmic futures trading.
Binance separates its API into distinct products. For futures trading, you'll primarily work with two base URLs: the USD-M Futures API (fapi.binance.com) and the COIN-M Futures API (dapi.binance.com). USD-M contracts are settled in USDT or BUSD, while COIN-M contracts settle in the underlying cryptocurrency. Most traders start with USD-M since the collateral is stable.
The binance api documentation futures covers three major interaction types: REST API for order placement and account queries, WebSocket Streams for real-time market data and user data events, and the User Data Stream which delivers order updates and position changes without polling.
Always start development on the Binance futures testnet. It mirrors the production API exactly but uses play money. Mistakes on testnet cost nothing — mistakes on mainnet can cost your entire margin.
Before touching a single endpoint, you need API keys. On Binance, navigate to Account → API Management, create a new key, and enable Futures trading permissions. Do NOT enable withdrawals unless your use case specifically requires it — that's an unnecessary attack surface.
Binance Futures uses HMAC-SHA256 signing for authenticated requests. Every signed request requires a timestamp parameter and a signature generated from your query string using your secret key. Here's the standard Python setup:
import hmac
import hashlib
import time
import requests
from urllib.parse import urlencode
API_KEY = 'your_api_key_here'
SECRET_KEY = 'your_secret_key_here'
BASE_URL = 'https://fapi.binance.com'
def get_signature(params: dict, secret: str) -> str:
query_string = urlencode(params)
signature = hmac.new(
secret.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def get_account_info():
endpoint = '/fapi/v2/account'
params = {
'timestamp': int(time.time() * 1000),
'recvWindow': 5000
}
params['signature'] = get_signature(params, SECRET_KEY)
headers = {'X-MBX-APIKEY': API_KEY}
response = requests.get(
BASE_URL + endpoint,
params=params,
headers=headers
)
response.raise_for_status()
return response.json()
account = get_account_info()
print(f"Total wallet balance: {account['totalWalletBalance']} USDT")
print(f"Available balance: {account['availableBalance']} USDT")
Compare this with how platforms like Bybit and OKX handle authentication — Bybit uses a similar HMAC approach but requires a different header format (api-key, sign, timestamp as separate headers), while OKX adds a passphrase layer. Binance's approach is arguably the most widely documented, which is why so many open-source bots start with Binance Futures API docs as their reference.
The binance futures api docs cover dozens of endpoints, but in practice most trading systems use a core set. Here are the critical ones:
| Endpoint | Method | Purpose | Auth Required |
|---|---|---|---|
| fapi/v1/exchangeInfo | GET | All symbols, filters, contract specs | No |
| fapi/v1/depth | GET | Order book snapshot | No |
| fapi/v1/klines | GET | OHLCV candlestick data | No |
| fapi/v2/account | GET | Account balances and positions | Yes |
| fapi/v1/order | POST | Place new order | Yes |
| fapi/v1/order | DELETE | Cancel existing order | Yes |
| fapi/v1/positionRisk | GET | Open positions | Yes |
| fapi/v1/leverage | POST | Change leverage for symbol | Yes |
Placing a futures order programmatically is straightforward once authentication is working. Here's a complete example that places a market buy order with basic error handling:
import hmac
import hashlib
import time
import requests
from urllib.parse import urlencode
API_KEY = 'your_api_key_here'
SECRET_KEY = 'your_secret_key_here'
BASE_URL = 'https://fapi.binance.com'
def sign_request(params):
query_string = urlencode(params)
sig = hmac.new(SECRET_KEY.encode(), query_string.encode(), hashlib.sha256).hexdigest()
params['signature'] = sig
return params
def place_market_order(symbol: str, side: str, quantity: float):
"""
side: 'BUY' or 'SELL'
quantity: number of contracts
"""
endpoint = '/fapi/v1/order'
params = {
'symbol': symbol,
'side': side,
'type': 'MARKET',
'quantity': quantity,
'timestamp': int(time.time() * 1000)
}
params = sign_request(params)
headers = {'X-MBX-APIKEY': API_KEY}
try:
response = requests.post(
BASE_URL + endpoint,
params=params,
headers=headers,
timeout=10
)
data = response.json()
if response.status_code != 200:
error_code = data.get('code', 'unknown')
error_msg = data.get('msg', 'unknown error')
raise Exception(f'Order failed [{error_code}]: {error_msg}')
print(f"Order placed: {data['orderId']}")
print(f"Status: {data['status']}")
print(f"Avg price: {data['avgPrice']}")
return data
except requests.exceptions.Timeout:
print('Request timed out — check order status before retrying')
raise
except requests.exceptions.RequestException as e:
print(f'Network error: {e}')
raise
# Example: buy 0.01 BTC perpetual contract
place_market_order('BTCUSDT', 'BUY', 0.01)
Binance error code -2010 means 'insufficient balance' and -1121 means invalid symbol. Keep a local map of common error codes so your bot can handle them gracefully instead of crashing.
The binance futures testnet api documentation is almost identical to production — same endpoints, same authentication mechanism, different base URL and API keys. To use testnet, register at testnet.binancefuture.com (separate account from your main Binance account) and generate testnet API keys from that portal.
The only real difference is the base URL. Swap fapi.binance.com for testnet.binancefuture.com and your existing code works immediately. This makes testnet integration trivial — just use an environment variable to switch between environments:
import os
ENVIRONMENT = os.getenv('TRADING_ENV', 'testnet') # default to safe
if ENVIRONMENT == 'production':
BASE_URL = 'https://fapi.binance.com'
API_KEY = os.getenv('BINANCE_PROD_API_KEY')
SECRET_KEY = os.getenv('BINANCE_PROD_SECRET_KEY')
else:
BASE_URL = 'https://testnet.binancefuture.com'
API_KEY = os.getenv('BINANCE_TESTNET_API_KEY')
SECRET_KEY = os.getenv('BINANCE_TESTNET_SECRET_KEY')
print(f'Running in {ENVIRONMENT.upper()} mode')
print(f'API base: {BASE_URL}')
This pattern is standard practice in professional algo trading. Even shops trading millions of dollars on Binance, Bybit, and Bitget maintain separate testnet environments and run every new strategy change through paper trading before touching live capital. Gate.io and KuCoin have similar testnet setups for their futures products, but Binance's testnet is the most feature-complete.
REST API polling has hard limits — Binance enforces weight-based rate limiting, and polling a 1-second kline endpoint 10 times per second will get you banned quickly. For real-time data, use WebSocket streams instead.
The mark price stream, best bid/ask stream, and user data stream (for position and order updates) are the three most critical for a futures trading bot. Here's a clean WebSocket setup for subscribing to mark price updates:
import asyncio
import json
import websockets
STREAM_URL = 'wss://fstream.binance.com/stream'
async def subscribe_mark_price(symbols: list):
streams = [f"{s.lower()}@markPrice@1s" for s in symbols]
stream_path = '/'.join(streams)
url = f"{STREAM_URL}?streams={stream_path}"
async with websockets.connect(url) as ws:
print(f"Connected to {len(streams)} mark price streams")
while True:
try:
message = await asyncio.wait_for(ws.recv(), timeout=30)
data = json.loads(message)
stream_data = data.get('data', {})
symbol = stream_data.get('s')
mark_price = float(stream_data.get('p', 0))
funding_rate = float(stream_data.get('r', 0))
print(f"{symbol}: Mark={mark_price:.2f}, Funding={funding_rate:.6f}")
except asyncio.TimeoutError:
# Send ping to keep connection alive
await ws.ping()
except websockets.exceptions.ConnectionClosed:
print('WebSocket disconnected — reconnecting...')
break
# Subscribe to BTC and ETH mark prices
asyncio.run(subscribe_mark_price(['BTCUSDT', 'ETHUSDT']))
WebSocket connections drop. Always implement reconnection logic with exponential backoff. A bot that crashes on a disconnection at 3am when a big move happens is worse than no bot at all.
The Binance Futures API is dense but well-structured once you understand the authentication pattern and the REST/WebSocket split. The testnet removes all risk from the learning curve — there's no excuse not to run every new strategy there first. Whether you're building a simple position monitor or a full algorithmic trading system, the foundation is the same: solid auth, disciplined error handling, and WebSocket-driven real-time data instead of polling.
Pair your API work with a reliable signal source. Platforms like VoiceOfChain give you the market intelligence layer — real-time signals across crypto markets — while your Binance Futures API integration handles the execution side. That combination, signal quality plus fast reliable execution, is what separates consistently profitable algo traders from the ones who keep debugging at 2am.