English counterpart of BINANCE_RESEARCH.md. | Türkçe
Phase 1 research completed on 2026-08-18 using only official Binance sources. Pinned commits are in BINANCE_VERSION.en.md, and V1 endpoints are in BINANCE_ENDPOINT_MATRIX.en.md.
Source priority: official Spot API Docs, official Spot OpenAPI, then official connectors.
Production REST defaults to https://api.binance.com; api-gcp and api1–api4 are alternatives, with the latter potentially faster but less stable. https://data-api.binance.vision is public market data only. Spot Testnet uses https://testnet.binance.vision/api or https://api1.testnet.binance.vision/api; endpoint paths remain /api/v3/....
X-MBX-TIME-UNIT: MICROSECOND.All signed REST parameters use one deterministic query string. This avoids ambiguity in Binance's delimiter-free query-plus-body signature rule. The signed UTF-8 bytes are exactly the encoded query sent on the wire.
Security types are NONE, TRADE, USER_DATA, and USER_STREAM. Non-NONE REST calls are signed and send the API key in X-MBX-APIKEY. TRADE is not enabled by default for a new key.
V1 fully supports HMAC-SHA256, supplies verified Ed25519 signer infrastructure, and leaves RSA as a future extension.
nil; convert names and values to Binance wire forms.name=value pairs.signature last.Binance does not mandate one REST parameter order, but deterministic order improves testing and observability. Signed and transmitted payloads must match exactly.
Remove signature, sort parameter names alphabetically, build raw UTF-8 name=value&..., and store HMAC hex or asymmetric Base64 in params.signature. This is not a URL query. REST percent-encoding is not reused; separate canonicalizers and official vectors test each contract.
recvWindowSigned requests require millisecond or microsecond timestamp. recvWindow is always milliseconds but may contain three fractional digits for microsecond precision; default is 5,000 and maximum 60,000. Binance recommends 5,000 or less. Server checks time both at receipt and before forwarding to matching engine; timestamp may be at most one second ahead and must remain within receive window.
V1 keeps 5,000 ms and stores /time-measured offset in an injectable clock. -1021 triggers resynchronization rather than blind trading retry.
exchangeInfo reports current RAW_REQUESTS, REQUEST_WEIGHT, and ORDERS. Static weight is planning input; response metadata observes actual use.
X-MBX-USED-WEIGHT-*.X-MBX-ORDER-COUNT-*; rejected responses need not.429 requires backoff; REST Retry-After is seconds.418 bans ranging from minutes to days.retryAfter is an epoch timestamp, not REST header semantics.rateLimits.Since 2026-04-02, selected successful trading calls can have request weight 0 while failures use documented weight. New and cancel order follow this rule. V1 preserves both worst-case static values and headers.
REST errors are {code,msg}. Message text may change; numeric code is the programmatic foundation.
| Situation | Classification | V1 behavior |
|---|---|---|
Validation / -1013 | definitive rejection | Local/API validation error |
-1021 | timestamp | Refresh offset; do not repeat trading POST without a new user action |
-1022 | signature | Auth/encoding error; no retry |
429 | rate limit | Honor Retry-After and central limiting |
418 | IP ban | Stop until ban expires |
-1006, -1007 | unknown execution | Reconcile through order query/UDS |
Trading timeout or relevant 5xx | unknown execution | Never blindly POST the same order again |
Other 4xx | client/API error | Normalize code and safe reason |
Matching-engine timeout after ten seconds can return -1007 even if the order executed. Each order therefore uses a unique newClientOrderId, and uncertainty is resolved through GET /api/v3/order or UDS.
| Filter | Local check |
|---|---|
PRICE_FILTER | min/max and exact price % tickSize == 0; zero disables a rule |
LOT_SIZE | min/max and exact quantity step |
MARKET_LOT_SIZE | MARKET-specific min/max/step |
MIN_NOTIONAL | price * quantity >= minNotional, respecting market flags and average window |
NOTIONAL | min/max notional and MARKET application flags |
Financial fields are BigDecimal; invalid values are never auto-rounded. Tick/step divisibility uses exact remainder, not inferred decimal scale. MARKET notional can depend on a moving reference price, so local preflight is best effort and Binance remains final authority. Unknown filters survive parsing and are never silently labeled fully validated.
Production uses wss://stream.binance.com:9443 or port 443; Testnet uses wss://stream.testnet.binance.vision. V1 uses combined /stream plus live SUBSCRIBE/UNSUBSCRIBE.
serverShutdown triggers prompt reconnect and restore.Removed !ticker@arr is replaced by !miniTicker@arr, per-symbol <symbol>@ticker, <symbol>@bookTicker, and top-depth <symbol>@depth5|10|20 with optional @100ms. Mini-ticker arrays include only changed symbols, not a complete snapshot.
Production WebSocket API is wss://ws-api.binance.com:443/ws-api/v3; Testnet is wss://ws-api.testnet.binance.vision/ws-api/v3. Legacy listen-key REST endpoints were removed on 2026-02-20.
| Method | Key support | V1 decision |
|---|---|---|
userDataStream.subscribe.signature | Signed HMAC/RSA/Ed25519 request | Primary, supporting HMAC-default and Ed25519 |
session.logon + userDataStream.subscribe | Ed25519 authenticated session only | Secondary/future optimization |
Signature subscription sends apiKey, timestamp, signature, optional recvWindow, and costs weight 2. One account subscription is allowed per connection, up to 1,000 active per session and 65,535 over session lifetime. Events use {subscriptionId,event}.
V1 normalizes executionReport, outboundAccountPosition, balanceUpdate, and eventStreamTerminated; unknown events retain raw metadata. Termination/disconnect/shutdown triggers restore while REST query supports order reconciliation through any gap.
Create keys at https://testnet.binance.vision/. Only /api/* is supported; balances are virtual and /sapi/* is absent. Testnet can reset monthly without notice, preserving keys but deleting orders/history and refreshing balances. It can differ from production and has a separate changelog. Production URLs or credentials never become an automatic fallback.
Adopt separate REST/WebSocket lifecycles, a single lazy facade, persistent sessions, explicit close, response/rate-limit envelopes, registries, reconnect restore, contract fixtures, and small runnable examples.
Adapt generated models into immutable Clojure maps and normalizers; replace financial float with BigDecimal; separate safe reads from command retries; enrich errors with numeric codes, headers, retry data, and unknown execution; isolate callbacks through bounded queues.
Do not copy per-endpoint generated class networks, silent fallback on schema changes, global mutable registries, secret-bearing request logs, or uniform retries across methods.
BigDecimal; timestamps/IDs to integers.5xx/-1006/-1007 means unknown execution.newClientOrderId.userDataStream.subscribe.signature.!ticker@arr; use current streams.Phase 3 reproduced official ASCII and full-width Unicode REST HMAC vectors, the official WebSocket HMAC vector, and RFC 8032 Ed25519 test 1. Signed timestamps, receive-window bounds, and raw-UTF-8 WebSocket behavior are contract-tested.
Phase 4 bound official HTTP/error/limit behavior to tests: 5xx can be unknown for commands; REST Retry-After is seconds; 418 is never automatically retried; response headers populate observation state; one JDK client owns a reusable pool; data.json :bigdec true is mandatory.
The Go/JavaScript cross-check confirmed architecture but tightened safety: retry cannot be inferred from HTTP method because cancel is state-changing DELETE. Every command uses :retry-policy :never.
Phase 8 rechecked the pinned Spot Docs, including 24-hour connections, 20-second ping, one-minute pong deadline, five control messages/second, 1,024 streams, WebSocket shutdown behavior, and current signature-subscription limits. Implementation replies to pong in the transport callback, batches restore, regenerates UDS signatures, and renews at 23h50m. Live credential-free BTCUSDT@bookTicker acceptance passed.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |