Create an internal transfer
Moves balance between two CBPay accounts, atomically and always free of charge — any combination works: person to person, person to company, company to person or company to company. Works with the four virtual balances (USDT default, USDC, BTC, GOLD) and always between balances of the same currency (no conversion). The destination is resolved by to_account_id, to_email, to_phone (OTP-verified phones only) or to_contact_id. Every transfer saves the recipient as a contact automatically (opt out with save_contact: false). The recipient’s webhook subscribers receive transfer_received.
Authorizations
Session JWT (from register/login) or API key (pk_...).
X-API-Key: <token> is accepted as an alternative header.
Headers
Alternative to the idempotency_key body field.
Body
Positive decimal string, up to the currency's decimals (6 for USDT/USDC/GOLD, 8 for BTC).
"10.500000"
E.164 phone of the destination account. Only accounts with an OTP-verified phone resolve (404 recipient_not_found otherwise; 422 recipient_ambiguous if more than one account shares the number).
Send straight to a contact from your book (uses its linked CBPay account, or its verified phone).
Profile QR token of the destination account (scanned from its CBPay QR). Also accepts the extended checkout QR payload (cbpay:pay?to=…&checkout=…) — the embedded checkout token is honored automatically.
Optional token of a universal checkout link to pay directly. The destination is forced to the link's account and the amount must cover the due quoted server-side in the chosen asset (422 checkout_amount_mismatch with the updated due otherwise). On completion the link is settled and auto-converted to its settlement_asset.
Balance currency to move; the destination receives in this same currency.
USDT, USDC, BTC, GOLD The destination is saved as a contact automatically; send false to skip it.