Skip to main content
Transfers represent both the request and execution of a fund movement from a source to a target. They provide upfront fee quotes and track the complete lifecycle from initiation through completion or failure.

Transfer types

Transfer typeSourceTargetTypical use
Crypto withdrawalCustodial accountExternal onchain addressPay a customer, settle to chain
Email transferCustodial accountCoinbase user by emailSend USDC to a Coinbase user
Fiat withdrawalCustodial account (USD)Payment method (bank)Fedwire/SWIFT/SEPA payout
Inbound depositExternal onchain addressCustodial accountReceive crypto (via deposit destination)

Lifecycle

Transfers move through a simple lifecycle from quote to execution outcome.

Transfer statuses

StatusDescriptionRecommended action
quotedTransfer is quoted. May be a waiting state (execute: false) or transient before execution (execute: true).If manual, call Execute a Transfer before quote expiry.
processingTransfer is executing.No action needed; monitor via Webhooks.
completedTransfer completed successfully.No action needed.
failedFailed due to execution error or quote expiry.Inspect failureReason, review Errors, then create a new transfer if needed.

Execution modes

ModeBehaviorWhen to use
execute: trueTransfer quotes then auto-executesMost production flows
execute: falseTransfer remains in quoted until you call /executeShow users fee quote before confirming

Fee quotes

Every transfer provides a comprehensive fee quote in the fees array before any money moves.
Fee typeDescription
bankTraditional banking fees (e.g., wire transfer fees)
conversionAsset conversion/exchange fees
networkBlockchain network fees (gas costs)
otherOther processing fees
To review fees before execution:
  1. Create a transfer with execute: false
  2. Review the fees array in the response
  3. Call POST /v2/transfers/{transferId}/execute when ready to proceed
{
  "fees": [
    { "type": "bank", "amount": "15.00", "asset": "usd" },
    { "type": "conversion", "amount": "1.00", "asset": "usd" },
    { "type": "network", "amount": "0.001", "asset": "eth" }
  ]
}
Fee quotes expire — the expiresAt field shows the deadline. If you use execute: false, you must call /execute before expiresAt.

Amount types

The amountType field controls whether the given amount is sent from source or received at target:
amountTypeBehavior
source (default)Target receives the amount minus fees
targetTarget receives the exact amount; fees are added to the source amount
Example — send exactly $100 to recipient, fees paid by sender:
{
  "amount": "100.00",
  "amountType": "target"
}

Supported rails and settlement times

Transfer typeRailAssetTypical settlement
Crypto withdrawalOnchainUSDC, ETH, BTC, etc.Minutes (network dependent)
Email transferOff-chainUSDC, USDInstant
Fiat withdrawalFedwireUSDSame day / next day
Fiat withdrawalSWIFTUSD1–5 business days
Fiat withdrawalSEPAEUR1–2 business days

Exchange rate

For transfers involving currency conversion, the exchangeRate object provides rate information:
{
  "exchangeRate": {
    "sourceAsset": "usd",
    "targetAsset": "btc",
    "rate": "0.00001"
  }
}
The rate indicates how many units of the target asset equal one unit of the source asset.

Transfer validation

Use validateOnly: true to validate transfer parameters without creating a transfer. Useful for preflight checks.
validateOnly and execute are mutually exclusive. Setting both to true returns a 400 error.
See Transfer Validation for complete request/response examples, validation errors, and sandbox guidance.

Outcomes

Completion

When a transfer reaches completed status, it contains the final execution details:
  • completedAt — When the transfer finished
  • executedAt — When the transfer moved from quoted to processing
  • targetAmount — The actual amount delivered to the target
  • details — Additional information (e.g., deposit destination reference)
{
  "transferId": "transfer_af2937b0-9846-4fe7-bfe9-ccc22d935114",
  "status": "completed",
  "source": {
    "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "network": "base",
    "asset": "usdc"
  },
  "target": {
    "accountId": "account_af2937b0-9846-4fe7-bfe9-ccc22d935114",
    "asset": "usdc"
  },
  "sourceAmount": "100.00",
  "sourceAsset": "usdc",
  "targetAmount": "100.00",
  "targetAsset": "usdc",
  "completedAt": "2026-01-01T00:05:00Z",
  "executedAt": "2026-01-01T00:01:30Z",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:05:00Z",
  "details": {
    "depositDestination": {
      "id": "depositDestination_af2937b0-9846-4fe7-bfe9-ccc22d935114"
    },
    "onchainTransactions": [
      {
        "transactionHash": "0x363cd3b3d4f49497cf5076150cd709307b90e9fc897fdd623546ea7b9313cecb",
        "network": "base"
      }
    ]
  }
}

Failure

When a transfer fails, the failureReason field contains a human-readable description of what went wrong. A transfer can reach failed status in two ways:
  • Execution error — the transfer was executing and encountered an error (e.g., insufficient balance, network failure).
  • Quote expiration — the transfer was in quoted status and the fee quote expired before /execute was called. Create a new transfer to get a fresh quote.
{
  "status": "failed",
  "failureReason": "Insufficient balance to complete this transfer."
}

Travel rule

For transfers requiring travel rule compliance, include the travelRule object with originator and beneficiary details.
FieldDescription
isSelfWhether the receiving wallet belongs to the sender
isIntermediaryWhether Coinbase is acting as an intermediary VASP
originatorInformation about the sender (name, address, VASP details)
beneficiaryInformation about the receiver (name, address, wallet type)
Set isIntermediary: true when your organization is a VASP using Coinbase to send crypto on behalf of your end customer. You must then provide the originator object with the sender’s details and your VASP information.
{
  "travelRule": {
    "isSelf": false,
    "isIntermediary": true,
    "originator": {
      "name": "John Doe",
      "address": {
        "line1": "123 Main St",
        "city": "San Francisco",
        "postCode": "94105",
        "countryCode": "US"
      },
      "virtualAssetServiceProvider": {
        "name": "Your VASP Name",
        "identifier": "5493001KJTIIGC8Y1R17"
      }
    },
    "beneficiary": {
      "name": "Jane Smith",
      "walletType": "custodial"
    }
  }
}

Webhooks

Subscribe to payment.transfer.* events to receive real-time status updates as transfers move through their lifecycle. See Webhooks for setup instructions.

Next steps

Quickstart

Create your first transfer in Sandbox

Example payloads

Payload shapes for each source/target type

Validation

Preflight checks and validation errors

Webhooks

Subscribe to transfer status events