◈   ⌘ api · Intermediate

Coinbase API Limits: Everything Traders Need to Know

A practical guide to Coinbase API rate limits, restrictions, and daily sending limits — with Python code examples for authentication, error handling, and staying within bounds.

Uncle Solieditor · voc · 14.03.2026 ·views 95
◈   Contents
  1. → What Are Coinbase API Rate Limits?
  2. → Coinbase Advanced API Rate Limits in Detail
  3. → Setting Up Coinbase Advanced API Authentication
  4. → Fetching Market Data and Placing Orders
  5. → Handling 429 Errors with Exponential Backoff
  6. → Coinbase Sending Limits and Account Restrictions
  7. → Coinbase API Limits vs Binance, Bybit, and OKX
  8. → Frequently Asked Questions
  9. → Building Within the Limits

If you've ever built a trading bot on Coinbase and suddenly started getting 429 errors at 2 AM, you already know why understanding Coinbase API limits matters. Rate limits aren't bureaucratic annoyances — they're a load-balancing mechanism, and knowing exactly where the ceilings are is what separates bots that run for months from bots that crash on launch day. This guide breaks down the current Coinbase API restrictions, the differences between public and private endpoint limits, how Coinbase Advanced API rate limits compare to other exchanges like Binance and OKX, and how to write defensive code that handles them gracefully.

What Are Coinbase API Rate Limits?

Coinbase API rate limits define how many requests your application can make to the Coinbase REST API within a given time window. Exceed those limits and the API returns HTTP 429 — Too Many Requests — along with a Retry-After header telling you how long to back off. These limits exist at multiple levels: per endpoint, per API key, and sometimes per IP. The Coinbase Advanced API (the successor to Coinbase Pro) organizes limits primarily around request weight and endpoint categories rather than a single global ceiling.

Coinbase Advanced API Rate Limits in Detail

The Coinbase Advanced Trade API replaced Coinbase Pro in 2023 and brought with it updated Coinbase API restrictions. Public endpoints (market data, product listings, candles) are throttled more conservatively than private ones. Private endpoints — placing orders, fetching balances, listing fills — use per-key rate limiting. Here's the current breakdown as documented in the Coinbase developer portal:

Coinbase Advanced API Rate Limits by Endpoint Type
Endpoint CategoryRate LimitAuth Required
Public market data (products, candles, tickers)10 req/secNo
Private orders, fills, portfolios15 req/secYes (API Key + HMAC)
Batch order operations5 req/secYes
WebSocket subscriptionsUp to 15 channels per connectionYes (for private channels
Coinbase limit per day (withdrawals)Depends on verification tierYes
The Coinbase REST API limits reset on a rolling per-second window, not a fixed clock boundary. A burst of 20 requests in 100ms will still trigger a 429 even if your average over the minute is within limits. Always implement token-bucket or leaky-bucket throttling on your client side, not just a simple counter.

Setting Up Coinbase Advanced API Authentication

Before you can make private API calls — and before rate limits on private endpoints apply to you — you need proper authentication. Coinbase Advanced Trade API uses HMAC-SHA256 signatures tied to your API key and secret. Here's a clean Python setup that you can drop into any bot:

import hashlib
import hmac
import time
import requests

API_KEY = "your_api_key_here"
API_SECRET = "your_api_secret_here"
BASE_URL = "https://api.coinbase.com"

def build_signature(timestamp: str, method: str, path: str, body: str = "") -> str:
    message = f"{timestamp}{method}{path}{body}"
    return hmac.new(
        API_SECRET.encode("utf-8"),
        message.encode("utf-8"),
        digestmod=hashlib.sha256
    ).hexdigest()

def coinbase_request(method: str, endpoint: str, body: str = "") -> requests.Response:
    timestamp = str(int(time.time()))
    path = f"/api/v3/brokerage{endpoint}"
    signature = build_signature(timestamp, method, path, body)

    headers = {
        "CB-ACCESS-KEY": API_KEY,
        "CB-ACCESS-SIGN": signature,
        "CB-ACCESS-TIMESTAMP": timestamp,
        "Content-Type": "application/json"
    }

    url = f"{BASE_URL}{path}"
    return requests.request(method, url, headers=headers, data=body or None)

Note that the timestamp must be within 30 seconds of Coinbase server time. Clock drift is a common cause of authentication failures that developers initially misdiagnose as API restrictions. Use an NTP-synced clock or fetch server time via the public /time endpoint before making signed requests.

Fetching Market Data and Placing Orders

With authentication in place, here's how to actually pull market data and handle the rate limit response correctly. This example fetches the best bid/ask for BTC-USD and includes basic 429 handling with a single retry:

def get_best_bid_ask(product_id: str = "BTC-USD") -> dict | None:
    response = coinbase_request("GET", f"/best_bid_ask?product_ids={product_id}")

    if response.status_code == 200:
        data = response.json()
        pricebook = data["pricebooks"][0]
        best_ask = pricebook["asks"][0]["price"]
        best_bid = pricebook["bids"][0]["price"]
        print(f"{product_id} — Ask: {best_ask} | Bid: {best_bid}")
        return data

    elif response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 1))
        print(f"[RATE LIMIT] Waiting {retry_after}s before retry...")
        time.sleep(retry_after)
        return get_best_bid_ask(product_id)

    else:
        print(f"[ERROR] {response.status_code}: {response.text}")
        return None

# Fetch live pricing
result = get_best_bid_ask("ETH-USD")
if result:
    spread = float(result["pricebooks"][0]["asks"][0]["price"]) - float(result["pricebooks"][0]["bids"][0]["price"])
    print(f"Spread: {spread:.2f}")

Handling 429 Errors with Exponential Backoff

A single retry works for occasional spikes, but production bots need something more robust. The pattern below wraps any Coinbase API call with a retry decorator that uses exponential backoff — doubling the wait time after each failed attempt. This is the same pattern used in institutional trading infrastructure and works well within Coinbase API restrictions without hammering the endpoint repeatedly:

from functools import wraps
from typing import Callable

def with_rate_limit_retry(max_retries: int = 4, base_delay: float = 1.0):
    """Decorator that retries on HTTP 429 with exponential backoff."""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_retries):
                response = func(*args, **kwargs)

                if response.status_code != 429:
                    return response

                wait = base_delay * (2 ** attempt)
                retry_header = response.headers.get("Retry-After")
                if retry_header:
                    wait = max(wait, float(retry_header))

                print(f"[429] Attempt {attempt + 1}/{max_retries}. Backing off {wait:.1f}s")
                time.sleep(wait)

            raise RuntimeError("Coinbase API rate limit: max retries exceeded")
        return wrapper
    return decorator

@with_rate_limit_retry(max_retries=4, base_delay=1.0)
def fetch_open_orders():
    return coinbase_request("GET", "/orders/historical/batch?order_status=OPEN")

# Usage
response = fetch_open_orders()
if response.status_code == 200:
    orders = response.json().get("orders", [])
    print(f"Open orders: {len(orders)}")
Pair this retry decorator with a client-side token bucket that proactively limits outgoing requests to 12/sec (giving 3 req/sec headroom below the 15/sec private limit). Reactive retry after 429 is the safety net — proactive throttling is what keeps you from hitting it in the first place.

Coinbase Sending Limits and Account Restrictions

Beyond request frequency, Coinbase API restrictions also cover how much value you can move per day. Coinbase limit per day for withdrawals and sends depends on your account verification level. These are separate from rate limits and apply regardless of whether you're using the API or the web interface:

When building automated withdrawal or rebalancing bots, always fetch your current limits via the /accounts endpoint before queuing large moves. A withdrawal that exceeds your daily limit will be rejected at the API level with a 400 error and a descriptive message in the response body — not a 429, which makes it easy to confuse with other errors if you're not parsing response bodies carefully.

Coinbase API Limits vs Binance, Bybit, and OKX

If you're running multi-exchange strategies — say, cross-listing arbitrage between Coinbase and Binance, or hedging a spot position on OKX — understanding how Coinbase API rate limits compare to other venues matters for designing a unified request scheduler. Binance uses a weight-based system where each endpoint consumes a different number of 'weight points' per minute (default 1200/min). Bybit allocates limits per endpoint category. OKX throttles market data at 20 requests per 2 seconds. Here's a side-by-side:

API Rate Limits Across Major Exchanges
ExchangePublic EndpointsPrivate EndpointsLimit Model
Coinbase Advanced10 req/sec15 req/secPer-second rolling window
Binance1200 weight/min (~20 req/sec)1200 weight/min (weighted)Weight-based per minute
Bybit120 req/min public600 req/min privatePer-minute buckets
OKX20 req/2sec (market data)60 req/2sec (trading)Per-2-second window

Platforms like Bybit and OKX tend to be more generous on private endpoint limits for active traders, which is why high-frequency market makers often treat Coinbase as a pricing reference while executing on venues with looser Coinbase Advanced API rate limits equivalents. For signals-driven trading — where you're reacting to real-time alerts from a service like VoiceOfChain rather than constantly polling — Coinbase's limits are more than adequate. VoiceOfChain delivers pre-processed signals, so your bot only touches the API when there's an actual trade trigger, not every tick.

Frequently Asked Questions

What happens when I exceed Coinbase API rate limits?
Coinbase returns HTTP 429 Too Many Requests with a Retry-After header indicating how many seconds to wait. Your API key is not banned — the limit resets on a rolling window. Always check the Retry-After header value rather than hardcoding a fixed sleep duration.
Are Coinbase API restrictions the same for all account types?
No. Verified individual accounts and institutional accounts have different private endpoint quotas. Coinbase Prime users get significantly higher rate limits and dedicated API infrastructure. If your bot consistently hits limits, upgrading your account tier is often the fastest solution.
What is the Coinbase limit per day for crypto withdrawals?
Daily sending limits depend on your verification level and account history. Basic accounts may have zero crypto withdrawal access, while fully verified accounts typically have $10,000–$50,000 equivalent per day. Institutional accounts have custom limits. Check your actual limits via the /accounts API endpoint before building automated withdrawal logic.
Do Coinbase REST API limits apply to WebSocket connections too?
WebSocket connections have separate limits — you can subscribe to up to 15 channels per connection, and there are limits on how many simultaneous connections your API key can maintain. For high-frequency price data, WebSocket is almost always preferable to polling the REST API, since it doesn't consume rate limit budget.
How do I check my current rate limit usage via the API?
Coinbase includes rate limit headers in every response: CB-RateLimit-Limit (your ceiling), CB-RateLimit-Remaining (requests left in the current window), and CB-RateLimit-Reset (epoch time when the window resets). Parse these headers in your request wrapper to build a live rate limit dashboard or adaptive throttle.
Can I increase my Coinbase Advanced API rate limits?
Yes. Coinbase offers higher limits for accounts on Advanced Trade with sufficient trading volume, and custom limits for institutional clients via Coinbase Prime. Contact Coinbase developer support with your use case and average request volume — they can manually increase limits for legitimate high-frequency applications.

Building Within the Limits

Coinbase API rate limits are predictable and workable once you understand the boundaries. The core rules: use HMAC authentication for private endpoints, implement exponential backoff with Retry-After header parsing, and build a client-side throttle that keeps you proactively under the 15 req/sec ceiling rather than reactively recovering from 429s. For sending limits, always query your account's current limits before scheduling large withdrawals — a 400 on a withdrawal attempt is a lot more disruptive than a 429 on a market data call. If you're integrating trading signals from a platform like VoiceOfChain, signal-driven execution naturally fits within Coinbase API restrictions since you're only calling the API when signals fire, not polling continuously. Compared to the weight-based complexity of Binance or the multi-bucket system on OKX, Coinbase's rate limit model is actually one of the simpler ones to reason about — as long as you know the numbers going in.

◈   more on this topic
◉ basics Mastering the ccxt library documentation for crypto traders ⌂ exchanges Mastering the Binance CCXT Library for Crypto Traders ⌬ bots Best Crypto Trading Bots 2025: Profitable AI-Powered Strategies