◈   ⌘ api · Intermediate

Binance Withdrawal Restrictions API: Complete Developer Guide

Learn how to query Binance withdrawal restrictions via API, handle limits programmatically, and build robust withdrawal automation with real code examples.

Uncle Solieditor · voc · 06.05.2026 ·views 51
◈   Contents
  1. → Understanding Binance Withdrawal Restrictions
  2. → Setting Up Binance API Authentication
  3. → Querying Coin and Network Withdrawal Status
  4. → Checking Account-Level Withdrawal Limits
  5. → Building a Pre-Flight Withdrawal Check
  6. → Common Restriction Errors and How to Handle Them
  7. → Frequently Asked Questions
  8. → Putting It All Together

Withdrawal restrictions on Binance aren't arbitrary — they exist because of KYC verification levels, network congestion policies, security holds, and regional compliance rules. If you're building a trading bot or automating fund management, hitting a withdrawal restriction at the wrong moment can lock up capital and break your entire flow. The Binance API exposes everything you need to check restrictions before attempting a withdrawal, handle errors gracefully, and route funds intelligently. Here's how to do it properly.

Understanding Binance Withdrawal Restrictions

Binance applies withdrawal restrictions across several dimensions. First, there's the account verification tier — unverified accounts face a 2 BTC daily withdrawal limit, while verified users get 100 BTC equivalent. Second, there are network-specific suspensions: Binance periodically halts withdrawals on specific blockchain networks during maintenance or during congestion events. Third, individual coins can be suspended separately from their networks. Finally, there are IP-based and 2FA-based security holds that trigger a 24-hour withdrawal freeze after account changes.

Compared to platforms like Bybit and OKX, which offer more granular API responses for restriction reasons, Binance's API requires you to cross-reference multiple endpoints to get the full picture. That said, it's entirely scriptable — and once you know the endpoints, you can build a comprehensive pre-flight check before initiating any withdrawal.

Always query withdrawal status BEFORE attempting a withdrawal. A failed withdrawal attempt doesn't just return an error — on Binance it can trigger additional security reviews and temporary holds.

Setting Up Binance API Authentication

Withdrawal-related endpoints require a signed request using your API secret. Your API key must have the 'Enable Withdrawals' permission enabled in the Binance dashboard. Never enable this permission on keys you use for read-only market data — keep separate keys for trading and withdrawal operations.

import hashlib
import hmac
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 sign_request(params: dict) -> str:
    query_string = urlencode(params)
    signature = hmac.new(
        API_SECRET.encode('utf-8'),
        query_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return signature

def get_signed_headers() -> dict:
    return {'X-MBX-APIKEY': API_KEY}

def build_signed_params(params: dict = None) -> dict:
    if params is None:
        params = {}
    params['timestamp'] = int(time.time() * 1000)
    params['recvWindow'] = 5000
    params['signature'] = sign_request(params)
    return params

The `recvWindow` parameter is important — it defines how long (in milliseconds) a request remains valid after the timestamp. Keep it between 5000 and 60000ms. Lower values are more secure but require tighter clock synchronization between your server and Binance's servers.

Querying Coin and Network Withdrawal Status

The most important endpoint for checking withdrawal restrictions is `/sapi/v1/capital/config/getall`. This returns a list of all coins with their network configurations, including whether withdrawals are currently enabled or suspended per network.

def get_coin_withdrawal_status(coin: str = None) -> list:
    """
    Fetch withdrawal status for all coins or a specific coin.
    Returns list of coin configs with network-level restriction details.
    """
    endpoint = '/sapi/v1/capital/config/getall'
    params = build_signed_params()
    
    try:
        response = requests.get(
            BASE_URL + endpoint,
            headers=get_signed_headers(),
            params=params,
            timeout=10
        )
        response.raise_for_status()
        data = response.json()
        
        if coin:
            data = [c for c in data if c['coin'].upper() == coin.upper()]
        
        # Extract withdrawal restriction details per network
        results = []
        for coin_data in data:
            for network in coin_data.get('networkList', []):
                results.append({
                    'coin': coin_data['coin'],
                    'network': network['network'],
                    'withdraw_enabled': network['withdrawEnable'],
                    'withdraw_min': network['withdrawMin'],
                    'withdraw_fee': network['withdrawFee'],
                    'withdraw_integer_multiple': network['withdrawIntegerMultiple'],
                    'special_tips': network.get('specialTips', '')
                })
        return results
        
    except requests.exceptions.HTTPError as e:
        print(f'HTTP Error: {e.response.status_code} - {e.response.text}')
        raise
    except requests.exceptions.Timeout:
        print('Request timed out — Binance API may be slow')
        raise

# Example usage
usdt_networks = get_coin_withdrawal_status('USDT')
for net in usdt_networks:
    status = 'OPEN' if net['withdraw_enabled'] else 'RESTRICTED'
    print(f"{net['coin']} on {net['network']}: {status} | Min: {net['withdraw_min']} | Fee: {net['withdraw_fee']}")

The `withdrawEnable` boolean is the key field. When it's `false`, any withdrawal attempt on that network will fail immediately. The `specialTips` field sometimes contains human-readable explanations — maintenance windows, congestion notices, or regulatory holds. Always log this field because it often contains timing information about when the restriction is expected to lift.

Checking Account-Level Withdrawal Limits

Network status is only half the picture. You also need to verify your account's withdrawal capacity. The `/sapi/v1/account/info` endpoint returns your verification tier and trading level, while `/sapi/v1/capital/withdraw/history` lets you calculate how much of your daily limit you've already consumed.

from datetime import datetime, timedelta

def get_daily_withdrawal_usage(hours_back: int = 24) -> dict:
    """
    Calculate total withdrawal amount in the last 24 hours.
    Returns dict with total withdrawn and estimated remaining capacity.
    """
    endpoint = '/sapi/v1/capital/withdraw/history'
    
    start_time = int((datetime.utcnow() - timedelta(hours=hours_back)).timestamp() * 1000)
    
    params = build_signed_params({
        'startTime': start_time,
        'limit': 1000
    })
    
    try:
        response = requests.get(
            BASE_URL + endpoint,
            headers=get_signed_headers(),
            params=params,
            timeout=10
        )
        response.raise_for_status()
        history = response.json()
        
        # Sum completed and processing withdrawals only
        active_statuses = {1, 2, 6}  # email_sent, cancelled=3, rejected=4, processing=5, success=6
        total_usdt_equivalent = 0.0
        
        completed = [
            w for w in history
            if int(w['status']) in {1, 2, 6}
        ]
        
        return {
            'withdrawal_count': len(completed),
            'withdrawals': completed,
            'raw_history': history
        }
        
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 403:
            print('API key lacks withdrawal history permission')
        raise

# Check account info for KYC tier
def get_account_api_restrictions() -> dict:
    endpoint = '/sapi/v1/account/apiRestrictions'
    params = build_signed_params()
    
    response = requests.get(
        BASE_URL + endpoint,
        headers=get_signed_headers(),
        params=params,
        timeout=10
    )
    response.raise_for_status()
    data = response.json()
    
    return {
        'ip_restrict': data.get('ipRestrict'),
        'enable_withdrawals': data.get('enableWithdrawals'),
        'enable_internal_transfer': data.get('enableInternalTransfer'),
        'permits_universal_transfer': data.get('permitsUniversalTransfer'),
        'trading_authorized': data.get('enableSpotAndMarginTrading')
    }

restrictions = get_account_api_restrictions()
print(f"Withdrawals enabled on this API key: {restrictions['enable_withdrawals']}")
If 'enableWithdrawals' returns False from the apiRestrictions endpoint, your API key itself doesn't have withdrawal permissions — no amount of troubleshooting the request will fix this. You need to regenerate the key in the Binance dashboard with withdrawal permissions enabled.

Building a Pre-Flight Withdrawal Check

Rather than attempting a withdrawal and handling the error, the professional approach is a pre-flight check that validates all conditions before submitting. This is especially important in automated systems where a failed withdrawal might not trigger an alert for minutes. On platforms like OKX and Gate.io, similar pre-check patterns are common in production trading bots precisely because they reduce unnecessary API calls and error cascades.

class WithdrawalPreflightError(Exception):
    pass

def preflight_withdrawal_check(coin: str, network: str, amount: float) -> dict:
    """
    Validates all conditions before attempting a withdrawal.
    Raises WithdrawalPreflightError with specific reason if blocked.
    Returns fee and minimum info if all checks pass.
    """
    # Check 1: API key permissions
    api_restrictions = get_account_api_restrictions()
    if not api_restrictions['enable_withdrawals']:
        raise WithdrawalPreflightError(
            'API key does not have withdrawal permissions enabled'
        )
    
    # Check 2: Coin/network availability
    coin_networks = get_coin_withdrawal_status(coin)
    target_network = None
    
    for net in coin_networks:
        if net['network'].upper() == network.upper():
            target_network = net
            break
    
    if not target_network:
        raise WithdrawalPreflightError(
            f'Network {network} not found for {coin}'
        )
    
    if not target_network['withdraw_enabled']:
        tips = target_network.get('special_tips', 'No details available')
        raise WithdrawalPreflightError(
            f'Withdrawals suspended for {coin} on {network}. Reason: {tips}'
        )
    
    # Check 3: Minimum amount
    min_amount = float(target_network['withdraw_min'])
    if amount < min_amount:
        raise WithdrawalPreflightError(
            f'Amount {amount} is below minimum {min_amount} for {coin}/{network}'
        )
    
    fee = float(target_network['withdraw_fee'])
    
    return {
        'coin': coin,
        'network': network,
        'amount': amount,
        'fee': fee,
        'amount_after_fee': amount - fee,
        'ready': True
    }

# Usage
try:
    check = preflight_withdrawal_check('USDT', 'TRX', 50.0)
    print(f"Ready to withdraw. You will receive: {check['amount_after_fee']} USDT")
    print(f"Network fee: {check['fee']} USDT")
except WithdrawalPreflightError as e:
    print(f"Withdrawal blocked: {e}")
    # Optionally alert via VoiceOfChain webhook or Telegram notification

This pattern integrates well with signal-driven trading systems. If you're using VoiceOfChain for real-time trading signals and want to automate fund movement after a signal fires, wrapping your withdrawal logic in a preflight check ensures the automation fails fast and loudly rather than silently dropping transactions.

Common Restriction Errors and How to Handle Them

Binance uses numeric error codes in their API responses. When a withdrawal fails, the error code tells you exactly what went wrong. Here are the most common ones traders encounter in production systems:

Binance Withdrawal API Error Codes
Error CodeMeaningFix
-1100Illegal characters in parameterValidate address format before submission
-1102Mandatory parameter missingCheck all required fields: coin, network, address, amount
-3044Withdrawals are not allowed for this assetCheck coin status via capital/config/getall
-3041Balance insufficientVerify available balance minus fee
-3025This withdraw is not allowed. Please try again laterAccount security hold — wait 24-48h after account changes
-1003Too many requestsImplement rate limiting: max 10 req/min on SAPI endpoints

Error -3025 is particularly frustrating because the message is vague. It almost always means one of three things: a recent password change, a recently added withdrawal address (Binance holds these for 24 hours), or a recent API key modification. Unlike KuCoin which sends an email explaining the hold, Binance leaves you to diagnose it via the error code alone.

Frequently Asked Questions

Why does Binance API return success but the withdrawal never arrives?
A successful API response only means the withdrawal request was accepted, not completed. Check the withdrawal status via /sapi/v1/capital/withdraw/history using the returned withdrawId. Status code 6 means success; status 5 means still processing. Network congestion on chains like Ethereum can delay confirmations by hours.
Can I withdraw to a new address immediately via the API?
No. Binance enforces a 24-hour whitelist hold on newly added withdrawal addresses for security reasons. This applies to addresses added via the web interface and via API. You must whitelist the address at least 24 hours before your bot attempts to withdraw to it.
Why is withdrawEnable false for a specific network?
Network-level suspensions happen for maintenance, security incidents, or blockchain upgrades. The specialTips field in the API response often contains a reason and estimated restoration time. Check Binance's official status page and Twitter for announced maintenance windows.
How do I check my remaining 24-hour withdrawal limit via API?
Binance doesn't expose the remaining limit directly. You need to sum your withdrawal history from the past 24 hours and subtract from your account tier limit (2 BTC unverified, 100 BTC verified). The /sapi/v1/capital/withdraw/history endpoint with a startTime parameter gives you the data to calculate this.
Does using a sub-account bypass withdrawal restrictions?
No. Sub-accounts on Binance have their own withdrawal limits and the same network restrictions apply. However, internal transfers between the main account and sub-accounts via /sapi/v1/sub-account/transfer don't count against withdrawal limits and aren't subject to network suspensions.
How often does Binance change withdrawal fees, and how do I stay updated?
Fees change without notice, sometimes multiple times per week during high network congestion. Never hardcode fees in your bot — always fetch the current fee from /sapi/v1/capital/config/getall immediately before calculating the withdrawal amount. Stale fee data is a common source of 'insufficient balance' errors.

Putting It All Together

Building reliable withdrawal automation on Binance requires treating restrictions as a first-class concern, not an afterthought. The combination of pre-flight checks, proper error code handling, and dynamic fee fetching eliminates the most common failure modes. Keep your withdrawal logic decoupled from your trading logic — a network suspension on TRC-20 USDT shouldn't halt your entire trading bot when ERC-20 might still be available.

For production systems, add a monitoring layer that polls withdrawal status every few minutes and alerts you if a transaction stays in 'processing' status longer than expected. If you're running signal-based strategies through a platform like VoiceOfChain, this kind of automated fund routing between exchanges — Binance to Bybit for example — becomes a real competitive edge when you can execute it reliably and programmatically.

◈   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