Sending Stablecoins
Bitnob allows you to programmatically send USDT or USDC to any on-chain address across supported blockchain networks. This is a key capability for use cases like payouts, merchant disbursements, and remittances.
You cannot send less than $1. Transfers below this minimum will not be processed.
Supported Chains
The networks you can send on depend on the stablecoin and on your environment.
chain | sandbox | production |
|---|---|---|
arbitrum | — | USDT, USDC |
avalanche | USDT, USDC | USDT, USDC |
base | USDC | USDC |
bsc | — | USDT, USDC |
ethereum | USDT, USDC | USDT, USDC |
optimism | USDT, USDC | USDT, USDC |
plasma | — | USDT |
polygon | USDT, USDC | USDT, USDC |
solana | USDT, USDC | USDT, USDC |
tron | — | USDT |
Production-only chains: arbitrum, bsc, plasma, tron. Stablecoin amounts use 6 decimals on every chain, so 2000000 is 2 USDT.
Call GET /api/stablecoins/supported-chains to view the supported list for your account — see Stablecoins Supported Chains in the API reference.
Limits, Fees and Timing
item | detail |
|---|---|
Minimum per withdrawal | $1 |
Maximum per withdrawal | None |
Daily / monthly limit | None |
Fee | $1 on every chain, charged on top in the currency withdrawn |
Typical time to transfer.success | Depends on the chain; no longer than 15 minutes |
Endpoint
POST /api/withdrawals This endpoint triggers an on-chain withdrawal from your wallet to an external address. Full parameter and response documentation lives in the Create Withdrawal API reference.
Request Parameters
These map one-to-one to the withdrawal request fields in the API reference.
parameter | type | required | description |
|---|---|---|---|
to_address | string | Yes | Recipient's on-chain wallet address |
amount | string | Yes | Amount in the smallest unit of the currency (e.g., '2000000' for 2 USDT) |
currency | string | Yes | Stablecoin type (USDT, USDC) |
chain | string | Yes | Blockchain network, exactly as returned by GET /api/stablecoins/supported-chains (e.g., tron, ethereum, polygon, solana) |
reference | string | Yes | A unique identifier for the transfer |
description | string | No | Optional transfer description for your records |
Sample Request
Sample Response
A pending status here is expected — see Create Withdrawal for the full response shape and Error Responses for the failure codes.
Webhook Lifecycle
Once a transfer is created, Bitnob handles the on-chain broadcasting and confirmation tracking internally, moving it through the withdrawal status lifecycle. Your app will receive the following webhook events:
transfer.success – after enough confirmations (based on chain)
transfer.failed – if the transfer is rejected, reverted, or times out on-chain. The held funds return to your available balance
Best Practices
Idempotency: reference is required. Always generate a unique reference per transfer; a reference that already belongs to a withdrawal is rejected with 409 rather than sent again.
Fee Handling: The withdrawal fee is a flat $1, charged to your balance on top of the amount sent — the recipient receives the full amount you specify. It is the same on every chain and for any amount, so you can display the total before the user confirms. The create response does not carry a fee field; read fee from Get Transaction By ID Or Reference to reconcile.
Status Checking: Avoid polling — listen to transfer events via webhooks instead. If you do need to look one up, use Get Transaction By ID Or Reference.
Address Validation: Use the /api/addresses/validate endpoint — see Validate Address — to confirm the address is well-formed for the chain before sending. It checks the format only, not whether the address exists or whether your account can send on that chain. A withdrawal to an address in the wrong format is rejected with 400; a wrong-chain send that passes the format check is not recoverable once broadcast.