Crypto deposits, withdrawals, withdrawals with currency conversion, fiat operations (SEPA and card providers), and WhiteBIT Codes — status state machines, fee calculation, and webhook reconciliation.
Move funds into and out of WhiteBIT programmatically: generate deposit addresses, submit crypto and fiat withdrawals, convert between currencies before withdrawing, and settle between accounts with WhiteBIT Codes. Each flow documents the transaction lifecycle, status state machine, fee calculation, and webhook events, where each applies.
EEA users: USDT deposits and withdrawals have been unavailable since December 30, 2024 (MiCA compliance). Use USDC or EURI as alternatives. See Regulatory Compliance for details.
API key — create an API key with the required permissions in the WhiteBIT dashboard. Every endpoint on this page requires HMAC-signed requests (X-TXC-APIKEY, X-TXC-PAYLOAD, X-TXC-SIGNATURE headers). Store the secret per Security Best Practices.
Webhook URL — configure the webhook endpoint in the API key settings to receive transaction notifications. See Webhooks.
Fiat access — fiat operations additionally require completed institutional onboarding with approved fiat access.
UC1 — Payment provider with per-end-user deposit address
A payment-provider partner assigns each end customer a unique deposit address and credits the customer’s account when funds arrive. Reconciliation is webhook-driven by uniqueId (each deposit address corresponds to one customer in the partner’s database).See the Crypto Deposits tab for endpoint detail.
A partner serving EEA end users submits withdrawals with the required travelRule object. The withdrawal goes through compliance review before on-chain broadcast.See the Crypto Withdrawals tab for endpoint detail.
When the partner holds one currency in Main balance but needs to send another, request a conversion quote, confirm it, and submit the withdrawal. The convert service handles balance routing internally; no manual Main↔Trade transfers are required.See the Withdrawal with Conversion tab for endpoint detail.
Generate a deposit address by calling POST /api/v4/main-account/address. See the API Reference for the full endpoint specification.Required parameters:
Parameter
Type
Description
ticker
string
Currency ticker (e.g., BTC, ETH). The currency must have can_deposit: true in the Asset Status response.
Optional parameters:network — cryptocurrency network (e.g., ERC20, TRC20). Required for multi-network currencies like USDT; omit for single-network currencies. Query the Asset Status endpoint for available networks per currency.The endpoint returns the same address for the same ticker and network combination on repeated calls — addresses are permanent and reusable, not ephemeral.Key response fields:account.address, account.memo (for currencies requiring a memo or destination tag), required.fixedFee, required.flexFee, required.minAmount, required.maxAmount.Rate limit: subject to platform-level rate limits — see Rate Limits for current enforced values.
The POST /api/v4/main-account/address endpoint above returns the same address for the same ticker and network combination on every call. For payment provider integrations that assign a unique deposit address per end user, use POST /api/v4/main-account/create-new-address instead — this endpoint generates a fresh address on every call. See the API Reference for the full specification.
The /create-new-address endpoint is not available by default. Contact support@whitebit.com to request access.
For sub-accounts, crypto deposits are disabled by default. To enable deposits, contact the assigned Account Manager or institutional@whitebit.com.
Required parameters:
Parameter
Type
Description
ticker
string
Currency ticker (e.g., BTC, ETH)
Optional parameters:network (required for multi-network currencies; for USDT the default network is ERC20), type (address type for currencies that support several formats — BTC and LTC accept p2sh-segwit and bech32; the default is bech32).Rate limit: subject to platform-level rate limits — see Rate Limits for current enforced values.
Choosing between the two endpoints: The choice depends on the partner’s reconciliation model. Partners managing one consolidated wallet per asset (treasury, market-maker, single-merchant) use /address; repeat calls return the same address. Partners assigning one address per end customer (payment provider, per-user wallet) use /create-new-address; each call returns a fresh address, so an incoming deposit identifies the end user by address alone.
Endpoint
Behavior
Best for
POST /api/v4/main-account/address
Returns the same address for the same ticker + network
Single-wallet setups, treasury management
POST /api/v4/main-account/create-new-address
Generates a new address on every call
Payment providers assigning one address per end user
Funds sent by the external party — mempool detection begins
Confirmation tracking begins — deposit.accepted webhook fires while confirmations.actual is below confirmations.required
Each confirmation-count change fires the deposit.updated webhook with the new confirmations.actual — this event tracks progress; it does not signal completion
Deposit credited to Main balance — deposit.processed webhook fires — terminal success state
OR (EEA/Turkey): Travel Rule hold — deposit frozen (status 27 or 28). If the Travel Rule API is enabled, submit originator data via API to unfreeze; otherwise manual action at whitebit.com is required. See Travel Rule below.
The deposit/withdraw history endpoint returns numeric status codes. The following table maps each code to the meaning and the corresponding webhook event.
Numeric status codes are namespaced by transactionMethod. The same code may mean different things for deposits (transactionMethod: 1) and withdrawals (transactionMethod: 2). Always interpret the code in the context of the transactionMethod that returned it.
Notify end user — manual action required at whitebit.com
Awaiting user action
21
AML frozen
—
No
Wait — under compliance review. Escalate to institutional team if >24h
Deposit frozen by AML controls
22
Uncredited
—
No
Wait — credit pending. Escalate to support if >24h
Detected but not credited
27
Travel Rule frozen
—
No
Notify end user — Travel Rule data required at whitebit.com
Awaiting Travel Rule data (EEA / Turkey)
28
Travel Rule processing
—
No
Wait — Travel Rule data under review
Travel Rule data submitted
Use POST /api/v4/main-account/history with transactionMethod: 1 and status filter to poll for deposits in specific states. See the endpoint page for the current enforced rate limit.
Each cryptocurrency network requires a different number of block confirmations before the platform credits a deposit.Webhook payloads include confirmations.actual and confirmations.required fields — the confirmations.required value determines when the deposit completes. Query the Asset Status endpoint (GET /api/v4/public/assets) for per-currency confirmation requirements.Confirmation requirements vary by currency and network. Do not hardcode specific numbers — always retrieve the current values from the Asset Status endpoint.
Crypto deposits credit the actual on-chain amount received; the system does not flag deposits as “underpaid” or “overpaid”. If a partner expects an exact amount (e.g., for invoice matching), reconciliation logic must compare the deposit amount in the deposit.processed webhook against the expected amount and surface mismatches as application-level alerts.
When a deposit is canceled (status 4 or 9), a refund may be available.Endpoint:POST /api/v4/main-account/refund-deposit — see the API Reference for the full specification.Prerequisites:
The deposit must have status canceled.
Obtain transactionId from the deposit.canceled webhook (uniqueId field) or from the deposit/withdraw history in the WhiteBIT interface.
Required parameters:
Parameter
Type
Description
transactionId
string
Transaction UUID of the canceled deposit.
address
string
Destination wallet address for the refund.
The refund address must satisfy three constraints:
The address must support the same network and asset as the original deposit.
The address must not be a WhiteBIT-generated deposit address (an address created by /api/v4/main-account/address or /api/v4/main-account/create-new-address) — the endpoint refunds to external addresses only.
The address does not need to match the original sender address.
refund.failed — refund failed (the destination address does not support the required network or asset, or address validation fails; use a different address or contact support)
Rate limit: subject to platform-level rate limits — see Rate Limits for current enforced values.
For integrations that use a single persistent deposit address instead of unique addresses per user, substitute POST /api/v4/main-account/address (API Reference) for the /create-new-address endpoint.
Since May 18, 2025, WhiteBIT places inbound crypto deposits for EEA and Turkey accounts on hold until Travel Rule verification completes.
Status 27 (DEPOSIT_TRAVEL_RULE_FROZEN): deposit frozen, awaiting Travel Rule data from the account holder
Status 28 (DEPOSIT_TRAVEL_RULE_FROZEN_PROCESSING): Travel Rule data submitted, under review by WhiteBIT
API-based verification: When the Travel Rule API is enabled for the account, partners can submit originator data via POST /api/v4/travel-rule/deposit/verification to unfreeze deposits programmatically. See Travel Rule for the full verification flow and request format.
Manual verification fallback: If the Travel Rule API is not enabled for the account, frozen deposits require manual action at whitebit.com. Contact institutional@whitebit.com to request Travel Rule API access.
Submit a crypto withdrawal by calling POST /api/v4/main-account/withdraw. See the API Reference for the full endpoint specification.Two withdrawal endpoints are available:
Endpoint
Fee Handling
POST /api/v4/main-account/withdraw
Amount includes the fee — the receiver gets amount - fee
POST /api/v4/main-account/withdraw-pay
Amount excludes the fee — the receiver gets the exact amount specified; the platform charges the fee on top
Crypto withdrawals cannot be reversed once broadcast on-chain. Verify the destination address and network before submitting the request — funds sent to a wrong address or an incompatible network are lost.
Internal-transfer routing: When the destination address belongs to another WhiteBIT user, the platform routes the transfer as an internal off-chain transfer rather than an on-chain broadcast. Internal transfers are fee-free; the partner does not pay blockchain fees and the recipient sees the funds immediately. For partner-to-partner or master-to-sub-account settlement, consider WhiteBIT Codes for fee-free transfers without requiring the destination address.
Required parameters:
Parameter
Type
Description
ticker
string
Currency ticker (e.g., BTC, ETH)
amount
string
Withdrawal amount
address
string
Destination wallet address
uniqueId
string
Unique transaction identifier — any unique string up to 255 characters per request. The endpoint does not validate the value as a UUID.
Optional parameters:network (required for multi-network currencies), memo (for currencies requiring a memo or destination tag).Rate limit: subject to platform-level rate limits — see Rate Limits for current enforced values.
Crypto withdrawals from EEA accounts require a travelRule object in the request body. The object identifies the destination wallet and, for hosted wallets, the destination VASP (Virtual Asset Service Provider — the exchange or custodian hosting the receiving wallet).
The platform still accepts the legacy flat format, but legacy submissions do not pass Travel Rule verification. Migrate to the structured format above for compliance.
Field
Type
Description
type
string
"individual" or "entity" — the receiver type
vasp
string
Destination platform (VASP) name (e.g., "Binance")
name
string
If individual: first name. If entity: entity name.
address
string
If individual: last name. If entity: entity address.
After a withdrawal request is submitted, the system validates the request and begins processing.The POST /api/v4/main-account/withdraw endpoint returns HTTP 201 when validation succeeds. The platform confirms and processes API-initiated withdrawals immediately — the signed request is the authentication. There is no interactive 2FA step between the POST response and the processing start.Exceptions to immediate processing:
Sub-account withdrawals wait for main-account approval before processing.
Withdrawals to AML-blocked destination addresses freeze pending compliance review.
Temporary withdrawal freeze (3 days) applies after a password reset or a 2FA setting change on the account.
Status transitions follow the state machine below: unconfirmed → pending → successful or canceled. Webhook events track the full lifecycle.
A revised confirmation model for IP-whitelisted API keys is planned but not yet deployed. Contact institutional@whitebit.com for availability.
Withdrawal fees combine a fixed component and a flexible (percentage-based) component.Fee model (sourced from the deposit address endpoint response and the Asset Status endpoint):
fixedFee — flat fee charged regardless of amount
flexFee — percentage-based fee with floor and ceiling:
Fiat deposit and withdrawal operations require completion of institutional onboarding with approved fiat access. This flow applies to the institutional partner’s master account. For broker-managed sub-account fiat scope and constraints, see the Broker Program guide.
Fiat operations require completion of institutional onboarding including KYB (Know Your Business) verification and fiat provider approval. See Institutional Onboarding for the full two-phase process. Fiat endpoints are not available until WhiteBIT explicitly approves fiat access.
The onboarding process has two phases: Phase 1 (crypto access via KYB) and Phase 2 (fiat access via fiat processing partner review). Fiat access is not automatic after KYB approval — a separate review process with the fiat processing partner is required.
The fiat deposit flow is invoice-based: generate a payment URL, hand it to the end user, and reconcile the settlement.
1
Generate a deposit invoice
Call POST /api/v4/main-account/fiat-deposit-url with the fiat ticker, amount, provider, and a partner-side uniqueId. The response contains a url. See the API Reference for the full specification.
2
Present the URL to the end user
The end user opens the returned URL and completes the payment with the provider or bank.
3
For SEPA: instruct the end user on the payment reference
The bank-side transfer must carry the uniqueId in the payment-reference field — see SEPA payment reference below.
4
Confirm completion and reconcile
Confirm the credited deposit through the deposit history (POST /api/v4/main-account/history) or the Main balance (POST /api/v4/main-account/balance), matching by uniqueId.
The fiat deposit endpoint requires per-account activation. Contact WhiteBIT support and provide the API key to request access.
Required parameters:
Parameter
Type
Description
ticker
string
Fiat currency ticker (e.g., EUR)
amount
string
Deposit amount
provider
string
Payment provider — check Asset Status endpoint for fiat currencies with can_deposit: true
uniqueId
string
Unique transaction identifier
Optional parameters:
Parameter
Type
Description
successLink
string
Redirect URL after successful deposit. HTTPS only. Redirect links require feature activation — contact support before use; unactivated or non-HTTPS links fail validation.
failureLink
string
Redirect URL after failed deposit. Same HTTPS and activation requirement as successLink.
returnLink
string
Redirect URL the end user lands on after the deposit flow (success or failure). Optional fallback target.
address
string
For provider: "VISAMASTER" — the end user’s card number (PAN). Required when funding by card.
customer
object
Customer identity block. Required for provider: "VISAMASTER" (USD/EUR) and provider: "MERCURYO". Sub-fields: firstName, lastName, email, birthDate (YYYY-MM-DD), address.{line1, line2, city, zipCode, countryCode}.
expiresAfter
integer
Invoice expiration in seconds. Maximum 86400 (24 hours). Accepted only for provider: "VISAMASTER" and provider: "CHECKOUT".
The API does not accept the GEL and UAH_VISAMASTER tickers. To deposit those currencies, use the WhiteBIT web interface.
The endpoint returns a URL that the end user opens to complete the fiat deposit. Take the provider value for the currency from the Asset Status response.
curl
Python
# Generate a fiat deposit invoice (provider value from Asset Status)curl -X POST "https://whitebit.com/api/v4/main-account/fiat-deposit-url" \ -H "Content-Type: application/json" \ -H "X-TXC-APIKEY: YOUR_API_KEY" \ -H "X-TXC-PAYLOAD: YOUR_PAYLOAD" \ -H "X-TXC-SIGNATURE: YOUR_SIGNATURE" \ -d '{ "ticker": "EUR", "provider": "PROVIDER", "amount": "100", "uniqueId": "fiat-deposit-001", "request": "/api/v4/main-account/fiat-deposit-url", "nonce": 1594297865000 }'
# Generate a fiat deposit invoice (provider value from Asset Status).# The send_request() helper is defined in the Crypto Deposits tab.response = send_request("/api/v4/main-account/fiat-deposit-url", { "ticker": "EUR", "provider": "PROVIDER", "amount": "100", "uniqueId": "fiat-deposit-001",})invoice_url = response.json()["url"]print("Send the end user to:", invoice_url)
The uniqueId submitted in the /fiat-deposit-url request must appear in the SEPA payment-reference field of the bank-side transfer initiated by the end user. WhiteBIT uses this string to match the incoming SEPA settlement to the original deposit request. If the end user omits or alters it, the deposit may settle unmatched and require manual reconciliation through institutional support.
VISAMASTER Referer header: When using the VISAMASTER provider, configure the browser to send the Referer header when opening the invoice link. If the header is missing (e.g., when opening the link from a Telegram message or an email client that strips referrers), WhiteBIT redirects the end user to the homepage instead of the payment provider. Test the redirect path in the actual deployment surface (mobile app, email link, in-app web view) before go-live.
Create a fiat withdrawal using the same POST /api/v4/main-account/withdraw endpoint used for crypto, specifying a fiat ticker.The same withdrawal endpoints apply (/withdraw and /withdraw-pay). Use fiat-specific tickers such as EUR, UAH_IBAN, USD_VISAMASTER, EUR_VISAMASTER.The beneficiary object is required for fiat withdrawals with tickers UAH_IBAN, USD_VISAMASTER, EUR_VISAMASTER, USD, and EUR. Set partialEnable to true for increased maximum limits — the application must then handle status 18 (“Partially successful”).
Fiat withdrawals require KYC verification. Accounts without KYC verification cannot process fiat withdrawals.
In exceptional cases, the WhiteBIT institutional team may grant a per-account override that permits fiat withdrawal without standard KYC. This is exception-only — not a default capability. Contact institutional@whitebit.com for integrations with a documented case requiring the override.
WhiteBIT Codes enable fee-free value transfer between WhiteBIT accounts.WhiteBIT Codes are alphanumeric strings representing a fixed amount of a specific currency. One account creates a code, shares the code string via any channel, and another account applies the code to receive the funds.
Fee-free — no fees for creating or applying codes
Use cases: internal transfers between accounts, promotional distributions, settlement between sub-accounts or partner accounts
Optional passphrase protection (up to 25 characters)
State machine: A WhiteBIT Code moves through two states: created (an unredeemed code exists; the platform reserves the creator’s funds) and applied (terminal — the code has been redeemed; funds credited to the redeemer). There is no void or cancel operation; the creator cannot reclaim an unredeemed code.Apply failures: Codes may fail to apply for several reasons (expired, invalid format, non-existent, wrong passphrase). The apply response distinguishes an already-applied code and a code applied by its own creator; the platform collapses the remaining failure modes into a generic rejection. If a redeemer’s apply fails on a recently-created code, request a fresh code from the creator.Correlation: The code string is the only correlation key shared between creator and redeemer. The creator-side description field is creator-only and not exposed to the redeemer. Partners running redemption flows must map the code to an internal user ID on the partner side.
The code string is a bearer token — possession grants redemption, and the creator cannot reclaim an unredeemed code. A leaked code is spendable by whoever holds it.
Security model: Share codes through trusted channels and consider the optional passphrase for an additional protection layer. Passphrases accept Latin letters, digits, and ASCII symbols (no whitespace, no Unicode) up to 25 characters. Treat the code string as sensitive on the partner side: do not log it in plaintext, do not include it in error reports, do not commit it to version control.
The code lifecycle has two steps: create and apply.Create:POST /api/v4/main-account/codes — see the API ReferenceRequired parameters:
Parameter
Type
Description
ticker
string
Currency ticker (e.g., BTC, ETH)
amount
string
Amount to transfer (max precision: 18 decimal places; maximum value 1e17).
Optional parameters:
Parameter
Type
Description
passphrase
string
Passphrase for protection (up to 25 characters, Latin letters, digits, and ASCII symbols).
description
string
Description visible only to the creator (up to 280 characters).
async
boolean
Processing-mode flag accepted by the endpoint. Confirm the exact semantic with the institutional team before relying on it in production.
Key response fields:code — the generated WhiteBIT Code string to share with the redeemer; message — success message; external_id — external identifier.Rate limit: subject to platform-level rate limits — see Rate Limits for current enforced values.Apply:POST /api/v4/main-account/codes/apply — see the API ReferenceRequired parameters:
Parameter
Type
Description
code
string
The WhiteBIT Code string
Optional parameters:
Parameter
Type
Description
passphrase
string
Required if the code was created with a passphrase
async
boolean
Processing-mode flag accepted by the endpoint. Confirm the exact semantic with the institutional team before relying on it in production.
Rate limit: subject to platform-level rate limits — see Rate Limits for current enforced values.Webhook event:code.apply fires when an account applies a code.
When the currency held in Main balance differs from the currency the end user needs to withdraw, request a conversion quote, confirm it, and then submit the withdrawal. The Convert service handles balance routing internally — manual transfers between Main and Trade balances are not required.
Verify the source currency is available in Main balance.Endpoint:POST /api/v4/main-account/balance — API Reference
2
Request a conversion estimate
Request a quote for converting the source currency to the withdrawal currency. The response includes an id (quote identifier), the quoted rate, and expireAt (Unix timestamp).Endpoint:POST /api/v4/convert/estimate — API Reference
3
Confirm the conversion
Confirm the quote using quoteId from the estimate response. The conversion executes atomically.Endpoint:POST /api/v4/convert/confirm — API Reference
4
Create withdrawal request
Submit a withdrawal to the end user’s external address using the converted currency.Endpoint:POST /api/v4/main-account/withdraw or POST /api/v4/main-account/withdraw-pay — API Reference
5
Receive webhook confirmation
The withdraw.successful webhook fires when the withdrawal completes. See Webhooks for setup and signature verification.
6
Verify via history
Query the history endpoint to confirm the withdrawal status. See the Crypto Withdrawals tab for the full status state machine.Endpoint:POST /api/v4/main-account/history — API Reference
The convert service sets quote expiry per quote and returns the value in expireAt (Unix timestamp). Confirm the quote before that time elapses, or request a new estimate. See Convert for full parameter details, direction options, and history queries.
Common synchronous rejections from /convert/confirm and the recovery for each:
Error code
Cause
Recovery
20 (api.converter.quoteExpired)
The quote expired before confirmation
Request a new estimate and confirm within the quote window
37
Insufficient balance at confirm time — the platform re-checks the balance on confirm, and the balance can change within the quote window even when the estimate succeeded
Top up the Main balance or request a new estimate for a smaller amount
0 with the quoteId field key frontendServerSide.converter.quoteInvalid
The quote was already used or never existed — the response does not distinguish the two
Request a new estimate
Error message values may arrive as translation keys (e.g., api.converter.quoteExpired) rather than finalized English strings. Treat the code and the field name under errors as the stable contract.
Convert USDT to BTC and withdraw BTC to an external address. The estimate returns a short-lived quote — confirm it before it expires, or request a new one:The critical-path call is the estimate — every later step reuses identifiers from its response. The Crypto Deposits tab defines the send_request() helper used below.
Python
curl
# Request a conversion estimate (USDT → BTC). The response carries the# quote "id" for /convert/confirm, the "rate", and "expireAt".estimate = send_request("/api/v4/convert/estimate", { "from": "USDT", "to": "BTC", "direction": "from", "amount": "100",})data = estimate.json()print("Quote:", data["id"], "Rate:", data["rate"], "Expires at:", data["expireAt"])
# Request a conversion estimate (USDT → BTC). The response carries the# quote "id" for /convert/confirm, the "rate", and "expireAt".curl -X POST "https://whitebit.com/api/v4/convert/estimate" \ -H "Content-Type: application/json" \ -H "X-TXC-APIKEY: YOUR_API_KEY" \ -H "X-TXC-PAYLOAD: YOUR_PAYLOAD" \ -H "X-TXC-SIGNATURE: YOUR_SIGNATURE" \ -d '{ "from": "USDT", "to": "BTC", "direction": "from", "amount": "100", "request": "/api/v4/convert/estimate", "nonce": 1594297865000 }'
Reliable fund tracking requires both webhook-based and polling-based reconciliation.Primary method — webhooks for real-time notifications:
Configure the webhook URL in API key settings (see Webhooks)
Verify the HMAC-SHA512 signature on every incoming webhook. Each delivery includes three headers — X-TXC-APIKEY (the API key the webhook is bound to), X-TXC-PAYLOAD (base64-encoded JSON body), and X-TXC-SIGNATURE (HMAC-SHA512 of the payload with the API secret). See Security Best Practices for the verification algorithm.
Track the nonce field — each webhook nonce is strictly greater than the previous. The nonce travels inside the JSON payload, not in a separate header.
Retry policy: The platform retries failed deliveries over a 24-hour window — see Webhooks for the retry schedule.Fallback method — poll POST /api/v4/main-account/history:
Use transactionMethod: 1 for deposits, transactionMethod: 2 for withdrawals
Filter by status array for specific states
Recommended polling interval: every 5 minutes for active monitoring
For balance endpoints, WebSocket account streams, and polling-interval guidance beyond deposits and withdrawals, see Account Monitoring.Deduplication: Use the uniqueId from webhook payloads and history responses to deduplicate across webhook and polling paths.
The meaning of uniqueId differs by direction: for withdrawals, the value echoes the identifier supplied in the withdrawal request; for deposits, the platform assigns the value (the transaction identifier that the refund endpoint consumes as transactionId). Both are unique per transaction and safe as idempotency keys.
WhiteBIT does not offer a webhook replay mechanism. Implement polling as a fallback for outages longer than the 24-hour retry window. Store all processed uniqueId values to prevent double-processing.
Reconciliation pattern:
Receive webhook — verify signature — extract uniqueId and status
Store the event with uniqueId as the idempotency key
On polling cycle: query the history endpoint — compare uniqueId values against stored events
Process any events found via polling that the webhook path did not deliver
Mark transactions as complete only when the transaction reaches a terminal status (3/7 for success, 4/9 for canceled deposits, 4 for canceled withdrawals)