Skip to main content
Moving value in the Derive v3 API is always a signed action: your wallet (or a scoped session key) EIP-712-signs an Action envelope, and the protocol re-verifies the signature before applying it. Four methods cover the distinct destinations:

private/transfer_spot

Move collateral between two subaccounts you own.

private/transfer_spot_external

Send collateral to a subaccount owned by a different wallet, bounded by your recipient allow-list.

private/withdraw

Withdraw collateral on-chain to an L1 recipient address.

private/transfer_positions

Move open positions between subaccounts, booked as an RFQ trade.
Each method needs a specific protocol scope on the signing key, and each carries a nonce, signer, signature, and signature_expiry_sec built exactly as described in Action signing. The action module for each flow is filled in by the server and does not appear on the wire — it is part of the signed struct hash and must match the deployment’s module address in Action signing.
Amounts, prices, and fees are human decimals on the wire — decimal strings (e.g. "100.5") or JSON numbers. The exception is private/withdraw, whose on-chain amount uses the asset’s native ERC-20 decimals (see below).

Transfer collateral between your subaccounts

private/transfer_spot moves a spot balance from one of your subaccounts to another subaccount you own (existing, or a new one created in the same call). Positions are not moved by this method — use private/transfer_positions for that. Required scope: transfer:existing_subaccount or transfer:new_subaccount (see Access scopes).

Transfer collateral to another wallet

private/transfer_spot_external sends collateral to a subaccount owned by a different wallet. The destination owner must be on the sender’s whitelisted-recipient allow-list, and the signing key needs transfer:different_owner_subaccount. The parameters mirror private/transfer_spot, with one addition and one change in meaning:
recipient_address
string
required
Owner (wallet) of the destination account — must be whitelisted.
to_subaccount_id
integer
required
Recipient’s existing destination subaccount. 0 ⇒ create a new subaccount for the recipient.
new_subaccount_manager
integer
required
Manager id for the new subaccount when to_subaccount_id == 0.
All other fields (subaccount_id, asset_name, sub_id, amount, max_fee_usd, nonce, signer, signature, signature_expiry_sec) are as in private/transfer_spot, and the response returns op_uuid and operation_id.

Managing the recipient allow-list

External transfers can only reach wallets you have explicitly whitelisted. Manage the list with private/update_whitelisted_recipients, itself a signed action requiring the admin scope. The action carries an add set and a remove set; the new allow-list is (current ∪ add) \ remove. Removals are applied after additions.
wallet
string
required
Wallet whose allow-list is being updated; becomes the action owner.
add
string[]
required
Recipient wallet addresses to add.
remove
string[]
required
Recipient wallet addresses to remove.
nonce
string
required
Strictly-increasing anti-replay nonce.
signer
string
required
Address that produced signature.
signature
string
required
0x-prefixed 65-byte EIP-712 signature over the update action.
signature_expiry_sec
integer
required
Unix seconds after which the signed action is rejected.

Withdraw collateral on-chain

private/withdraw removes collateral from a subaccount and settles it to an Ethereum L1 recipient. It is a signed action requiring the withdraw scope.
amount_in_underlying is denominated in the asset’s native ERC-20 decimals (e.g. 6 for USDC), not the decimal convention used by the transfer methods above. Match the on-chain token’s decimals exactly.
subaccount_id
integer
required
Subaccount the collateral is withdrawn from.
asset_name
string
required
Collateral asset to withdraw.
amount_in_underlying
string
required
Amount in the asset’s native ERC-20 decimals.
force_batch
boolean
required
Whether to force the withdrawal into a settlement batch.
max_fee_usd
string
required
Maximum sequencer fee, in USD, the signer authorizes.
nonce
string
required
Strictly-increasing anti-replay nonce.
signer
string
required
Address that produced signature.
signature
string
required
0x-prefixed 65-byte EIP-712 signature over the withdraw action.
signature_expiry_sec
integer
required
Unix seconds after which the signed action is rejected.
The withdraw request does not carry an explicit L1 recipient field; the on-chain recipient in the signed action is resolved server-side (e.g. from the wallet’s registered L1 address). Confirm the recipient resolution for your target deployment against the API Reference tab before mainnet use.
public/withdraw_debug returns the EIP-712-encoded data and hashes for a withdraw action, so you can byte-compare against your local signing to diagnose rejected signatures. It is a debugging aid, not a required step — see Action signing for the full set of *_debug signing-preview helpers.

Transfer positions between subaccounts

private/transfer_positions moves open positions from one subaccount to another. It is booked as an RFQ-module trade: both sides sign a transfer quote over the same legs, and the transfer clears at the agreed prices. The signing key needs a transfer:* scope covering the destination (transfer:existing_subaccount, transfer:new_subaccount, or transfer:different_owner_subaccount). The request carries a maker_params and a taker_params object — each a signed transfer quote — plus wallet:
wallet
string
required
Wallet initiating the position transfer.
maker_params
object
required
Maker-side signed transfer quote: direction, legs, max_fee, subaccount_id, and the nonce / signer / signature / signature_expiry_sec signing fields.
taker_params
object
required
Taker-side signed transfer quote over the same legs, with its own max_fee and signing fields.
Both quotes sign the same legs hash; each side authorizes its own max_fee. The response returns the resulting maker_quote and taker_quote.
The legs fields for a transfer quote follow the RFQ leg shape; confirm the precise per-leg parameters against the the API Reference tab. See RFQ for the underlying quote-signing mechanics.