Does Binance Have an API? Complete Guide for Traders
Yes, Binance has a powerful free API. Learn how to set it up, authenticate, and start pulling market data or automating trades in minutes.
Yes, Binance has a powerful free API. Learn how to set it up, authenticate, and start pulling market data or automating trades in minutes.
Binance has one of the most capable and well-documented APIs in the crypto industry — and yes, it's free to use. Whether you're pulling historical candles, streaming live order book data, or automating your trading strategy, the Binance API handles all of it. Compared to what's available from traditional finance (Yahoo Finance's API was shut down, and Google Finance has no official API at all), crypto exchanges like Binance, Bybit, and OKX are leagues ahead in giving developers real access to real data.
The Binance API is a set of HTTP endpoints and WebSocket streams that let you interact with Binance programmatically. It breaks down into three main areas: the REST API for request-response operations (fetching prices, placing orders, checking balances), WebSocket streams for real-time data without polling, and the User Data Stream for account-level events like order fills and balance updates.
The Binance API is completely free. You only need an account and API keys — there's no subscription or tier system for basic access. Rate limits apply, but for most individual traders and developers they're generous enough that you'll never hit them.
The Binance API is free in the sense that Binance charges no fee to use it. You pay standard trading fees when you execute orders through the API — same as clicking buttons in the UI — but data access, authentication, and connectivity are all free. This puts Binance in a very different category from legacy financial data providers. Yahoo Finance had a semi-official API that was quietly shut down years ago and is now only accessible through scraping or third-party wrappers. Google Finance has never had an official public API. Meanwhile, Binance, Bybit, OKX, and KuCoin all offer full REST and WebSocket access at no cost.
| Platform | Free API? | Real-Time Data | Order Execution | WebSocket |
|---|---|---|---|---|
| Binance | Yes | Yes | Yes | Yes |
| Bybit | Yes | Yes | Yes | Yes |
| OKX | Yes | Yes | Yes | Yes |
| Yahoo Finance | No (deprecated) | No | No | No |
| Google Finance | No official API | No | No | No |
| Coinbase Advanced | Yes | Yes | Yes | Yes |
Rate limits on Binance are weight-based. Each endpoint has a request weight, and you get 1200 weight per minute on the REST API by default. Lighter endpoints (like a single ticker price) cost 1 weight. Heavy endpoints (like full order book snapshots) cost more. If you're building something intensive, you can apply for elevated limits through Binance's institutional program, but for most bots and data tools, default limits are fine.
Before writing a single line of code, you need API keys. Log into Binance, go to Account > API Management, and create a new key. You'll get an API Key (public) and a Secret Key (never share this). During setup, configure the permissions you need — read-only for data, trading permissions for order execution. Always restrict the key to specific IP addresses if you're running a bot on a server. Never enable withdrawal permissions unless your use case absolutely requires it.
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://api.binance.com'
def get_signature(params: dict, secret: str) -> str:
query_string = urlencode(params)
return hmac.new(
secret.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
def get_account_info() -> dict:
endpoint = '/api/v3/account'
params = {'timestamp': int(time.time() * 1000)}
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()
if __name__ == '__main__':
account = get_account_info()
balances = [b for b in account['balances'] if float(b['free']) > 0]
for asset in balances:
print(f"{asset['asset']}: {asset['free']} free, {asset['locked']} locked")
Public endpoints on Binance don't require authentication — no API key needed. This is perfect for market data tools, dashboards, and signal platforms. You can pull the current price of any pair, full order book depth, recent trades, and OHLCV (candlestick) data going back years. Platforms like VoiceOfChain use this kind of real-time data feed to generate trading signals — pulling live price action and volume data from exchanges like Binance and Bybit, then surfacing actionable insights to traders.
import requests
BASE_URL = 'https://api.binance.com'
def get_price(symbol: str) -> float:
"""Get current price for a symbol like BTCUSDT."""
endpoint = '/api/v3/ticker/price'
response = requests.get(BASE_URL + endpoint, params={'symbol': symbol})
response.raise_for_status()
return float(response.json()['price'])
def get_klines(symbol: str, interval: str = '1h', limit: int = 100) -> list:
"""
Fetch OHLCV candles.
interval options: 1m, 5m, 15m, 1h, 4h, 1d, 1w
"""
endpoint = '/api/v3/klines'
params = {'symbol': symbol, 'interval': interval, 'limit': limit}
response = requests.get(BASE_URL + endpoint, params=params)
response.raise_for_status()
candles = []
for k in response.json():
candles.append({
'open_time': k[0],
'open': float(k[1]),
'high': float(k[2]),
'low': float(k[3]),
'close': float(k[4]),
'volume': float(k[5]),
})
return candles
def get_order_book(symbol: str, depth: int = 10) -> dict:
"""Get order book bids and asks."""
endpoint = '/api/v3/depth'
response = requests.get(BASE_URL + endpoint, params={'symbol': symbol, 'limit': depth})
response.raise_for_status()
data = response.json()
return {
'bids': [(float(p), float(q)) for p, q in data['bids']],
'asks': [(float(p), float(q)) for p, q in data['asks']]
}
if __name__ == '__main__':
price = get_price('BTCUSDT')
print(f'BTC Price: ${price:,.2f}')
candles = get_klines('ETHUSDT', interval='4h', limit=5)
for c in candles:
print(f"Open: {c['open']} | Close: {c['close']} | Volume: {c['volume']:.2f}")
book = get_order_book('SOLUSDT')
print(f"Best bid: {book['bids'][0][0]} | Best ask: {book['asks'][0][0]}")
Order placement requires a signed request. The key difference from data endpoints is that every order request must include a timestamp and a HMAC-SHA256 signature using your secret key. Binance will reject unsigned or incorrectly signed requests with a -1022 error. Build error handling from the start — API errors are common and expected, especially during volatile markets when rate limits can temporarily tighten.
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://api.binance.com'
class BinanceAPIError(Exception):
def __init__(self, code, message):
self.code = code
self.message = message
super().__init__(f'Binance API Error {code}: {message}')
def signed_request(method: str, endpoint: str, params: dict) -> dict:
params['timestamp'] = int(time.time() * 1000)
query_string = urlencode(params)
signature = hmac.new(
SECRET_KEY.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
params['signature'] = signature
headers = {'X-MBX-APIKEY': API_KEY}
url = BASE_URL + endpoint
if method == 'POST':
response = requests.post(url, params=params, headers=headers)
elif method == 'DELETE':
response = requests.delete(url, params=params, headers=headers)
else:
response = requests.get(url, params=params, headers=headers)
data = response.json()
if 'code' in data and data['code'] != 200:
raise BinanceAPIError(data['code'], data.get('msg', 'Unknown error'))
return data
def place_market_order(symbol: str, side: str, quantity: float) -> dict:
"""
Place a market order.
side: 'BUY' or 'SELL'
"""
return signed_request('POST', '/api/v3/order', {
'symbol': symbol,
'side': side,
'type': 'MARKET',
'quantity': quantity
})
def place_limit_order(symbol: str, side: str, quantity: float, price: float) -> dict:
return signed_request('POST', '/api/v3/order', {
'symbol': symbol,
'side': side,
'type': 'LIMIT',
'timeInForce': 'GTC',
'quantity': quantity,
'price': price
})
if __name__ == '__main__':
try:
# Example: buy 0.001 BTC at market price
order = place_market_order('BTCUSDT', 'BUY', 0.001)
print(f"Order filled: {order['orderId']} | Status: {order['status']}")
except BinanceAPIError as e:
print(f"Order failed: {e}")
# Common codes:
# -1121: invalid symbol
# -2010: insufficient balance
# -1013: quantity below minimum
except requests.RequestException as e:
print(f"Network error: {e}")
Always test order placement on Binance Testnet first (testnet.binance.vision) before running against your real account. The testnet uses the same API structure but with fake funds — a mistake there costs nothing.
Binance has one of the best developer APIs in the crypto space — free, well-documented, and genuinely capable. Whether you're building a data tool, a signal aggregator, or a full automated trading bot, the infrastructure is already there waiting for you. Compared to the dead-end of Yahoo Finance's deprecated API or Google Finance's non-existent one, working with Binance (or similar platforms like Bybit, OKX, Gate.io, and Bitget, which all offer comparable APIs) gives you direct access to real markets in real time. Tools like VoiceOfChain leverage exactly this kind of API access to surface real-time signals from live exchange data — the same raw data is available to you the moment you generate your first API key.