API Integration

What are the Differences Between Binance Futures and Spot APIs? Endpoint, Parameter, and Weight Comparison

A comprehensive comparison between Binance Futures API and Spot API: detailed differences in base URLs, signing mechanisms, order parameters, leverage settings, position queries, funding rates, and weight rules, including practical code for parallel API calls.

The fundamental differences between the Binance Futures API and Spot API lie in the base domain names and the parameter sets: Spot uses api.binance.com/api/v3/*, USDⓈ-M Futures use fapi.binance.com/fapi/v1/*, and COIN-M Futures use dapi.binance.com/dapi/v1/*. Although the signing algorithm remains HMAC-SHA256 for both, Futures require additional parameters such as reduceOnly, positionSide, and leverage, and they operate under different weight rules. This article provides a 10-dimensional comparison table and real code examples to help you smoothly migrate your spot quantitative strategies to futures. If you don't have a Binance account, please complete your registration at the Binance Official Website first; new users can open an account via the Register for Free channel.

I. General Comparison Overview

Dimension Spot USDⓈ-M Futures COIN-M Futures
Base URL api.binance.com fapi.binance.com dapi.binance.com
Path Prefix /api/v3/ /fapi/v1/ & /fapi/v2/ /dapi/v1/
Margin Asset USDT, USDC BTC, ETH, BNB, etc.
Max Leverage N/A (Margin only) 125x 125x
Dual-Side Position Not Supported Supported (HEDGE mode) Supported
WebSocket URL stream.binance.com:9443 fstream.binance.com dstream.binance.com
Min Order Amount 5 USDT (MIN_NOTIONAL) 5 USDT Based on notional value
Funding Rate N/A Every 8 Hours Every 8 Hours
Weight per Min 6000 2400 2400
listenKey Validity 60 Minutes 60 Minutes 60 Minutes

Key takeaway: Endpoints for USDⓈ-M always start with fapi, and COIN-M start with dapi. Never attempt to use Spot code simply by changing the URL.

II. Subtle Differences in Signing Mechanisms

While the signing algorithm is identical (HMAC-SHA256), two points require attention:

1. Different Default recvWindow Values

  • Spot: Default 5000ms, max 60000ms.
  • Futures: Default 5000ms, max 60000ms, but officials strongly recommend not exceeding 5000ms.

2. Numerical Parameters as Strings

The Futures API is more sensitive to numerical precision. When placing orders, it is recommended to pass price and quantity as strings to avoid -1111 Precision errors caused by floating-point precision:

# Not recommended
{"price": 60000.123456789, "quantity": 0.001}

# Recommended
{"price": "60000.12", "quantity": "0.001"}

III. Differences in Position and Balance Query Interfaces

Spot Balance

# Spot: GET /api/v3/account
# Returns a balances array
{
  "balances": [{"asset": "USDT", "free": "1000", "locked": "0"}]
}

USDⓈ-M Futures Positions

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

API_KEY = "YOUR_KEY"
SECRET_KEY = "YOUR_SECRET"
FAPI = "https://fapi.binance.com"

def _sign(params):
    params["timestamp"] = int(time.time() * 1000)
    query = urlencode(params)
    params["signature"] = hmac.new(SECRET_KEY.encode(), query.encode(), hashlib.sha256).hexdigest()
    return params

def get_positions():
    """V2 Position Query: Returns all non-zero positions"""
    params = _sign({})
    r = requests.get(f"{FAPI}/fapi/v2/positionRisk", params=params,
                     headers={"X-MBX-APIKEY": API_KEY})
    return [p for p in r.json() if float(p["positionAmt"]) != 0]

def get_futures_balance():
    """V2 Futures Account Balance"""
    params = _sign({})
    r = requests.get(f"{FAPI}/fapi/v2/balance", params=params,
                     headers={"X-MBX-APIKEY": API_KEY})
    return r.json()

positions = get_positions()
for p in positions:
    print(f"{p['symbol']}: Qty {p['positionAmt']}, Entry {p['entryPrice']}, UnPnL {p['unRealizedProfit']}")

IV. Comparison of Order Parameters

Placing a Spot order requires only 4-5 parameters; Futures requires additional fields like position side, reduce-only, and self-trade prevention:

Parameter Spot Futures
symbol Mandatory Mandatory
side BUY / SELL BUY / SELL
type LIMIT/MARKET/... LIMIT/MARKET/STOP/TAKE_PROFIT/TRAILING_STOP_MARKET
quantity Mandatory Mandatory (or use closePosition)
positionSide BOTH (One-way) / LONG / SHORT (Hedge)
reduceOnly true for reduce-only orders
closePosition true for one-click liquidation
workingType MARK_PRICE / CONTRACT_PRICE
newOrderRespType ACK/RESULT/FULL ACK/RESULT

Futures Limit Order Example

def place_futures_limit(symbol, side, quantity, price, position_side="BOTH"):
    params = _sign({
        "symbol": symbol,
        "side": side,
        "type": "LIMIT",
        "timeInForce": "GTC",
        "quantity": str(quantity),
        "price": str(price),
        "positionSide": position_side,
    })
    r = requests.post(f"{FAPI}/fapi/v1/order", params=params,
                      headers={"X-MBX-APIKEY": API_KEY})
    return r.json()

# Open Long 0.01 BTC, Limit 60000
order = place_futures_limit("BTCUSDT", "BUY", 0.01, 60000)
print(order["orderId"])

V. Leverage and Margin Mode Settings

Two interfaces unique to Futures:

# Set Leverage Multiplier
def set_leverage(symbol: str, leverage: int):
    params = _sign({"symbol": symbol, "leverage": leverage})
    r = requests.post(f"{FAPI}/fapi/v1/leverage", params=params,
                      headers={"X-MBX-APIKEY": API_KEY})
    return r.json()

set_leverage("BTCUSDT", 10)  # Set 10x leverage

# Set Margin Mode: ISOLATED or CROSSED
def set_margin_type(symbol: str, margin_type: str):
    params = _sign({"symbol": symbol, "marginType": margin_type})
    r = requests.post(f"{FAPI}/fapi/v1/marginType", params=params,
                      headers={"X-MBX-APIKEY": API_KEY})
    return r.json()

set_margin_type("BTCUSDT", "ISOLATED")

Note: You cannot switch margin modes while a position exists for the same symbol; you must close the position first.

VI. Funding Rate

The Funding Rate is a concept unique to contracts, settled every 8 hours:

# Query Latest Funding Rate
def get_funding_rate(symbol="BTCUSDT"):
    r = requests.get(f"{FAPI}/fapi/v1/premiumIndex",
                     params={"symbol": symbol})
    data = r.json()
    return {
        "markPrice": data["markPrice"],
        "fundingRate": data["lastFundingRate"],
        "nextFundingTime": data["nextFundingTime"]
    }

# Query Historical Funding Rate
def funding_history(symbol, limit=100):
    r = requests.get(f"{FAPI}/fapi/v1/fundingRate",
                     params={"symbol": symbol, "limit": limit})
    return r.json()

Arbitrage Tip: When fundingRate is positive, longs pay shorts; when negative, the opposite applies. A common strategy when rates remain highly positive for days is to short USDⓈ-M futures while going long on the spot market.

VII. Differences in Weights and Rate Limits

# Spot Response Headers
X-MBX-USED-WEIGHT-1m: 45
X-MBX-ORDER-COUNT-10s: 3

# Futures Response Headers
X-MBX-USED-WEIGHT-1m: 12
X-MBX-ORDER-COUNT-1m: 5
X-MBX-ORDER-COUNT-10s: 3

Futures adds a 1-minute order limit (default 1200 orders/minute), which must be monitored in high-frequency strategies.

VIII. WebSocket Differences

# Spot Subscription
import websocket, json

def on_message(ws, msg):
    data = json.loads(msg)
    print(data["s"], data["c"])  # symbol, close price

# Spot
ws_spot = websocket.WebSocketApp(
    "wss://stream.binance.com:9443/ws/btcusdt@ticker",
    on_message=on_message)

# USDⓈ-M Futures
ws_fut = websocket.WebSocketApp(
    "wss://fstream.binance.com/ws/btcusdt@markPrice",  # Mark Price Push
    on_message=on_message)

Unique Futures subscription topics include: @markPrice, @forceOrder (Liquidation Push), and @liquidation.

IX. Strategy Code for Parallel Spot + Futures Operations

Hedging strategies often require opening a Spot long position and a Futures short position simultaneously:

import asyncio, aiohttp

async def spot_buy(session, symbol, qty):
    # Simplified: Needs signing in practice
    async with session.post("https://api.binance.com/api/v3/order",
                            params={"symbol": symbol, "side": "BUY",
                                    "type": "MARKET", "quantity": qty}) as r:
        return await r.json()

async def futures_short(session, symbol, qty):
    async with session.post("https://fapi.binance.com/fapi/v1/order",
                            params={"symbol": symbol, "side": "SELL",
                                    "type": "MARKET", "quantity": qty}) as r:
        return await r.json()

async def hedge():
    async with aiohttp.ClientSession() as s:
        results = await asyncio.gather(
            spot_buy(s, "BTCUSDT", 0.01),
            futures_short(s, "BTCUSDT", 0.01)
        )
        print(results)

asyncio.run(hedge())

X. FAQ

Q1: Can I use one set of API Keys to operate both Spot and Futures?

A: Yes. In the API Key permission settings, check both Enable Spot & Margin Trading and Enable Futures. Remember that Futures accounts must be opened separately on the web portal and pass a knowledge test, otherwise, API calls will return -2015 Invalid API-key, IP, or permissions.

Q2: Are the balances for fapi.binance.com and dapi.binance.com independent?

A: Yes. USDⓈ-M Futures use independent USDT/USDC wallets, COIN-M Futures use independent BTC/ETH wallets, and the Spot wallet is entirely separate. Funds must be moved between accounts via /sapi/v1/futures/transfer.

Q3: What is the difference between Futures v1 and v2?

A: V2 is an enhanced version with optimized precision and field naming. Positions and balances MUST use v2 (/fapi/v2/positionRisk, /fapi/v2/balance), while placing or canceling orders remains in v1 (/fapi/v1/order).

Q4: Do I need to change my code for Portfolio Margin accounts?

A: Portfolio Margin uses a separate domain papi.binance.com/papi/v1/*. The endpoints are similar to fapi but with slight parameter differences. This only applies to VIP or high-net-worth accounts.

Q5: What is the minimum order amount for Futures API?

A: For USDⓈ-M, it's typically 5 USDT notional value (e.g., about 0.0001 BTC if the price is 60,000); popular pairs like BNBUSDT and ETHUSDT may go down to 1 USDT. Check the MIN_NOTIONAL filter via GET /fapi/v1/exchangeInfo for specifics.

For more Futures API topics, return to the Categories and select the "API Integration" section.

Keep reading

Still have Binance questions? Head back to the category page for more tutorials on the same topic.

Categories

Related tutorials

How to Apply for Binance API? Common Guide for Key Generation and Signatures 2026-04-14 How to Use Binance Spot API? Executable Code from Zero to Your First Order 2026-04-14 Will My IP Get Banned? Detailed Explanation of Binance API Rate Limits and Weights 2026-04-14 How to Subscribe to Binance WebSocket Market Data? Single vs. Combined Stream Code 2026-04-14