Skip to content

Webhooks overview

What are webhooks?

Wallet-as-a-Service (Palisade) sends automated messages called webhooks to your back-end systems whenever specific events occur on the platform. The system sends the message, or payload, to a unique URL on your server that you designate to receive webhook events.

Why are webhooks beneficial?

The automated nature of webhooks allows organizations to receive guaranteed, real-time updates about any interactions with their wallets (including creation of new wallets, deposits and withdrawals). This push-based approach eliminates the need for API/UI polling and ensures customers are immediately notified of important updates.

Webhook payload format

Wallet-as-a-Service (Palisade) delivers webhook messages as POST requests containing JSON objects with a base64-encoded payload. For example:

{
    "domain": "WALLET",
    "timestamp": "2025-05-08T14:15:37Z",
    "payload": "eyJpZCI6IjAxOTYxNTNiLTY3YmMtN2NkMy1iNTExLTM1NDM3M2QyODEzMCIsICJ2YXVsdElkIjoiMDE5NjE1MmQtNTI5NC03MzlkLTk5NDUtMmE0OTlmOWUzOTg5IiwgIm9yZ2FuaXphdGlvbklkIjoiMjFjODEzMTktNWI4My00NWY5LWI2NDgtNDIwNTUwODRhZjE1IiwgInF1b3J1bUlkIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIiwgImNyZWF0ZWRCeSI6ImE1NWRmOWUwLWUxNGEtNDQxMC1hOTgzLTEyYWZhZTQ2NjYyZiIsICJjcmVhdGVkQXQiOiIyMDI1LTA0LTA4VDExOjQ4OjU2Ljg5OTA4NloiLCAidXBkYXRlZEF0IjoiMjAyNS0wNC0wOFQxMTo0ODo1Ni45MDA0OTBaIiwgIm5hbWUiOiJld3FmZXciLCAiZGVzY3JpcHRpb24iOiIiLCAiYWRkcmVzcyI6IjB4NDY0NDMyMGYzMUQ2OTU4RWQ4NjAzRWI2NjYwNDQ5NTBBYTY5NzAyZSIsICJwdWJsaWNLZXkiOiIwNDgxY2IwMmU4MjFlNTVhMmM2MTk2ZmZkZTM4MGJhM2I0OTgxN2JkYmYwMmYzMTVkYzI4YjU2ZjcwNzkyZDU2ZTZhZGFjOTE3ZTdhZGFmODdmMTBjMDg4NDA4YThjNmEwZTZkMTgwNzkzYzA1MGMzZDBjODc3MWNiOWRkZjgyNThkIiwgImtleXN0b3JlIjoiSFNNIiwgImJsb2NrY2hhaW4iOiJBUkJJVFJVTSIsICJzZXR0aW5ncyI6e30sICJzdGF0dXMiOiJQUk9WSVNJT05FRCJ9",
}

When decoded, the payload contains detailed information about the blockchain event. For example:

{
  "id": "0196153b-67bc-7cd3-b511-354373d28130",
  "vaultId": "0196152d-5294-739d-9945-2a499f9e3989",
  "organizationId": "21c81319-5b83-45f9-b648-42055084af15",
  "createdBy": "a55df9e0-e14a-4410-a983-12afae46662f",
  "createdAt": "2025-04-08T11:48:56.899086Z",
  "updatedAt": "2025-04-08T11:48:56.900490Z",
  "name": "My Wallet",
  "address": "0x4644320f31D6958Ed8603Eb666044950Aa69702e",
  "publicKey": "0481cb02e821e55a2c6196ffde380ba3b49817bdbf02f315dc28b56f70792d56e6adac917e7adaf87f10c088408a8c6a0e6d180793c050c3d0c8771cb9ddf8258d",
  "keystore": "HSM",
  "blockchain": "ARBITRUM",
  "settings": {},
  "status": "PROVISIONED"
}

The webhook contains a signature header you can use to verify that the payload is authentic. For example: MEQCIGjBwNKzzfqK9/Rb3Q2OQCyCuUiOOQz7vZwQ9iqInz76AiB/bvRn5iNUAkeVT80/pwhQ2LUajE6Mb2JtGt2mRmJMpg==

Retry Behaviour

Your server must return an HTTP-200 (OK) response to confirm successful receipt of a webhook notification.

If your server does not respond, Wallet-as-a-Service (Palisade) automatically retries the request several times based on the following schedule (in seconds): 0, 60, 120, 180, 320, 480, 840, 1500, 2820, 5400.

The system does not retry for client-side errors (HTTP 4xx) except for the following cases:

429 - Too Many Requests: Indicates rate limits have been exceeded. 408 - Request Timeout: Indicates the server took too long to respond.

After 10 failed attempts, the system marks the notification as failed and stops retrying.

Event Ordering

Wallet-as-a-Service (Palisade) strives to send notifications in order (per resource), but we cannot guarantee delivery sequence. Design your endpoint to process events independently without relying on their delivery order.

Subscription Domains

When you create a webhook, you subscribe to one or more domains. Each domain sends notifications when the corresponding resource changes state.

DomainDescriptionPayload
TRANSACTIONTransaction status changes (transfers, deposits, withdrawals)Transaction object
WALLETWallet status changes (creation, provisioning)Wallet object
APPROVALApproval request updatesApproval object

Transaction Domain

You receive a webhook notification whenever a transaction transitions to a new status. The payload contains the full transaction object with its current state.

StatusDescriptionTerminal?
REQUESTEDTransaction createdNo
POLICY_CHECK_PENDINGValidating against policiesNo
POLICY_CHECK_PASSEDPolicy checks passedNo
APPROVAL_CHECK_PENDINGWaiting for approvalsNo
APPROVAL_CHECK_PASSEDApprovals completeNo
COMPILATION_PENDINGPreparing for blockchainNo
COMPILEDReady for signingNo
SIGNATURE_PENDINGWaiting for signatureNo
SIGNEDSigned successfullyNo
PUBLISH_PENDINGSubmitting to networkNo
PUBLISHEDSubmitted to blockchainNo
CONFIRMATION_PENDINGAwaiting block confirmationNo
CONFIRMEDConfirmed on blockchain✅ Yes
REJECTEDRejected by policy or approval✅ Yes
FAILEDTechnical failure✅ Yes

For more details on transaction status flow, see Transactions overview.

Transaction Payload Example

{
  "domain": "TRANSACTION",
  "timestamp": "2025-05-08T14:30:00Z",
  "payload": "base64-encoded-transaction-object"
}

When decoded, the payload contains the transaction object. Key fields include:

{
  "id": "019c94f1-cc8c-79b4-9c0f-bc7edaabc267",
  "vaultId": "0196152d-5294-739d-9945-2a499f9e3989",
  "walletId": "0196153b-67bc-7cd3-b511-354373d28130",
  "organizationId": "21c81319-5b83-45f9-b648-42055084af15",
  "status": "CONFIRMED",
  "blockchain": "ETHEREUM",
  "hash": "0x8a4c5e9f2b1d7c3a6e8f0b2d4c6a8e0f2b4d6c8a0e2f4b6d8c0a2e4f6b8d0c2e",
  "destination": {
    "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2E8Ba"
  },
  "asset": {
    "symbol": "ETH"
  },
  "qty": "1.500000000000000000",
  "createdAt": "2025-05-08T14:25:00Z",
  "updatedAt": "2025-05-08T14:30:00Z"
}

For the complete transaction schema, see the Transaction API reference.

Inbound transactions and compliance

For inbound transactions, the payload may include a freezeInfo field indicating whether funds are frozen for compliance review. See Transaction Freeze and Compliance Controls for details.

Wallet Domain

You receive a webhook notification whenever a wallet transitions to a new status.

StatusDescriptionTerminal?
CREATEDWallet record createdNo
PROVISIONINGWallet being set upNo
PROVISIONEDWallet ready for use✅ Yes
PROVISIONING_FAILEDSetup failed✅ Yes

For the complete wallet schema, see the Wallet API reference.

Approval Domain

You receive a webhook notification whenever an approval request is created or updated. This includes approvals for transactions, policy changes, and user management actions.

Approval Set Status

The overall approval request status:

StatusDescriptionTerminal?
PENDINGWaiting for approvers to respondNo
METRequired approvals received✅ Yes
NOT_METApproval rejected✅ Yes
EXPIREDTimed out before requirements met✅ Yes
FAILEDTechnical failure during processing✅ Yes

Individual Approval Status

Each approver's response within an approval set:

StatusDescription
PROCESSINGApprover is reviewing the request
APPROVEDApprover approved the request
REJECTEDApprover rejected the request

For the complete approval schema, see the Approval API reference.

Best Practices

Idempotent Processing

Design your webhook handler to be idempotent. Use the resource id and updatedAt timestamp to detect and safely handle duplicate deliveries.

Quick Acknowledgment

We recommend returning a 200 OK response within 5 seconds. Perform any heavy processing asynchronously after acknowledging receipt to avoid timeouts.

Signature Verification

Always verify the webhook signature before processing to ensure the payload is authentic. See Manage webhooks for verification details.