Wallet Webhook Events
Account-level webhook events for token deposits and the bank transfers they produce. Register a WALLET-type endpoint from the dashboard (Devtools → Webhooks).
These are the only notification for automatic withdrawal on deposit — you never make a request to start one, so there is no response to read a status from.
Registration, signature verification, retries, and URL rules: Webhooks.
Events
| Event | Fires when |
|---|---|
wallet.deposit.updated | A token deposit is credited, or is retried |
wallet.withdrawal.updated | A bank transfer to your own account changes status |
wallet.deposit.updated arrives once the deposit is credited and the withdrawal it triggered has been decided, so a single event tells you the money arrived and what happened next. A deposit that triggered nothing — an ordinary deposit address, or one blocked by your sender list — still produces the event.
Deposits on Solana are not announced. Read them with GET /v1/wallet/deposits/{id}.
Envelope
{
"eventId": "wallet.deposit.updated:5e9d0273-...:COMPLETED:COMPLETED",
"event": "wallet.deposit.updated",
"webhookType": "WALLET",
"timestamp": "2026-08-07T09:34:22.000Z",
"data": {}
}| Field | Description |
|---|---|
eventId | Unique — use for idempotency |
event | Event name |
webhookType | WALLET for these events |
timestamp | ISO 8601 |
data | Event-specific payload |
A retried deposit produces a second event for the same deposit, with its own eventId. Key your handler on eventId and treat a repeat as a no-op.
Event data
wallet.deposit.updated
{
"id": "5e9d0273-8a41-4c62-b0f7-1d3e8c95a460",
"txHash": "0x5d5355...103ee3",
"logIndex": 12,
"chainId": 1,
"tokenId": "a71c4e08-2f96-4b3d-85ae-6c0f7d21b943",
"amount": "100000",
"from": "0x9a3f7c21b8e04d6f5a19c2e70b48d3f61a5e9d02",
"status": "COMPLETED",
"confirmations": 24,
"triggerAddress": "0x7c1a3e889d2b4f618a441f0b6d3c9a5588ab01cd",
"destination": { "type": "BANK_ACCOUNT", "id": "b21f4c77-...", "name": "ACME SDN BHD" },
"result": { "status": "FAILED", "statusReason": "sender_not_allowed", "withdrawal": null },
"createdAt": "2026-08-07T09:30:44.000Z",
"updatedAt": "2026-08-07T09:34:22.000Z"
}Fields match the REST record — see GET /v1/wallet/deposits/{id} for the full table and the status reason values.
Read result.status for the outcome. result is null when the deposit arrived at an ordinary deposit address.
wallet.withdrawal.updated
{
"withdrawalId": "c4a80f13-6d29-4e75-83b1-9f0c2a7e5d68",
"status": "COMPLETED",
"statusReason": null,
"amount": "100000",
"refId": "FW-20260807-0001",
"reference": "ACME payout",
"destination": { "type": "BANK_ACCOUNT", "id": "b21f4c77-...", "name": "ACME SDN BHD" },
"depositId": "5e9d0273-8a41-4c62-b0f7-1d3e8c95a460",
"createdAt": "2026-08-07T09:31:05.000Z",
"updatedAt": "2026-08-07T09:34:22.000Z"
}| Field | Type | Description |
|---|---|---|
withdrawalId | string (UUID) | Matches GET /v1/wallet/fiat/withdrawals/{id} |
status | string | PENDING, PROCESSING, COMPLETED, REJECTED, FAILED, CANCELLED |
statusReason | string | null | Set only on REJECTED, FAILED, and CANCELLED |
amount | string | Amount in sen |
refId | string | Bank reference |
reference | string | null | Your own reference |
destination | object | null | The bank account paid |
depositId | string | null | The deposit that triggered it, or null for a withdrawal you created yourself |
depositId is how you join the two events. It is the only field that distinguishes a triggered withdrawal from one you created with POST /v1/wallet/fiat/withdrawals.