GUARDLABS
GuardLabs ยท Technical note

Binance API errors fixed: 429 rate limit, -1021 timestamp, -2015 key (Python)

Your bot ran fine in testing, then went live and started throwing -1021, 429, or -2015. Those three cover most Binance API failures. Here is what each one means and the exact fix.

-1021: Timestamp for this request is outside the recvWindow

Your server clock drifted from Binance's, so the signed request arrives "too old" and is rejected.

  • Sync the clock: on Linux sudo timedatectl set-ntp true (or run chrony/ntpd).
  • Widen the window: pass recvWindow=10000 (max 60000) on signed calls.
  • Best: let the client adjust for the time difference instead of trusting the OS clock.
import ccxt
ex = ccxt.binance({'apiKey': K, 'secret': S,
    'options': {'recvWindow': 10000, 'adjustForTimeDifference': True}})

429 / 418: Too Many Requests (rate and weight limits)

Binance limits by request weight, not by count. A tight while True polling loop burns the weight budget and you get 429; ignore it and it escalates to 418 — an IP ban lasting minutes to days.

  • Turn on the client limiter: enableRateLimit: True.
  • On 429, back off exponentially and respect the Retry-After header.
  • Stop polling prices over REST — use WebSocket streams for quotes, REST only for orders.
ex = ccxt.binance({'apiKey': K, 'secret': S, 'enableRateLimit': True})

import time
for attempt in range(6):
    try:
        data = ex.fetch_ohlcv('BTC/USDT', '1m'); break
    except ccxt.RateLimitExceeded:
        time.sleep(2 ** attempt)   # 1s, 2s, 4s, 8s...

-2015: Invalid API-key, IP, or permissions

The key reads public data fine but fails on private calls. It is almost always one of three things:

  • IP allow-list: the key is locked to an IP that is not your server's. Add the server IP or remove the restriction.
  • Permission: "Enable Spot/Futures Trading" was never ticked for that key.
  • Wrong environment: a testnet key used on live (or the reverse) — the endpoints differ.

The real fix is architecture, not patches

These errors are symptoms of polling-style code. A reliable bot separates concerns: one task streams market data over WebSocket, another sends orders over REST with rate limiting and retries, the clock offset is handled centrally, and keys are scoped and IP-locked. Patch the three above to stop the bleeding — but if they keep coming back under load, the loop itself needs rebuilding.

Need this fixed fast? I debug Python and exchange-API bot issues — rate limits, timeouts, order errors — order a fix on Kwork. Building a fault-tolerant bot from scratch? start a project on FreelanceHunt.

Published 2026-06-22 2 min read All articles EN / RU / ES
Bot keeps hitting API errors?

I debug Python and exchange-API issues (rate limits, timeouts, order errors) and build fault-tolerant trading bots from scratch.