Webhooks & Notifications
Real-time push notifications through webhooks organized into three streams. Subscribe per vault to receive events as they happen.
Webhook Streams
| Stream | Scope | What It Covers |
|---|---|---|
| Outgoing | Per vault | Full lifecycle of transactions created within the platform |
| Blockchain | Per vault | All blockchain transactions affecting vault addresses (outgoing + external) |
| Incoming | Per vault | Incoming deposits with balance changes and confirmations |
Setup Subscriptions
Configure webhook subscriptions per vault:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://your-app.com/webhooks/carabaas",
"streams": ["outgoing", "incoming", "blockchain"]
}' \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}
Get Subscription Info
curl -H "Authorization: Bearer $TOKEN" \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}
Delete Subscriptions
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}
Confirmation Settings
Configure how many blockchain confirmations trigger the final confirmation event:
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"confirmations": {
"bitcoin-mainnet": 3,
"ethereum-mainnet": 12,
"polygon-mainnet": 30
}
}' \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}/confirmations
Outgoing Stream
The outgoing stream tracks the full lifecycle of transactions created within the platform. Each state transition emits a notification.
Transaction Lifecycle Events
Success Flow
| Type | Fields | Description |
|---|---|---|
pending | quorum, approvals | Transaction created, no quorum configured |
approval-pending | quorum, approvals | Waiting for M-of-N approvals |
approved | quorum, approvals | One approval received (sent per approval) |
warning | reasonCode | Insufficient balance — waiting up to 72h |
requested | — | Approved and queued for processing |
inited | — | Blockchain transaction built |
master-approval-pending | — | Waiting for master approval (binds order to blockchain tx) |
master-approved | — | Master approval received |
signed | — | MPC signature completed |
submitted | blockchainHash | Broadcast to blockchain |
mined | blockchainHash, balanceChanges | Confirmed on-chain with balance changes |
Failure Events
| Type | Fields | Description |
|---|---|---|
warning | reasonCode | Insufficient balance — platform retries for up to 72h |
cancelled | reasonCode | Cancelled (e.g., insufficient balance after 72h, or declined) |
failed | blockchainHash | Transaction failed on-chain (e.g., reverted) |
rolledback | blockchainHash | Transaction rolled back after submission |
replaced | blockchainHash | Transaction replaced (e.g., RBF on Bitcoin) |
Common Notification Fields
Every outgoing notification includes:
| Field | Description |
|---|---|
stream | Always "outgoing" |
type | Event type (see tables above) |
vaultId | Vault the transaction belongs to |
accountId | Account within the vault |
addressId | Source address |
network | Blockchain network |
orderId | Your unique order identifier |
transactionId | Platform transaction ID |
destinationAddress | Recipient blockchain address |
timestamp | Event timestamp (Unix ms) |
Enriched Context
Notifications include full context about the account and address involved — you don't need additional API calls to identify the source:
| Field | Description |
|---|---|
account.name | Account name (e.g., "hot-wallets") |
account.data | Custom metadata you set on the account |
address.name | Address name (e.g., "customer-12345") |
address.networkAddress | On-chain address string |
address.hdpath | HD derivation path |
address.data | Custom metadata you set on the address |
address.memo | Memo/tag value (for Stellar, Ripple, Cosmos) |
This is especially useful for deposit attribution — match incoming funds to a customer by address.name, address.data, or address.memo directly from the webhook payload, without querying the API.
Example: Mined Notification
{
"stream": "outgoing",
"type": "mined",
"vaultId": "cai3GvhueQApTaCcUtjai9",
"network": "ethereum-sepolia",
"accountId": "eFjwUQXB8CMnrTHSgYzaL6",
"addressId": "gMP71sR5sNUnGdKFTsNzp6",
"destinationAddress": "0x3f06F88431d30067a7E87BB87957d008ADCc3bA7",
"orderId": "59850710-3998-4347-8c82-0d625bac9bbb",
"transactionId": "suoPF5JPqgo2NvMmMfR6mg",
"blockchainHash": "0x6a925762547de72487bb1cce0c95226e8e9cf24d...",
"metadata": {
"asn": "4",
"gas": "21000",
"gasUsed": "21000",
"gasPrice": "1200010",
"isContractCall": false
},
"balanceChanges": [
{
"asset": "c1",
"amount": "-14000000000000000",
"amountFormatted": {
"asset": { "name": "ETH Sepolia", "decimals": 18, "type": "native" },
"value": "-0.014"
},
"address": {
"id": "gMP71sR5sNUnGdKFTsNzp6",
"networkAddress": "0xF3fC7B157615c5eD88f87d05f24C4C8E0c8D6A42",
"network": "@eth-like",
"hdpath": "m/44/60/0/0/1",
"name": "hot-wallet:eth-like",
"data": { "purpose": "operations" }
},
"account": {
"id": "eFjwUQXB8CMnrTHSgYzaL6",
"name": "hot-wallets",
"data": {}
}
}
]
}
Example: Warning (Insufficient Balance)
{
"stream": "outgoing",
"type": "warning",
"reasonCode": "insufficient_balance",
"orderId": "77566f66-634e-4c0f-adce-2adc0bce7dd7",
"transactionId": "ooRPCgGMpeB1a13HG1Ajyj",
"network": "ethereum-sepolia",
"vaultId": "4inhhkumdUQAuvNnM77qQs",
"accountId": "43ta6eUh3qmWFZVmMCfNP1",
"addressId": "sd3hr3UQLFX5zUwPXqSk3o",
"destinationAddress": "0xe8d5a90ba593ad8fbc7d40de4dfc8b7f269f9cb2",
"timestamp": 1758633267120
}
Blockchain Stream
The blockchain stream reports all on-chain transactions affecting vault addresses — both outgoing (your transactions) and external (third-party transfers to or from your addresses). Scoped to a specific vault.
Event Types
| Type | Description |
|---|---|
transaction | A blockchain transaction affecting a vault address |
mempool | Transaction detected in mempool (Bitcoin only) |
confirmation | Confirmation count update for a tracked transaction |
Common Fields
| Field | Description |
|---|---|
stream | Always "blockchain" |
type | Event type |
vaultId | Vault whose addresses are affected |
network | Blockchain network |
blockchainHash | On-chain transaction hash |
balanceChanges | Array of balance changes per address and asset |
confirmations | Current confirmation count |
Incoming Stream
The incoming stream tracks deposits to vault addresses from mempool detection through confirmations and potential rollbacks.
Event Types
| Type | Description |
|---|---|
mempool | Deposit detected in mempool before block inclusion |
confirmation | Deposit confirmed with current confirmation count |
rollback | Previously seen deposit rolled back after reorg |
Common Fields
| Field | Description |
|---|---|
stream | Always "incoming" |
type | Incoming event type (mempool, confirmation, rollback) |
vaultId | Vault receiving the deposit |
accountId | Account within the vault |
addressId | Receiving address |
network | Blockchain network |
blockchainHash | On-chain transaction hash |
transactionId | Platform transaction ID |
orderId | Auto-assigned order ID for the deposit |
confirmations | Current confirmation count |
balanceChanges | Array of balance changes with formatted values |
metadata | Network-specific metadata (gas, contract call, etc.) |
Example: Incoming Deposit
{
"stream": "incoming",
"type": "confirmation",
"network": "ethereum-sepolia",
"blockchainHash": "0xc2cc27bdcee3e369a05fe740da898de8b8ace653...",
"vaultId": "cai3GvhueQApTaCcUtjai9",
"transactionId": "d6ZktNHf45cVdHTufyrwU2",
"orderId": "29270015-c058-40be-9303-003502234cf8",
"accountId": "eFjwUQXB8CMnrTHSgYzaL6",
"addressId": "gMP71sR5sNUnGdKFTsNzp6",
"metadata": {
"asn": "0",
"gas": "21000",
"gasUsed": "21000",
"gasPrice": "1200015",
"isContractCall": false
},
"balanceChanges": [
{
"asset": "c1",
"amount": "49999974799685000",
"amountFormatted": {
"asset": { "name": "ETH Sepolia", "decimals": 18, "type": "native" },
"value": "0.049999974799685"
},
"address": {
"id": "gMP71sR5sNUnGdKFTsNzp6",
"networkAddress": "0xF3fC7B157615c5eD88f87d05f24C4C8E0c8D6A42",
"network": "@eth-like",
"hdpath": "m/44/60/0/0/1",
"name": "customer-12345",
"data": { "mid": "cust-12345" }
},
"account": {
"id": "eFjwUQXB8CMnrTHSgYzaL6",
"name": "deposits",
"data": {}
}
}
],
"confirmations": 1
}
Replay & List Notifications
Replay a Notification
Re-deliver a previously sent notification (useful for debugging or recovery):
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://acme.com/webhook/vault-updates",
"deliveryId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}' \
https://api.carabaas.com/api/v1/subscriptions/notifications/{notificationId}/replay
List Notifications
View the delivery log:
curl -H "Authorization: Bearer $TOKEN" \
https://api.carabaas.com/api/v1/subscriptions/notifications