Overview
CDP offers two types of webhook subscriptions for monitoring wallet activity:- Transaction Webhooks — Track the full lifecycle of transactions sent from your wallets using
wallet.transaction.*events (created, broadcast, confirmed, failed, and more). - Onchain Data Webhooks — Monitor onchain token transfers (ERC-20) into and out of any address, even for non-CDP wallets, using
onchain.activity.detectedorwallet.activity.detectedevents.
Transaction webhooks work the same way for both Server Wallets and Embedded Wallets.
Transaction webhooks
Transaction webhooks let you subscribe to real-time events that track the full lifecycle of transactions sent from your CDP wallets. Events fire as your transaction moves through each stage — from creation to confirmation or failure. Use transaction webhooks when you need to:- Monitor whether a transaction has been signed, broadcast, or confirmed
- Detect stuck or pending transactions and take action (e.g., submit a replacement)
- Build reliable transaction status tracking without polling
Event types
The following event types cover the full transaction lifecycle:| Event | Description |
|---|---|
wallet.transaction.created | Transaction is created |
wallet.transaction.signed | Transaction is signed |
wallet.transaction.broadcast | Transaction is broadcast to the network |
wallet.transaction.pending | Transaction stuck in mempool for more than 30 seconds |
wallet.transaction.replaced | Transaction replaced an existing pending transaction |
wallet.transaction.confirmed | Transaction confirmed onchain |
wallet.transaction.failed | Transaction failed onchain or was replaced |
Creating a subscription
Use the SDK to create a webhook subscription for transaction lifecycle events:EVM
Supported events
All transaction lifecycle events are supported on EVM:| Event | Description |
|---|---|
wallet.transaction.created | Transaction is created |
wallet.transaction.signed | Transaction is signed (signEvmTransaction) |
wallet.transaction.broadcast | Transaction is broadcast to the network |
wallet.transaction.pending | Transaction stuck in mempool for more than 30 seconds |
wallet.transaction.replaced | Transaction replaced an existing pending transaction |
wallet.transaction.confirmed | Transaction confirmed onchain |
wallet.transaction.failed | Transaction failed onchain or was replaced |
Webhook payload
EVM payloads include thetransaction_hash and the address of the account that sent the transaction.
Confirmed event:
pending event includes gas parameters so you can evaluate whether to submit a replacement transaction with higher gas.
Solana
Supported events
Solana supports a subset of transaction lifecycle events. Thepending and replaced events are not supported because Solana does not have a mempool or transaction replacement mechanism.
| Event | Description |
|---|---|
wallet.transaction.created | Transaction is created |
wallet.transaction.signed | Transaction is signed (signSolanaTransaction) |
wallet.transaction.broadcast | Transaction is broadcast to the network |
wallet.transaction.confirmed | Transaction confirmed onchain |
wallet.transaction.failed | Transaction failed onchain |
Webhook payload
Solana payloads usetransaction_signature instead of transaction_hash and do not include an address field.
Confirmed event:
Transaction lifecycle scenarios
The events you receive depend on how the transaction progresses through the network.Transaction confirmed successfully
The most common path: a transaction is created, broadcast, and confirmed onchain.Transaction failed onchain
The transaction was broadcast but failed during execution (e.g., reverted).Transaction replaced
When a stuck transaction is replaced with a new one (e.g., with higher gas), the original and replacement each emit separate events.| Transaction | Events |
|---|---|
| Original (stuck) | failed |
| Replacement | broadcast → replaced → confirmed or failed |
failed event because it will never land onchain. Handle the old transaction failure accordingly.
Transaction stuck > 30 seconds (EVM only)
If a transaction remains pending in the mempool for more than 30 seconds, apending event fires with gas parameters. You can use this to decide whether to submit a replacement transaction or continue waiting.
Transaction monitoring expires (EVM only)
If a transaction is still pending when the monitoring window expires, no further events are fired.Best practices
Verify webhook signatures
Verify webhook signatures
Always verify the signature on incoming webhook payloads using the
secret returned when you created the subscription. This ensures the payload is genuinely from CDP and has not been tampered with. See Verify webhook signatures for implementation details.Handle monitoring window expiry
Handle monitoring window expiry
CDP guarantees at-least-once delivery for all webhook events fired within the monitoring window. Most transactions confirm well within this period. In the rare case that a transaction is still pending when the monitoring window expires (3 minutes for EVM, 2 minutes for Solana), no further events are fired. You can query the network at that point to check whether the transaction is still pending, has since confirmed, or has failed.
Handle the pending event correctly
Handle the pending event correctly
The
pending event means a transaction has been in the mempool for more than 30 seconds — it does not mean the transaction failed. When you receive a pending event, you can:- Submit a replacement transaction with higher gas (using the gas parameters in the payload)
- Continue waiting for a
confirmedorfailedevent
Onchain data webhooks
This section shows how to use Onchain Data Webhooks from a Server Wallet workflow to create webhook subscriptions via our REST endpoints and receive events at your target destination. This is a Server Wallet-focused adaptation of the Onchain Data Webhooks flow, tailored for use cases such as tracking USDC transfers into and out of wallet addresses.Prerequisites
Before setting up your webhook subscription, make sure you have the following:A Secret API Key
A Secret API Key
Sign up at portal.cdp.coinbase.com, then navigate to API Keys and select Create API key under the Secret API Keys tab.
- Enter an API key nickname (restrictions are optional)
- Click Create
- Secure your API Key ID and Secret in a safe location
A webhook URL
A webhook URL
You’ll need an HTTPS URL to receive webhook events. For quick testing, webhook.site gives free temporary URLs instantly.For production, use your own HTTPS endpoint.
cdpcurl
cdpcurl
Install
cdpcurl to make authenticated requests to CDP APIs:A CDP Server Wallet address
A CDP Server Wallet address
If you don’t already have one, follow the Server Wallet v2 Quickstart.After completing it, you should have an EVM wallet address to use as
WALLET_ADDRESS.Funding is not required to create a webhook subscription. Funding is required only if you want to trigger and validate live transfer events.
Local environment variables configured
Local environment variables configured
Set these once in your terminal so you can run the commands in this guide as-is.
This guide defaults to Base Sepolia for testnet validation.
USDC_CONTRACT_ADDRESS tells the webhook which token contract to watch. Without this filter, your subscription may match transfers from other tokens too. The value shown above is the USDC contract on Base Sepolia (testnet).1. Prepare subscription payload
In this example, you will track USDC transfers in or out of your CDP Server Wallet. Each subscription listens foronchain.activity.detected events on the USDC contract, filtered by your wallet address using the params.from and params.to labels.
- Outgoing transfers
- Incoming transfers
Run this to create
outgoing-usdc.json using your exported env vars:You can filter on any ERC-20 event parameter using
params.[any_param] in labels (e.g. params.from, params.to, params.value). See the configuration fields table in the Onchain Data Webhooks Quickstart for the full list of supported label filters.Alternative: monitor all wallet activity with wallet.activity.detected
Alternative: monitor all wallet activity with wallet.activity.detected
Use this when:Then create both subscriptions using the same
- You want to track all ERC-20 tokens, not just USDC
- You don’t need contract-level filtering
- You prefer fewer labels and simpler setup
cdpcurl commands from step 2, replacing outgoing-usdc.json / incoming-usdc.json with outgoing-wallet.json / incoming-wallet.json.2. Subscribe to transfer events
Using the configurations you created in the previous step, create webhook subscriptions usingcdpcurl.
- Outgoing transfers
- Incoming transfers
response.json
3. Verify webhook event capture
Use the CDP Faucet to send 1 USDC to your wallet and confirm the webhook fires.Send USDC via CDP Faucet
Open the CDP Faucet, select Base Sepolia + USDC, paste your
WALLET_ADDRESS, and click Send.Check your webhook URL
Open your
WEBHOOK_URL and wait for an incoming POST request. You should receive an onchain.activity.detected payload similar to:Confirm the event matches your filter
Check that
parameters.to matches your WALLET_ADDRESS you exported in the prerequisites. This confirms your subscription to incoming transfer events is working successfully.To test outgoing, send USDC from your wallet and confirm parameters.from matches. See Transferring tokens from a CDP Wallet.What to read next
Create webhook subscription
Full reference for supported event types, label filters (
params.*, transaction_from, transaction_to), and advanced optionsOnchain Data Webhooks Overview
Learn more about webhook capabilities, delivery guarantees, and supported use cases
Verify Webhook Signatures
Validate that webhook payloads are genuinely from CDP
Sending Transactions
Learn about the Sign and Send APIs for EVM transactions