Coinbase API Pricing: What Traders Actually Pay
A practical breakdown of Coinbase API pricing tiers, free limits, price history endpoints, and code examples to help traders build smarter tools.
A practical breakdown of Coinbase API pricing tiers, free limits, price history endpoints, and code examples to help traders build smarter tools.
If you're building a trading bot, a price alert system, or just want reliable market data without paying for Bloomberg, the Coinbase API is one of the most accessible starting points in crypto. But 'free' doesn't always mean what traders expect — there are rate limits, tiered pricing on the Advanced Trade API, and some endpoints that behave differently depending on whether you're authenticated. Here's what actually matters when you sit down to build something.
The short answer: yes, for most read-only market data. Coinbase splits its API offerings into two main categories — the public market data endpoints (no authentication required, coinbase api free tier) and the Advanced Trade API (formerly Coinbase Pro API), which handles order execution and requires authentication.
For price data specifically, the public REST API lets you pull current prices, order book snapshots, and candle data without an API key. The free coinbase api price data tier is rate-limited to roughly 10 requests per second on public endpoints. For most individual traders running scripts that check prices every few seconds, this is more than enough. Where things get expensive — in time and complexity, not always in dollars — is when you need authenticated access for trading or need real-time WebSocket feeds at scale.
Coinbase does not charge per API call for market data. Costs come from trading fees on executed orders through the Advanced Trade API, not from reading prices.
The coinbase advanced api pricing model is volume-based, similar to how Binance and Bybit structure their fee schedules. Fees apply to executed trades, not to API calls. Here's the structure as of 2024:
| 30-Day Volume (USD) | Maker Fee | Taker Fee |
|---|---|---|
| < $10,000 | 0.40% | 0.60% |
| $10K – $50K | 0.25% | 0.40% |
| $50K – $100K | 0.15% | 0.25% |
| $100K – $1M | 0.10% | 0.20% |
| > $1M | 0.05% | 0.10% |
| > $15M | 0.00% | 0.05% |
Compare this to OKX, which starts makers at 0.08% from day one, or Bybit which offers 0.10% maker fees at base tier. Coinbase's starting fees are noticeably higher, which matters if you're running a high-frequency strategy. For lower-volume traders, the difference is marginal. The coinbase exchange api pricing becomes competitive only once your 30-day volume crosses $100K.
One thing to note: there's no separate pricing model for API access itself on Coinbase. You pay the same fees whether you trade through the web UI or through an automated bot. This is different from some institutional data providers who charge subscription fees purely for market data access.
The simplest use case — coinbase api get price for a specific trading pair — requires no authentication. Here's a clean Python implementation:
import requests
import json
def get_coinbase_price(product_id: str) -> dict:
"""
Fetch current price for a trading pair from Coinbase.
product_id examples: 'BTC-USD', 'ETH-USD', 'SOL-USD'
"""
url = f"https://api.coinbase.com/api/v3/brokerage/market/products/{product_id}"
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
return {
"product_id": data.get("product_id"),
"price": data.get("price"),
"price_percentage_change_24h": data.get("price_percentage_change_24h"),
"volume_24h": data.get("volume_24h"),
"status": data.get("status")
}
except requests.exceptions.Timeout:
print("Request timed out — Coinbase API may be slow")
return {}
except requests.exceptions.HTTPError as e:
print(f"HTTP error: {e.response.status_code}")
return {}
# Usage
btc_price = get_coinbase_price("BTC-USD")
print(f"BTC price: ${btc_price.get('price')}")
print(f"24h change: {btc_price.get('price_percentage_change_24h')}%")
Note that Coinbase migrated from the old v2 public API to the v3 Advanced Trade API endpoints. If you see tutorials pointing to `api.coinbase.com/v2/prices/{pair}/spot` — that still works but is considered legacy. The v3 endpoint above gives you richer data including volume and status.
The coinbase api price history endpoint returns OHLCV candles and does require authentication on v3. This is one of the more important distinctions traders miss: current spot price is public, but historical candle data needs a signed request. Here's how to set up authentication and pull historical data:
import requests
import time
import hmac
import hashlib
import os
from datetime import datetime, timedelta
API_KEY = os.environ.get("COINBASE_API_KEY")
API_SECRET = os.environ.get("COINBASE_API_SECRET")
def sign_request(method: str, path: str, body: str = "") -> dict:
"""Generate authentication headers for Coinbase Advanced Trade API."""
timestamp = str(int(time.time()))
message = timestamp + method.upper() + path + body
signature = hmac.new(
API_SECRET.encode("utf-8"),
message.encode("utf-8"),
digestmod=hashlib.sha256
).hexdigest()
return {
"CB-ACCESS-KEY": API_KEY,
"CB-ACCESS-SIGN": signature,
"CB-ACCESS-TIMESTAMP": timestamp,
"Content-Type": "application/json"
}
def get_price_history(product_id: str, granularity: str = "ONE_HOUR", days_back: int = 7) -> list:
"""
Fetch OHLCV candles for a product.
granularity options: ONE_MINUTE, FIVE_MINUTE, FIFTEEN_MINUTE,
THIRTY_MINUTE, ONE_HOUR, TWO_HOUR, SIX_HOUR, ONE_DAY
"""
end_time = int(time.time())
start_time = end_time - (days_back * 86400)
path = f"/api/v3/brokerage/market/products/{product_id}/candles"
params = {
"start": str(start_time),
"end": str(end_time),
"granularity": granularity
}
headers = sign_request("GET", path)
url = f"https://api.coinbase.com{path}"
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
response.raise_for_status()
candles = response.json().get("candles", [])
# Parse candles into readable format
parsed = []
for candle in candles:
parsed.append({
"timestamp": datetime.fromtimestamp(int(candle["start"])).isoformat(),
"open": float(candle["open"]),
"high": float(candle["high"]),
"low": float(candle["low"]),
"close": float(candle["close"]),
"volume": float(candle["volume"])
})
return parsed
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print("Authentication failed — check your API key and secret")
elif e.response.status_code == 429:
print("Rate limited — slow down your requests")
return []
# Usage
history = get_price_history("ETH-USD", granularity="ONE_HOUR", days_back=7)
for candle in history[:5]:
print(f"{candle['timestamp']} | Close: ${candle['close']:.2f} | Vol: {candle['volume']:.2f}")
Coinbase limits candle requests to 300 candles per call. For longer history (e.g., months of 1-minute data), you need to paginate by adjusting start/end timestamps across multiple requests.
Rate limits are where most developers hit their first wall. Coinbase's public endpoints allow 10 requests per second. Authenticated endpoints on the Advanced Trade API allow up to 30 requests per second with a burst allowance. These are generous compared to some alternatives — KuCoin, for example, caps unauthenticated users at 3 requests per second on some endpoints.
For real-time price monitoring across many pairs, REST polling gets inefficient fast. The better approach is WebSocket subscriptions. The Coinbase WebSocket feed at `wss://advanced-trade-ws.coinbase.com` lets you subscribe to ticker updates and receive price pushes without polling. Here's a minimal WebSocket setup:
import websocket
import json
import time
import hmac
import hashlib
API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
def on_message(ws, message):
data = json.loads(message)
if data.get("type") == "ticker":
for event in data.get("events", []):
for ticker in event.get("tickers", []):
print(f"{ticker['product_id']}: ${ticker['price']}")
def on_error(ws, error):
print(f"WebSocket error: {error}")
def on_close(ws, close_status_code, close_msg):
print("Connection closed")
def on_open(ws):
timestamp = str(int(time.time()))
channel = "ticker"
product_ids = ["BTC-USD", "ETH-USD"]
# Build signature for authenticated subscription
message = timestamp + channel + ",".join(product_ids)
signature = hmac.new(
API_SECRET.encode("utf-8"),
message.encode("utf-8"),
digestmod=hashlib.sha256
).hexdigest()
subscribe_msg = {
"type": "subscribe",
"product_ids": product_ids,
"channel": channel,
"api_key": API_KEY,
"timestamp": timestamp,
"signature": signature
}
ws.send(json.dumps(subscribe_msg))
ws = websocket.WebSocketApp(
"wss://advanced-trade-ws.coinbase.com",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever()
For platforms like VoiceOfChain that generate real-time trading signals, WebSocket feeds are essential — polling REST endpoints introduces latency that makes signal timing unreliable. If you're building anything time-sensitive, switch to WebSocket early rather than retrofitting later.
Coinbase isn't always the right choice depending on your use case. Here's how it stacks up against other major exchange APIs:
For aggregated price signals combining data from multiple exchanges, a platform like VoiceOfChain removes the need to manage multiple API integrations — it processes cross-exchange data and surfaces actionable signals so traders can act rather than engineer. But when you need raw Coinbase-specific data — for regulatory reporting, USD liquidity analysis, or US market focus — the Coinbase API is the right primary source.
The Coinbase API is genuinely accessible for traders who want to build data tools without a massive budget. Current price data is free, WebSocket feeds are reliable, and the fee structure on the Advanced Trade API is competitive once you're past $100K monthly volume. The main gotchas are: historical candle data requires authentication, rate limits need WebSocket for real-time use cases, and fee tiers start higher than Binance or OKX at lower volumes.
If you're starting a project today, use the public REST endpoints to prototype, add WebSocket for any live price monitoring, and only wire up authenticated endpoints when you actually need to trade. Combine Coinbase price data with signal platforms like VoiceOfChain to get both raw data and interpreted intelligence — that combination covers most serious trading workflows without overengineering from day one.