Webhooks
Webhooks deliver real-time updates for events to your system, eliminating the need to poll the API. When an event occurs, relevant data is pushed to your configured server endpoint.
Setting Up Your Webhook
Step 1: Access Your Corporate Dashboard
- Navigate to your Rox Custody Corporate Dashboard using your subdomain.Example:
https://[your-subdomain].roxcustody.com - Log in with your credentials and ensure you have access to your corporate dashboard.
Step 2: Create Your Vault
Before setting up webhooks, ensure you have created a vault within the dashboard. This is a required step, as the webhook events will correspond to activities linked to your vault.
Step 3: Verify Your Website and Token
- Input Your Server's URL: Provide an HTTPS URL where you want to receive webhook events. The URL must be a valid HTTPS endpoint.
- Set Your Secret Token: Enter a secret token of your choice (up to 255 characters). This token will be sent in the webhook request headers under the key
rox-auth-secret. - Verify Requests on Your Server: Use the
rox-auth-secretheader to validate the authenticity of incoming webhook payloads on your backend server.
Step 4: Events Selection and Retry Configuration
After verification, choose the events you want to subscribe to, so you only receive updates for relevant actions. For each event category, you can configure:
- Retry Count: Number of retry attempts (1-10) if the webhook delivery fails
- Retry Period: Time interval between retries. Available options:
15-minute,30-minute,1-hour,2-hour,3-hour,4-hour,5-hour
Step 5: Test Your Webhook
You can trigger a test event from the webhooks events page to ensure your endpoint is correctly configured to receive and process webhook payloads. The test will send a sample payload to your configured endpoint.
rox-auth-secret header to validate the authenticity of incoming webhook payloads on your backend server before processing any event.Webhook Headers
When receiving webhook events, your server will receive the following headers:
| Header | Description |
|---|---|
rox-auth-secret | Your configured secret token for authentication |
subdomain | The corporate subdomain |
vault-id | The vault ID associated with the webhook event |
Event Types
Rox Custody fires events across the categories below. You can subscribe to all categories or only the ones relevant to your integration.
Wallet Events
| Event | Description |
|---|---|
SYNC_VAULT_WALLETS | Fires when vault wallets are synchronized with the system. |
SYNC_CLIENT_WALLETS | Fires when client wallets are synchronized with the system. |
| { |
| "event": "sync_client_wallets", |
| "vaultId": 22, |
| "vaultWallets": [ |
| { |
| "id": 3017, |
| "type": "CLIENT", |
| "asset": { |
| "id": 2000, |
| "logo": "http://localhost:5000/public/files/assets/base.png", |
| "name": "Sepolia Ether", |
| "type": "COIN", |
| "status": "ACTIVE", |
| "symbol": "ETH", |
| "decimals": 18, |
| "contractAddress": null |
| }, |
| "client": { |
| "id": 18, |
| "externalId": "Client1" |
| }, |
| "balance": "0", |
| "targetId": 18, |
| "publicAddress": "0xd6C963d5f2C06102eA87990457049055Ccf59430", |
| "pendingBalance": "0", |
| "transactionsCount": "0" |
| } |
| ] |
| } |
Transaction Events
| Event | Description |
|---|---|
CREATE_TRANSACTION | Fires when a new transaction is created. |
BROADCASTED_TRANSACTION | Fires when a transaction is being broadcast to the blockchain network. |
COMPLETED_TRANSACTION | Fires when a transaction is confirmed and successfully completed. |
COMPLIANCE_RULE_TRANSACTION | Fires when a new compliance rule transaction is created |
REJECTED_TRANSACTION | Fires when a transaction is rejected by the admin. |
ERROR_TRANSACTION | Fires when an unexpected error occurs during transaction processing. |
BLOCKCHAIN_REJECTED_TRANSACTION | Fires when a transaction is rejected by the blockchain network. |
CANCEL_TRANSACTION | Fires when a transaction is cancelled. |
| { |
| "event": "completed_transaction", |
| "vaultId": 22, |
| "transaction": { |
| "id": "423", |
| "fees": "0.000009292470526579", |
| "note": null, |
| "type": "Outgoing", |
| "amount": "1e-11", |
| "client": { |
| "id": 18, |
| "externalId": "Client1" |
| }, |
| "markup": "0 ETH", |
| "status": "COMPLETED", |
| "parentId": null, |
| "walletId": "3017", |
| "coinSymbol": "ETH", |
| "callMethod": null, |
| "dollarAmount": "0.00000004422030000000", |
| "errorMessage": null, |
| "senderAddress": "0xd6C963d5f2C06102eA87990457049055Ccf59430", |
| "encodedPayload": null, |
| "statusChangedAt": "2025-08-26T09:04:31.000Z", |
| "receiverAddress": "0x22D5Dc46AfF8A9733DEAd29D81Bc982DD0e90BeB", |
| "transactionHash": "0x16d07234a377915daf28172b50a993ff390b5167b928d581a620d79848d5fcd8", |
| "feesDollarAmount": "0.04109158344264813537", |
| "paymentPolicyType": "api", |
| "gasStationCategoryWalletId": "14" |
| } |
| } |
Assets Events
| Event | Description |
|---|---|
ADD_ASSET | Fires when a new asset is added to a vault. |
ACTIVATE_ASSET | Fires when an asset is activated and made available for use. |
DEACTIVATE_ASSET | Fires when an asset is deactivated and becomes unavailable. |
HOLD_ASSET | Triggered when an asset is placed on hold or reactivated by a corporate admin or Roxcustody super admin. |
| { |
| "event": "deactivate_asset", |
| "assets": [ |
| { |
| "id": 2000, |
| "logo": "http://localhost:5000/public/files/assets/base.png", |
| "name": "Sepolia Ether", |
| "type": "COIN", |
| "status": "ACTIVE", |
| "symbol": "ETH", |
| "network": { |
| "id": 23, |
| "logo": "http://localhost:5000/public/files/assets/base.png", |
| "name": "Base Sepolia", |
| "type": "PUBLIC", |
| "chain": { |
| "id": 84532, |
| "name": "Base Sepolia", |
| "rpcUrls": { |
| "default": { |
| "http": [ |
| "https://sepolia.base.org" |
| ] |
| } |
| }, |
| "testnet": true, |
| "blockExplorers": { |
| "default": { |
| "url": "https://sepolia.basescan.org", |
| "name": "Basescan", |
| "apiUrl": "https://api-sepolia.basescan.org/api" |
| } |
| }, |
| "nativeCurrency": { |
| "name": "Sepolia Ether", |
| "symbol": "ETH", |
| "decimals": 18 |
| } |
| }, |
| "status": "ACTIVE", |
| "symbol": "ETH", |
| "category": "EVM", |
| "isSwappable": false |
| }, |
| "decimals": 18, |
| "contractAddress": null |
| } |
| ], |
| "vaultId": 22 |
| } |
Network Events
| Event | Description |
|---|---|
HOLD_NETWORK | Fires when a blockchain network is placed on hold or reactivated by a corporate admin or Roxcustody super admin. |
| { |
| "event": "hold_network", |
| "network": { |
| "id": 23, |
| "logo": "http://localhost:5000/public/files/assets/base.png", |
| "name": "Base Sepolia", |
| "type": "PUBLIC", |
| "chain": { |
| "id": 84532, |
| "name": "Base Sepolia", |
| "rpcUrls": { |
| "default": { |
| "http": [ |
| "https://sepolia.base.org" |
| ] |
| } |
| }, |
| "testnet": true, |
| "blockExplorers": { |
| "default": { |
| "url": "https://sepolia.basescan.org", |
| "name": "Basescan", |
| "apiUrl": "https://api-sepolia.basescan.org/api" |
| } |
| }, |
| "nativeCurrency": { |
| "name": "Sepolia Ether", |
| "symbol": "ETH", |
| "decimals": 18 |
| } |
| }, |
| "status": "HOLD", |
| "symbol": "ETH", |
| "category": "EVM", |
| "isSwappable": false |
| }, |
| "vaultId": 22 |
| } |
Token Events
| Event | Description |
|---|---|
TOKEN_CREATED_WITH_ASSET | Fires when a new security token is created. |
| { |
| "event": "token_created_with_asset", |
| "vaultId": 22, |
| "token": { |
| "id": 123, |
| "name": "My Security Token", |
| "symbol": "MST", |
| "type": "TOKEN", |
| "network": { |
| "id": 23, |
| "name": "Base Sepolia", |
| "symbol": "ETH", |
| "category": "EVM" |
| }, |
| "vault": { |
| "id": 22, |
| "name": "My Vault" |
| } |
| } |
| } |
Payment Vault Order Events
| Event | Description |
|---|---|
CREATE_PAYMENT_VAULT_ORDER | Fires when a new payment vault order is created. |
SELECT_ASSET_PAYMENT_VAULT_ORDER | Fires when an asset is selected for a payment vault order. |
CANCELLED_PAYMENT_VAULT_ORDER | Fires when a payment vault order is cancelled. |
PAID_PAYMENT_VAULT_ORDER | Fires when a payment vault order is marked as paid. |
| { |
| "event": "create_payment_vault_order", |
| "order": { |
| "id": "01KDTERRXSM230ANGSNYJZGWNF", |
| "email": null, |
| "vault": { |
| "photo": null, |
| "fiatCurrencyDetails": { |
| "id": 5, |
| "name": "US Dollar", |
| "symbol": "$", |
| "pricingId": "usd" |
| }, |
| "gasStationCategoryId": 1 |
| }, |
| "status": "PENDING", |
| "wallet": { |
| "id": 89, |
| "type": "ORDER", |
| "asset": { |
| "id": 3, |
| "logo": "https://api-admin.roxcustody.io/public/files/assets/aave.png", |
| "name": "Aave", |
| "type": "TOKEN", |
| "status": "ACTIVE", |
| "symbol": "aave", |
| "network": { |
| "id": 1, |
| "logo": "https://api-admin.roxcustody.io/public/files/assets/ethereum.png", |
| "name": "Ethereum", |
| "type": "PUBLIC", |
| "chain": { |
| "id": 1, |
| "name": "Ethereum", |
| "rpcUrls": { |
| "default": { |
| "http": [ |
| "https://ethereum-rpc.publicnode.com", |
| "https://eth.llamarpc.com" |
| ] |
| } |
| }, |
| "blockExplorers": { |
| "default": { |
| "url": "https://etherscan.io", |
| "name": "Etherscan", |
| "apiUrl": "https://api.etherscan.io/api" |
| } |
| }, |
| "nativeCurrency": { |
| "name": "Ether", |
| "symbol": "ETH", |
| "decimals": 18 |
| } |
| }, |
| "status": "ACTIVE", |
| "symbol": "ETH", |
| "category": "EVM", |
| "isSwappable": true |
| }, |
| "decimals": 18, |
| "contractAddress": null |
| }, |
| "balance": "0", |
| "protocol": 0, |
| "targetId": "45", |
| "publicAddress": "0x358c06c4b8e7A4B26C5016678f33Be45ab95eB89", |
| "pendingBalance": "0", |
| "transactionsCount": "0" |
| }, |
| "balance": "0", |
| "vaultId": 13, |
| "globalId": "01KDTERRXS9C608SXM91NV1MQC", |
| "itemName": null, |
| "walletId": "89", |
| "createdAt": "2025-12-31T13:00:07.767Z", |
| "updatedAt": "2025-12-31T13:02:47.000Z", |
| "clientName": null, |
| "expiration": "2025-12-31T16:02:47.000Z", |
| "paymentLink": "roxcustody.com/orders/01KDTERRXS9C608SXM91NV1MQC", |
| "amountInFiat": "25.50000000000000000000", |
| "transactions": [], |
| "amountInAsset": "0.171566978402745072", |
| "amountInDollar": "25.50000000000000000000", |
| "amountToBeCollected": "0", |
| "expirationWithTolerance": "2025-12-31T16:02:47.000Z" |
| }, |
| "vaultId": 13 |
| } |
By subscribing to these events, you can stay updated in real time about your vault's assets, transactions, and wallets.