TL;DR
Binance Spot and USDⓈ-M Futures expose deliberately different order-placement models, and the differences cause most integration bugs. The two that bite hardest: maker-only (post-only) is an order type on Spot (LIMIT_MAKER) but a time-in-force value on Futures (GTX, Good-Till-Crossing), and iceberg orders exist on Spot (icebergQty) but not on USDⓈ-M Futures. An unexpected EXPIRED_IN_MATCH status is self-trade prevention (STP), not a bug. Because the two venues use different enums, filters, and rejection codes, teams integrating both typically normalize them behind a single order model instead of branching everywhere.
Spot and USDⓈ-M Futures are separate API surfaces (/api/v3 for Spot, /fapi/v1 for Futures) with separate enum, filter, and error-code definitions. The docs describe how to place an order on each, but rarely put the two side by side, so the divergences stay hidden until an order behaves differently than the Spot code that "worked."
The single most common cross-venue trip-up.
Spot post-only code cannot be reused on Futures by changing the symbol — the parameter that carries the intent moves from type to timeInForce.
Two divergences follow: GTX and GTD exist only on Futures. A Futures GTD order requires goodTillDate, which must be at least 600 seconds in the future.
STP is the usual explanation for orders that expire without an obvious cause.
No Spot equivalent, and a frequent source of "unknown parameter" or logic errors when Spot code is ported:
Common Futures rejections: -2021 (order would immediately trigger) and -2022 (reduce-only rejected).
Recent gotcha — conditional orders moved to the Algo service. Since 2025-12-09, USDⓈ-M Futures conditional types (STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET, TRAILING_STOP_MARKET) are handled by the Algo Order endpoints. Sending them to the plain New Order endpoint returns -4120 (STOP_ORDER_SWITCH_ALGO); that endpoint now effectively accepts LIMIT and MARKET.
| Behavior | Spot (/api/v3) | USDⓈ-M Futures (/fapi/v1) |
|---|---|---|
| Maker-only / post-only | Order type LIMIT_MAKER | Time-in-force GTX |
| Iceberg | icebergQty param | Not supported (slice client-side) |
| Time-in-force set | GTC, IOC, FOK | GTC, IOC, FOK, GTX, GTD, RPI |
| Stop / take-profit type names | STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT | STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET, TRAILING_STOP_MARKET |
| Conditional orders | Same endpoint | Algo endpoints (else -4120) |
| STP modes | NONE, EXPIRE_MAKER, EXPIRE_TAKER, EXPIRE_BOTH, DECREMENT, TRANSFER | EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH (default EXPIRE_MAKER) |
| Self-match status | EXPIRED_IN_MATCH | EXPIRED_IN_MATCH |
| Extra order statuses | PENDING_NEW, PENDING_CANCEL | — |
| Position side param | n/a | positionSide (Hedge Mode) |
| Reduce-only / close-position | n/a | reduceOnly, closePosition |
| PERCENT_PRICE basis | avg of previous trade prices | mark price |
| Order-placement rate accounting | IP weight + order-count | 0 on IP; counts X-MBX-ORDER-COUNT-10S / 1M |
| Filter-violation error codes | filter-specific | -40xx (-4013 / -4014 / -4164 / -4131) |
| Symbol reference | exchangeInfo | exchangeInfo |
When a desk trades both venues (and others besides), this branching multiplies. A connectivity/normalization layer sits beneath the execution system (OMS/EMS/algos) and presents one order model, so the caller expresses "post-only limit" once instead of choosing LIMIT_MAKER on Spot and timeInForce=GTX on Futures, and reads one canonical order state instead of reconciling EXPIRED_IN_MATCH against each venue's status set.
Axon Trade is one such layer. It uses a canonical slash-format symbol (e.g. ETH/USDT), identical for market data and execution across 30+ exchanges, reached through a single, slightly modified FIX 4.4 session rather than a per-venue REST/WebSocket integration. Its normalized reference data is delivered over FIX SecurityList (35=y) with Symbol (55) and SecurityExchange (207).
How do you place a post-only order on Binance Futures?
On USD-M Futures post-only is set through time-in-force GTX on a limit order not through a separate order type.
Why is there no LIMIT_MAKER on Binance Futures?
Futures expresses maker-only through the GTX time-in-force instead of a LIMIT_MAKER order type which is a Spot only order type.
What does EXPIRED_IN_MATCH mean on Binance?
It means an order was expired by self-trade prevention because it would have matched an order from the same account or trade group rather than filled or canceled normally.
Does Binance Futures support iceberg orders?
No native iceberg parameter exists on USD-M Futures while Spot supports iceberg through the icebergQty parameter.
Which time-in-force values does Binance Spot support?
Binance Spot supports exactly GTC IOC and FOK while USD-M Futures adds GTX GTD and RPI.
Why did my Binance Futures stop order start returning -4120?
Since 2025-12-09 conditional order types moved to the Algo Order endpoints and the plain New Order endpoint rejects them with code -4120.
Axon Trade provides advanced trading infrastructure for institutional and professional traders, offering high-performance FIX API connectivity, real-time market data, and smart order execution solutions. With a focus on low-latency trading and risk-aware decision-making, Axon Trade enables seamless access to multiple digital asset exchanges through a unified API.
Explore Axon Trade’s solutions:
Contact Us for more info.