Binance vs Bybit API: signing, limits and test environments
Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.
On paper the Binance and Bybit APIs are the same kind of thing: HMAC-signed REST, a millisecond timestamp, a receive window, a separate testnet. That similarity is what makes porting slow — code that works on one fails on the other in ways that look like bugs in your code.
This page is for developers adding the second integration or deciding which to build first. It compares mechanism only, no fees or quotas, and does not pick a winner. For the general checklist, see choosing an exchange for automation.
Short answer
- You want to sign with Ed25519 → Binance Spot documents and recommends it. Bybit’s guide lists HMAC and RSA keys.
- You want your remaining budget per endpoint on every response → Bybit’s
X-Bapi-Limit-Status. Binance reports weight used per IP. - You want the venue to force IP restriction before withdrawals → Binance documents that rule. We have not verified an equivalent rule for Bybit.
- You are porting hedge-mode futures code → budget real time: same concept, different parameter names and switching scope.
What they have in common
- HMAC-SHA256 request signing, with an asymmetric-key option.
- A time check that rejects requests older than the receive window (default 5000 ms) or more than one second ahead of server time.
- Separate testnet and demo hostnames, so a key used in the wrong environment fails authentication instead of trading.
- One-way and hedge position modes on derivatives, with the switch blocked while orders or positions are open.
Where they actually differ
Signature payload and where credentials travel
| Binance | Bybit | |
|---|---|---|
| API key | X-MBX-APIKEY header | X-BAPI-API-KEY header |
| Timestamp | timestamp parameter (Spot accepts ms or µs) | X-BAPI-TIMESTAMP header, ms |
| Receive window | recvWindow parameter | X-BAPI-RECV-WINDOW header |
| Signature | signature parameter | X-BAPI-SIGN header |
| Signed string | Query string concatenated with the body; non-ASCII percent-encoded first | timestamp + api_key + recv_window + queryString (GET) or + jsonBodyString (POST) |
| HMAC output | Hex | Lowercase hex |
The structural difference is what goes into the signed string. On Binance
the timestamp is just a parameter inside the signed query; on Bybit the
timestamp, key and window are prepended to the payload and travel as headers.
Signing code for one fails on the other: -1022 on Binance, 10004 on Bybit.
See what HMAC request signing is and
API signature methods compared.
Binance HMAC signatures are not case-sensitive (RSA and Ed25519 are); Bybit RSA signatures are base64, not hex.
Key types
Binance Spot supports HMAC, RSA and Ed25519 keys. The USDⓈ-M futures General Info page documents HMAC and RSA; we did not find Ed25519 there, so check before using one for futures.
Bybit’s system-generated keys sign with HMAC. Self-generated keys are RSA: you give Bybit only the public key, and it will “never hold your private key”.
Permissions and IP rules
Binance’s rules are specific:
- Withdrawals cannot be enabled on a key without IP restriction.
- A key with no whitelisted IP loses Spot & Margin trading permission 90 days after activation; it can be re-enabled by hand.
GET /sapi/v1/account/apiRestrictionslets a process check its own permissions at startup.
Details are in Binance API key permissions.
On Bybit we can confirm that IP binding exists — 10010 reads “Unmatched IP,
please check your API key’s bound IP addresses.” — and that a missing
permission returns 10005. We have not verified Bybit’s permission scopes,
whether IP binding is required for any of them, or a permission-query endpoint,
so we make no claim either way — see
Bybit API key setup.
Where the two clearly differ is error specificity. Binance folds a bad key,
a wrong IP and a missing permission into one code, -2015. Bybit gives each
its own code: 10003, 10010 and 10005.
Timestamp windows
The rules are close to identical. Binance:
timestamp < serverTime + 1000 && serverTime - timestamp <= recvWindow. Bybit:
server_time - recv_window <= timestamp < server_time + 1000.
Binance Spot caps recvWindow at 60000 ms; we did not find a stated maximum
for Binance futures or for Bybit. Failures surface as -1021 on Binance — with
a second message for requests “1000ms ahead of the server’s time” — and
10002 on Bybit.
The fix on both is the same: sync to server time (Bybit publishes
GET /v5/market/time) rather than widening the window. See
clock sync and timestamps.
Rate-limit models
Binance meters weight per IP. Every response carries
X-MBX-USED-WEIGHT-(interval), and “the limits on the API are based on the
IPs, not the API keys.” Order counts are tracked per account, reported in
X-MBX-ORDER-COUNT-(interval). Breaching returns 429; continuing returns a
418 IP ban. Both carry Retry-After.
Bybit has two independent layers. A per-IP HTTP limit returns HTTP 403
“access too frequent”; the ban lifts automatically. Separately, a per-UID,
per-endpoint limit on a rolling per-second window returns retCode 10006,
with X-Bapi-Limit, X-Bapi-Limit-Status and X-Bapi-Limit-Reset-Timestamp
on every response. Batch endpoints have their
own budget and consume one unit per order — and if a batch overruns, the
overflow orders fail while the rest succeed.
So on Binance, processes behind one IP share one weight budget; on Bybit the per-endpoint budget follows the account and a batch can partially succeed. Read quotas from each venue’s page, not code comments — see the Binance rate-limit guide.
Testnet and demo environments
| Binance | Bybit | |
|---|---|---|
| Testnet | Spot: testnet.binance.vision (GitHub login; /api/* only, not /sapi/*). USDⓈ-M: demo-fapi.binance.com | api-testnet.bybit.com |
| Demo trading | Spot Demo Mode: demo-api.binance.com, keys from a normal account | api-demo.bybit.com, key created on Production while in Demo Trading mode |
| Mixing keys | Testnet and Demo Mode keys do not cross | 10003 lists four environments: mainnet, testnet, mainnet-demo, testnet-demo |
Older futures examples may still show testnet.binancefuture.com. Bybit
advises against using Demo Trading on Testnet. Setup is covered in
the Binance testnet guide and
the Bybit testnet guide.
Position mode parameters
| Binance USDⓈ-M | Bybit linear | |
|---|---|---|
| Switch | POST /fapi/v1/positionSide/dual, dualSidePosition "true"/"false" | POST /v5/position/switch-mode, mode 0 (one-way) / 3 (hedge) |
| Scope | Every symbol; after CM migration it flips USDⓈ-M and COIN-M together | Per symbol or per settle coin; symbol beats coin beats default |
| Order field | positionSide: BOTH, or LONG/SHORT (required in hedge) | positionIdx: 0, or 1/2 (required in hedge) |
| Switch blocked by | -4067 open orders, -4068 open position | 110028 open orders, 110024 open position |
Binance also rejects reduceOnly in hedge mode, and a positionSide mismatch
returns -4061. See hedge mode.
Error-code families
Binance returns { "code": -1121, "msg": "Invalid symbol." } with a
meaningful HTTP status; 5XX means execution status is unknown. Spot filter
violations share -1013 with a “Filter failure: …” message; USDⓈ-M futures
uses dedicated codes such as -4014 and -4164.
Bybit wraps everything in retCode, retMsg, result, retExtInfo, time,
usually with HTTP 200. The 10xxx range covers request, auth and rate limit;
110xxx covers derivatives and positions. HTTP 403 is overloaded: rate
limit, a GET with an empty JSON body, or an IP in the US or Mainland China,
which Bybit’s guide says are restricted.
So a Binance client can branch on HTTP status first; a Bybit client has to parse the body even on a 200. More in auth errors across exchanges.
Which to pick
| Your situation | Lean toward | Why |
|---|---|---|
| You want Ed25519 signing on Spot | Binance | Documented and recommended there |
| You want a distinct error per auth cause | Bybit | 10003, 10005 and 10010 are separate; Binance uses -2015 for all three |
| You want withdrawals to require IP restriction by rule | Binance | Documented; not verified for Bybit |
| You pace requests per endpoint from response headers | Bybit | Remaining budget is reported per endpoint |
| Your servers are in the US or Mainland China | Check access first | Bybit says such IPs get 403; Binance’s regional terms must be checked on its own pages |
Can you use both
Yes: one signing module per venue, one error layer that keeps the native code visible, and a credential slot per environment. CCXT can handle the signing for both; see getting started with CCXT.
FAQ
Is the Binance signature the same as Bybit’s?
No. Both use HMAC-SHA256, but Binance signs the query string concatenated with
the body, while Bybit signs timestamp + api_key + recv_window followed by the
query string or JSON body. Code written for one produces a signature the other
rejects, as -1022 on Binance and 10004 on Bybit.
Why does a failed Bybit request return HTTP 200?
Bybit reports most errors in the body as a non-zero retCode, usually with
HTTP 200. Only HTTP-level problems, such as the IP rate limit or a restricted
region, use real status codes, so a client must read retCode on every
response.
Do Binance and Bybit use the same timestamp rule?
Nearly. Both reject a request more than 1000 ms ahead of server time or older
than the receive window, and both default the window to 5000 ms. Binance sends
the window as a parameter; Bybit sends it as the X-BAPI-RECV-WINDOW header.
The errors are -1021 and 10002.
Can a Bybit testnet key be used for demo trading?
No. Bybit’s 10003 message lists four environments — mainnet, testnet,
mainnet-demo and testnet-demo — and a key works only against the one it was
created in. Bybit’s FAQ names this mismatch as the most likely cause of
10003.