Skip to main content
To execute a transfer, make a POST request to /v1/wallets/{wallet_id}/transfer.

Body

In the body of the request, pass the following parameters.
object
required
The source asset, amount, and chain for the transfer. Specify either asset (for named assets) or asset_address (for custom assets), not both.
object
required
The destination for the transfer.
string
Amount as a decimal string in standard units (e.g. "10.0" for 10 USDC). For exact_input, the amount to send. For exact_output, the exact amount to receive. Takes precedence over source.amount when both are provided.
'exact_input' | 'exact_output'
Whether the amount refers to the input token (exact_input) or the output token (exact_output). Defaults to exact_input.
  • exact_input — the specified amount is deducted from the source wallet; the destination amount varies based on fees and bridge pricing.
  • exact_output — the recipient receives exactly the specified amount; the source amount is determined by the bridge provider and may be higher due to fees.
Exact output is only supported for cross-chain or cross-asset (DADC) transfers on EVM source chains. Solana is not supported as a source chain for exact output.
integer
The maximum allowed slippage in basis points (1 bps = 0.01%). Must be between 0 and 10000. Only applies to cross-chain and cross-asset transfers. If omitted, an appropriate slippage tolerance is automatically determined based on current market conditions. See slippage for details.
object
Optional fee configuration for cross-chain transfers.

Response

The endpoint returns a 200 response with a pending wallet action resource.
The transfer action is processed asynchronously. The response contains a pending wallet action resource with status: "pending" that Privy processes in the background.
string
The unique identifier for the wallet action.
'pending' | 'succeeded' | 'rejected' | 'failed'
The current status of the action.
string
The ID of the wallet initiating the transfer.
string
The ISO 8601 timestamp for when the action was created.
'transfer'
The type of action. For transfers, this is always transfer.
'exact_input' | 'exact_output'
The amount type used for this transfer. Omitted when the default exact_input was used.
string
The named asset being transferred (e.g. "usdc", "eth"). Present when the transfer was initiated with a named asset; omitted for custom-token transfers.
string
The token contract address (EVM) or mint address (Solana) of the transferred asset. Present when the transfer was initiated with asset_address.
integer
The number of decimals for the transferred token. Present when the transfer was initiated with asset_address and the decimals were resolved on-chain.
string
The amount sent on the source chain as a decimal string (e.g. "1.5"). Omitted for exact_output cross-chain transfers until the source amount is determined.
string
The chain the transfer is sent from (e.g. "tempo", "ethereum").
string
The recipient wallet address.
string
The destination asset for cross-asset transfers. Omitted for same-asset transfers.
string
The destination chain for cross-chain transfers. Omitted for same-chain transfers.
string
The amount received on the destination chain. Populated immediately for exact_output transfers, or after fill confirmation for exact_input cross-chain transfers.
FeeLineItem[]
Fees paid for the transfer. Each item has a type (relayer or developer) and an amount in USD. Items of type developer include a recipient address.
object
Present on rejected or failed actions when available. Contains a message string with a human-readable description of the failure, and an optional details field with additional context.
To track the status of a transfer, see wallet action lifecycle.

Examples

Use the transfer convenience method on the wallets service to transfer tokens from a wallet.
The method returns a TransferActionResponse with the pending wallet action. See wallet action lifecycle to track the status.
To send exactly 100 USDC to a recipient on Arbitrum from a Tempo wallet:
For exact_output cross-chain transfers, source_amount is null at creation because the exact source amount is determined by the bridge provider at execution time. It is populated once the transfer is confirmed on-chain.

API reference

See the API reference for more details.