Configure webhook notifications
Subscribing to webhooks via API
Prior to configuring your webhook, please be sure to notify the integration point of contact to enable these for your sandbox.
API permission group and API key configuration
Once Webhooks are enabled for your sandbox or organization, you will need to update your permission group and API key to test these. Please either create a new Permission Group or edit an existing one to include the global permission - Configure webhooks.

Webhook validation key
The webhook validation key is used to validate the authenticity of the webhook API signature and the notifications your receive. This is an added security measure to safeguard your integration and any actionable operations you may initiate as a result of this data.
Idempotency using MessageId
Each message will have a messageId which should be treated as an idempotentId for each webhook message. This should be used to validate that you have not received this before.
Timestamp should also be used to validate or ensure freshness of an event.
Webhook schema
| Payload | Overview |
|---|---|
payload | Encrypted payload with relevant event transactionIdor additional Ids, depending on event type |
timestamp | Sending timestamp |
message_id | Unique ID associated with the event message. This should be treated as an idempotent ID |
event_type | The type of event topic and name for the associated subscription |
{
"payload": []byte,
"timestamp": int64,
"message_id": string,
"event_type": string
}Webhook endpoint
Once you've configured the API key and received the Webhook validation key, you must create a Webhook endpoint where you will receive the notifications.
Webhook event types
Prior to configuring the event subscriptions to the endpoint you've just configured, you are able to list the complete configured list for your organization. This will provide you with detailed topic, name and description details for each supported event.
{
"data": [
{
"description": "Notification of a new RIA program customer who has successfully completed and passed Onboarding KYC. Not needed anymore on favorr of the subaccount opened event.",
"id": "program-customer-onboard.completed"
},
{
"description": "Notification of a successful withdrawal completed on-chain",
"id": "withdrawal.completed"
},
{
"description": "Notification of a subaccount that currently is low on funds",
"id": "subaccount.low-balance"
},
{
"description": "Notification of a failed transfer",
"id": "transfer.failed"
},
{
"description": "Notification of successful completion of deposit attribution",
"id": "deposit.attributed"
},
{
"description": "Notification of a successful withdrawal initiated but still pending quorum approval and/or risk review",
"id": "withdrawal.initiated"
},
{
"description": "Notification of a collateral package state change",
"id": "collateral-package-state-change.collateral-package-state-change"
},
{
"description": "Notification of a successful transfer that is now completed",
"id": "transfer.completed"
},
{
"description": "Notification of an open RIA program customer process that has requested further information.",
"id": "program-customer-onboard.rfi"
},
{
"description": "Notification of a new deposit pending attribution",
"id": "deposit.pending-attribution"
},
{
"description": "Notification of a failed withdrawal",
"id": "withdrawal.failed"
},
{
"description": "Notification of a subaccount withdrawal request status change",
"id": "subaccount.subaccount-withdrawal-request-status-change"
},
{
"description": "Notification of a transfer that has successfully been initiated",
"id": "transfer.initiated"
},
{
"description": "Notification of a subaccount that has successfully completed and passed Onboarding KYC.",
"id": "subaccount.opened"
}
],
"page": {
"next": null
}
}Webhook subscriptions
When you've selected the relevant events, you will need to configure the endpoint with one or many events subscriptions. Each time an event happens, a notification will be triggered and sent to the corresponding endpoint(s) subscribed to this event type.
Validating the webhook notification and decoding the payload
Once you've received the notification, depending on the language you're using, you may need to decode the payload from Base64 format.
import * as ed from '@noble/ed25519';
const pubKey = 'c14b7f3da18abb17b7304f925a68b18c1ea0dad6663b6b54cb67a737ecb77cd0';
function toHex(str: string) {
var result = '';
for (var i=0; i<str.length; i++) {
result += str.charCodeAt(i).toString(16);
}
return result;
}
const message = `...` // message
const signature = '...' // signature
const isValid = await ed.verifyAsync(signature, toHex(message), pubKey);
console.log("Is valid: ", isValid);
console.log("Payload: ", atob(JSON.parse(message).payload));from http.server import BaseHTTPRequestHandler, HTTPServer
from nacl.exceptions import BadSignatureError
from nacl.encoding import HexEncoder
from nacl.signing import VerifyKey
import base64
import json
publicKey = VerifyKey("c14b7f3da18abb17b7304f925a68b18c1ea0dad6663b6b54cb67a737ecb77cd0", encoder=HexEncoder)
class MyServer(BaseHTTPRequestHandler):
def do_POST(self):
signature = HexEncoder.decode(self.headers.get("Api-Signature"))
content_len = int(self.headers.get('Content-Length'))
message = self.rfile.read(content_len)
try:
publicKey.verify(message, signature)
except BadSignatureError:
print("Invalid signature")
payload = base64.b64decode(json.loads(message)["payload"].encode('utf-8')).decode('utf-8')
print("Payload", payload)
self.send_response(200)
self.end_headers()Manage your webhook endpoints (update and cancel subscriptions)
Once you've configured your Webhook endpoints and subscriptions you can manage the existing configurations leveraging the Update Webhook Endpoint or Cancel Webhook Subscriptions.
Additional external webhook resources
Updated 8 months ago