Skip to main content
The account transfer API provides an endpoint for transferring funds between spot and perpetuals accounts. A transfer request returns 202 Accepted when the request is accepted; you are notified of completion on the transfer_updates WebSocket channel.

POST /accounts/transfer

Initiate a fund transfer between spot and perpetuals accounts. The request returns 202 Accepted when accepted, and you are notified of completion on the transfer_updates WebSocket channel.
Authentication: Required (JWT or API Key)
Request Body:
Request Parameters: Asset Restrictions:
  • Only stablecoin assets can be transferred between spot and perps accounts.
  • The asset must be active as a stablecoin on both the spot and perps sides.
  • Use GET /perpetual/transfer-assets to fetch the list of transferable stablecoin assets.
Perpetual → Spot (perps as source): When transferring from a perps account to spot, the maximum transferable amount is capped per request: transferable_max = max(0, min(total_balance - locked_balance, available_balance)) × 80%
  • available_balance follows balance-query semantics (it includes unrealized PnL where applicable).
  • If amount exceeds transferable_max, the transfer is rejected with an insufficient-balance error.
Balance Notifications:
  • After a successful transfer, both the source and destination accounts emit balance update events over WebSocket so clients can refresh displayed balances without polling.
  • Spot balance updates are delivered on the spot_account.balance_update channel.
  • Perps balance updates are delivered on the perpetuals_account.balance_update channel.
Response (202 Accepted):
Response Fields: Status Codes:
  • 202 - Transfer request accepted and queued for processing
  • 400 - Invalid request parameters (non-stablecoin asset, invalid amount, etc.)
  • 401 - Authentication failed (missing or invalid JWT/API key)
  • 500 - Internal server error
  • 503 - Transfer validation service temporarily unavailable
Error Responses: 400 Bad Request - Invalid parameters:
Possible error codes:
  • invalid_request_format - Malformed JSON or missing required fields
  • invalid_amount - Amount is zero, negative, or invalid decimal
  • invalid_source_type - Source account type must be ‘spot’ or ‘perps’
  • invalid_dest_type - Destination account type must be ‘spot’ or ‘perps’
  • same_account_type - Source and destination types cannot be the same
  • invalid_asset - Asset is not supported for spot-perps transfer (not a stablecoin, not active, or not found)
  • amount_below_minimum - Amount is below minimum transfer amount for the asset
401 Unauthorized:
500 Internal Server Error:
Transfer Lifecycle: After a transfer is accepted:
  1. The request is validated and accepted, returning 202 Accepted with a transfer_id.
  2. Funds are debited from the source account, then credited to the destination account.
  3. When the transfer completes (or fails), the client is notified in real time on the transfer_updates WebSocket channel.
Transfer States: WebSocket Notification: When the transfer completes (or fails), you receive a real-time notification:
Important Notes:
  • Stablecoin Only: Only stablecoin assets that are active on both the spot and perps sides can be transferred
  • Perp → Spot cap: Outgoing perpetuals transfers are limited per request to 80% of min(total - locked, available) (see Perpetual → Spot above); plan amount accordingly or split into multiple transfers
  • Real-time Updates: Subscribe to WebSocket transfer_updates channel for completion notifications. Balance update notifications are also pushed to spot_account.balance_update and perpetuals_account.balance_update channels.
  • Source and destination types must be different (cannot transfer within the same account type)
Example Request: