Introduction
The On-chain Transfers API enables inbound and outbound transfers of cryptocurrencies via their native blockchain networks. Bipa manages hot wallets with institutional-grade security via Fireblocks.Multi-network USDT
Support for Ethereum, Polygon, Tron, Arbitrum, and Optimism
Bitcoin
Native Bitcoin transfers on the Bitcoin network
Institutional custody
Multi-sig wallets secured by Fireblocks
Auto-conversion
Optional auto-convert inbound transfers to BRL
Supported assets & networks
USDT
| Network | Confirmations | Inbound time | Outbound time |
|---|---|---|---|
| Polygon | 128 blocks | ~5 minutes | ~2 minutes |
| Arbitrum | 64 blocks | ~2 minutes | ~1 minute |
| Optimism | 64 blocks | ~2 minutes | ~1 minute |
| Tron | 20 blocks | ~1 minute | ~1 minute |
| Ethereum | 12 blocks | ~3 minutes | ~3 minutes |
Bitcoin
| Network | Confirmations | Inbound time | Outbound time |
|---|---|---|---|
| Bitcoin | 3 blocks | ~30 minutes | ~10-60 minutes |
Polygon and Arbitrum are recommended for USDT due to lower fees and faster confirmations.
The transfer object
Attributes
| Attribute | Type | Description |
|---|---|---|
id | string | Unique transfer identifier |
customer_id | string | Customer who owns the transfer |
direction | string | inbound or outbound |
asset | string | USDT or BTC |
network | string | Blockchain network |
amount_gross | string | Total amount in smallest unit (for outbound: net + fee) |
amount_net | string | Net amount in smallest unit (credited/received) |
fee | string | Network fee in smallest unit (0 for inbound) |
decimals | integer | Decimal places for the asset (6 for USDT, 8 for BTC) |
status | string | Transfer status |
address | string | Deposit address (inbound only) |
destination_address | string | Recipient address (outbound only) |
tx_hash | string | Transaction hash |
confirmations | integer | Current confirmations |
confirmations_required | integer | Required confirmations |
created_at | string | ISO 8601 timestamp |
confirmed_at | string | ISO 8601 confirmation timestamp |
Transfer statuses
| Status | Description |
|---|---|
pending | Waiting for transaction to be broadcast |
processing | Transaction broadcast, awaiting confirmations |
confirmed | Required confirmations reached, credited/sent |
failed | Transfer failed |
Inbound transfer flow
Outbound transfer flow
Endpoints
Create Deposit Address
Create an address to receive inbound transfers
Create Transfer
Create an outbound transfer to external address
Get Transfer
Retrieve transfer details
List Transfers
List all on-chain transfers
Fees
Inbound fees
Inbound transfers (deposits) are free. Bipa covers network fees for incoming transactions.Outbound fees
| Asset | Network | Fee |
|---|---|---|
| USDT | Polygon | 1 USDT |
| USDT | Arbitrum | 1 USDT |
| USDT | Optimism | 1 USDT |
| USDT | Tron | 1 USDT |
| USDT | Ethereum | 3-25 USDT (dynamic) |
| BTC | Bitcoin | Dynamic (based on mempool) |
Bitcoin transfers are always sent with fast priority. Fees vary based on network congestion and are shown before confirmation.
Amount encoding
All monetary amounts are returned as string-encoded integers in the asset’s smallest unit to avoid floating-point precision issues. This is the industry standard for financial and blockchain APIs.Decimal places by asset
| Asset | Decimals | Smallest unit | Example |
|---|---|---|---|
| USDT | 6 | 0.000001 USDT | "100000000" = 100 USDT |
| BTC | 8 | 1 satoshi | "1000000" = 0.01 BTC |
Amount fields
For every transfer, four amount-related fields are returned:| Field | Type | Description |
|---|---|---|
amount_gross | string | Total amount in smallest unit |
amount_net | string | Net amount in smallest unit |
fee | string | Fee in smallest unit |
decimals | integer | Decimal places for the asset |
Conversion examples
USDT (6 decimals):Code examples
- JavaScript
- Python
- Go
Outbound transfer example
When sending 100 USDT on Polygon (1 USDT fee):| Field | Value | Human-readable |
|---|---|---|
amount_net | "100000000" | 100.000000 USDT (recipient receives) |
fee | "1000000" | 1.000000 USDT |
amount_gross | "101000000" | 101.000000 USDT (deducted from balance) |
decimals | 6 | — |
Webhooks
| Event | Description |
|---|---|
onchain.transfer.pending | Transfer detected, awaiting confirmations |
onchain.transfer.confirmed | Transfer confirmed and processed |
onchain.transfer.failed | Transfer failed |
