◈   ⌘ api · Intermediate

Binance API Signature Mismatch: Complete Fix Guide

Everything you need to debug and fix Binance API signature mismatch errors — from HMAC authentication basics to timestamp sync and working code examples in Python and JS.

Uncle Solieditor · voc · 05.05.2026 ·views 20
◈   Contents
  1. → How Binance API Authentication Actually Works
  2. → Why the Signature Mismatch Error Happens
  3. → Diagnosing Timestamp Drift First
  4. → Correct Signature Implementation in JavaScript
  5. → Preventing Signature Errors in Production Bots
  6. → Frequently Asked Questions
  7. → Conclusion

You set up your trading bot, double-checked your API keys, and hit run — then Binance throws back a cryptic -1022 error: "Signature for this request is not valid." If this sounds familiar, you're not alone. API signature mismatch is one of the most common roadblocks for traders building automated strategies on Binance. The good news: it's almost always fixable in under ten minutes once you understand what's actually being signed and why it goes wrong.

How Binance API Authentication Actually Works

Binance uses HMAC-SHA256 to verify that requests come from you and haven't been tampered with in transit. Every request touching account data — orders, balances, trade history — requires a signature. The process: take all your request parameters, serialize them into a query string, then compute an HMAC-SHA256 hash using your API secret as the key. That hash gets appended to your request as the 'signature' parameter.

Your API key goes in the request header (X-MBX-APIKEY), while the signature goes in the query string or request body. Binance recomputes the signature server-side using the same parameters and your stored secret. If the two don't match, you get -1022. This means any difference — a single character, an extra space, a different parameter order — will cause authentication to fail.

import hmac
import hashlib
import time
import requests
from urllib.parse import urlencode

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

def create_signature(params: dict) -> str:
    query_string = urlencode(params)
    return hmac.new(
        API_SECRET.encode("utf-8"),
        query_string.encode("utf-8"),
        hashlib.sha256
    ).hexdigest()

def get_account_info():
    params = {
        "timestamp": int(time.time() * 1000),
        "recvWindow": 5000
    }
    params["signature"] = create_signature(params)

    headers = {"X-MBX-APIKEY": API_KEY}
    response = requests.get(
        f"{BASE_URL}/api/v3/account",
        params=params,
        headers=headers
    )
    data = response.json()

    if "code" in data:
        print(f"API Error {data['code']}: {data['msg']}")
        return None
    return data

result = get_account_info()
print(result)

Why the Signature Mismatch Error Happens

The root causes fall into a handful of categories. Once you know them, debugging becomes systematic rather than guesswork.

Binance error -1021 means your timestamp is outside the recvWindow tolerance. Error -1022 means the signature itself is wrong. These two errors have different root causes — don't confuse them when debugging.

Diagnosing Timestamp Drift First

Before touching any signature logic, always check your clock sync. This is the most overlooked cause of API authentication failures, especially on cloud servers and VMs. Binance's /api/v3/time endpoint is public and requires no authentication — it's the perfect diagnostic tool. Run this on whatever machine your bot actually runs on, not just your local dev machine.

import requests
import time

def check_time_sync():
    server_data = requests.get(
        "https://api.binance.com/api/v3/time"
    ).json()
    server_time = server_data["serverTime"]
    local_time = int(time.time() * 1000)
    drift_ms = abs(server_time - local_time)

    print(f"Server time : {server_time}")
    print(f"Local time  : {local_time}")
    print(f"Drift       : {drift_ms} ms")

    if drift_ms > 1000:
        print("WARNING: Clock drift exceeds 1000ms — signature requests will fail!")
        print("Fix: run 'sudo ntpdate -s time.nist.gov' or enable NTP sync.")
    elif drift_ms > 500:
        print("CAUTION: Drift approaching unsafe range. Monitor closely.")
    else:
        print("Clock sync OK — within acceptable range.")

    return drift_ms

drift = check_time_sync()

If your drift is over 1000ms, fix your system clock before investigating anything else. On Linux, run sudo ntpdate -s time.nist.gov or enable systemd-timesyncd. On Windows, resync through Date and Time settings. If you can't adjust the clock (some container environments restrict this), you can offset your timestamp generation by fetching server time before each request — but treat this as a last resort, since it adds latency on every authenticated call.

Correct Signature Implementation in JavaScript

Node.js bots hit a common pitfall: URLSearchParams serializes parameters differently than Python's urlencode in certain edge cases, especially with arrays and nested objects. Keep your parameter values as flat strings and numbers, and you avoid most of these issues. Here's a production-ready implementation for Binance's /api/v3/openOrders endpoint that you can adapt to any signed endpoint:

const crypto = require('crypto');
const axios = require('axios');

const API_KEY = 'your_api_key_here';
const API_SECRET = 'your_api_secret_here';
const BASE_URL = 'https://api.binance.com';

function createSignature(params) {
  const queryString = new URLSearchParams(params).toString();
  return crypto
    .createHmac('sha256', API_SECRET)
    .update(queryString)
    .digest('hex');
}

async function getOpenOrders(symbol = 'BTCUSDT') {
  const params = {
    symbol,
    timestamp: Date.now(),
    recvWindow: 5000,
  };
  params.signature = createSignature(params);

  try {
    const { data } = await axios.get(`${BASE_URL}/api/v3/openOrders`, {
      params,
      headers: { 'X-MBX-APIKEY': API_KEY },
    });
    return data;
  } catch (err) {
    const apiErr = err.response?.data;
    // -1022 = invalid signature, -1021 = timestamp out of recvWindow
    console.error('Binance API error:', apiErr || err.message);
    throw err;
  }
}

getOpenOrders('ETHUSDT')
  .then(orders => console.log(`Open orders: ${orders.length}`))
  .catch(console.error);

Notice that the signature is added to the params object after all other parameters are finalized. This is critical — if you modify any parameter after computing the signature, the signature is immediately invalidated. Build your complete parameter set first, sign it in one shot, then send the request.

Preventing Signature Errors in Production Bots

One-off fixes are fine for getting started, but production trading bots need a more systematic approach. Signature failures at 3am while a position is open aren't just annoying — they can be expensive. Whether you're running strategies on Binance, KuCoin, or Bybit, these production principles apply across all exchanges.

If you're running automated strategies and want to validate signals before execution, platforms like VoiceOfChain provide real-time trading signals with exchange-specific entry points. Having a reliable signal layer means your bot only fires API calls when there's a genuine opportunity — reducing unnecessary requests and the blast radius of any authentication issues.

Exchanges like OKX and Gate.io use similar HMAC-based authentication but have different timestamp tolerances and endpoint structures. If you're running multi-exchange bots, abstract your authentication layer so each exchange gets its own signing implementation rather than sharing a generic function that might make wrong assumptions about parameter encoding or body construction.

Frequently Asked Questions

What does Binance error code -1022 mean?
-1022 is Binance's 'Invalid signature' error, meaning the HMAC-SHA256 hash you sent doesn't match what Binance computed from your parameters. The most common causes in order are: wrong API secret, timestamp drift, and incorrect parameter encoding. Check these three things before investigating anything else.
Does the same signature problem happen on Bybit and OKX?
Yes. Bybit and OKX both use HMAC-SHA256 authentication, so the same classes of bugs apply — clock drift, wrong secret, incorrect parameter serialization. Timestamp tolerances differ: Bybit allows roughly 5 seconds of drift, while OKX is more lenient at around 30 seconds. Always check exchange-specific docs for exact limits.
What recvWindow value should I use for my trading bot?
Binance defaults to 5000ms, which is fine for most bots with stable latency. Increase to 10000ms if your server has variable network conditions. Binance caps the maximum at 60000ms and won't accept values above it — and larger windows reduce the security value of the timestamp check, so only go higher if you have a clear reason.
Why does my signature work locally but fail on my production server?
This is almost always clock drift. Cloud VMs — especially ones that have been running for months or went through a suspend/resume cycle — frequently have drifted clocks. Run the check_time_sync() function from this article on your production machine specifically. If drift exceeds 1000ms, fix your NTP configuration before investigating anything else.
Do I need a different signing method for Binance Futures vs Spot?
The HMAC-SHA256 algorithm is identical, but the base URL differs: Spot uses https://api.binance.com while Futures uses https://fapi.binance.com. Your API key also needs Futures trading permissions enabled separately in the Binance account dashboard — a missing permission looks like an auth failure but isn't a signature issue.

Conclusion

Binance API signature mismatches almost always trace back to one of three things: clock drift, a wrong or malformed API secret, or incorrect parameter serialization. The systematic fix is: check your timestamp sync first, verify your secret has no hidden whitespace, then confirm your parameter string is being built and encoded correctly before signing. The Python and JavaScript examples in this guide give you working implementations you can drop into any project.

Once your authentication is solid, shift your focus to what your bot is actually doing with the API. Whether you're executing signals from VoiceOfChain or running your own technical analysis on Binance, KuCoin, or any other exchange, reliable API auth is the foundation everything else depends on. Get it right once, test it on a real endpoint, and it will run without issues indefinitely.

◈   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