Skip to main content
This guide creates transfers to a crypto address, an email recipient, and a payment method in Sandbox, then shows how to validate, poll status, handle webhooks, and list transfers. The Sandbox does not connect to any blockchain network or settle funds on real fiat rails. Base URL: https://sandbox.cdp.coinbase.com

Prerequisites

Before you begin, you’ll need:
Install the CDP CLI (requires Node.js 22+):
Configure a Sandbox environment using your CDP Secret API Key JSON file from the CDP Portal:
Keep the API key secret. Never commit it to source control.
Install the SDK (requires Node.js 22+):
Export your API key credentials. CdpClient reads them from the environment automatically:
Initialize the client pointed at Sandbox:
main.ts
Keep API keys secret. Never commit them to source control.
See the Custodial Accounts Quickstart for setting up a Sandbox account with funds.Set the account ID:
Sandbox transfers do not move real funds. Crypto targets are placeholder addresses, email targets are mock recipients, and payment method targets simulate fiat rails. Do not use real recipient details when testing in Sandbox.

1. Create a transfer to a crypto address

Send USDC from the funded account to an external on-chain address. In Sandbox, use these reserved addresses to test specific outcomes: Send to the success address:

Reserved address failure responses

Use the same create-transfer payload as the success example and replace only target.address to test deterministic Sandbox failures:
Address: 0x2222222222222222222222222222222222222222Expected response: HTTP 400
Save the transfer ID for later steps:

2. Create a transfer to an email

Send USDC to a Coinbase user by email. In Sandbox, use these reserved test emails to avoid privacy issues with real addresses: Send to the success email:
Any email not listed above returns a 4xx error. This prevents Sandbox from validating real email addresses.

Reserved email failure responses

Use the reserved email addresses to exercise validation, synchronous execution, and asynchronous failure paths.
Use sandboxinvalidtarget@domain.com with execute: true.Expected response: HTTP 400

3. Create a fiat withdrawal to a payment method

Withdraw USD from the account to a bank-rail payment method (Fedwire, SWIFT, or SEPA). The rail is determined by the payment method itself. Sandbox auto-provisions mock payment methods on every entity. List them and pick one to use:
Send the withdrawal:

4. Validate before executing

Use validateOnly: true to verify recipient details before committing a transfer. This is useful for preflight checks on user-entered addresses or emails:
A 200 response means the transfer would succeed. A 4xx response contains an errorType explaining why validation failed.
validateOnly and execute are mutually exclusive. Do not set both to true.

5. Check transfer status

Poll the transfer to see its current status:

6. Handle webhooks

In production, subscribe to payments.transfers.* events to receive real-time status updates rather than polling. See Webhooks for setup. Events fired for a successful transfer:
  1. payments.transfers.processing, transfer is executing
  2. payments.transfers.completed, transfer succeeded
Events fired for a failed transfer:
  1. payments.transfers.processing, transfer is executing
  2. payments.transfers.failed, transfer failed; inspect failureReason

7. List transfers

View all transfers for your entity:

Move to production

To run this flow on real rails, switch from the Sandbox base URL to the production base URL and use a production API key. Production transfers move real funds: crypto targets settle on-chain, email targets credit real Coinbase users, and payment method targets execute on Fedwire, SWIFT, or SEPA.

Transfers overview

Transfer types, fee quotes, travel rule, and lifecycle

Deposit Destinations

Receive inbound crypto into a custodial account

Webhooks

Subscribe to real-time transfer status events

REST API reference

Create, execute, list, and get transfers