HomeDocsWebhooks
Webhooks

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

  1. Navigate to your Rox Custody Corporate Dashboard using your subdomain.Example: https://[your-subdomain].roxcustody.com
  2. 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

  1. Input Your Server's URL: Provide an HTTPS URL where you want to receive webhook events. The URL must be a valid HTTPS endpoint.
  2. 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.
  3. Verify Requests on Your Server: Use the rox-auth-secret header 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.

Use the 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:

HeaderDescription
rox-auth-secretYour configured secret token for authentication
subdomainThe corporate subdomain
vault-idThe 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

EventDescription
SYNC_VAULT_WALLETSFires when vault wallets are synchronized with the system.
SYNC_CLIENT_WALLETSFires when client wallets are synchronized with the system.
Wallet Events, example payload
JSON
{
"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

EventDescription
CREATE_TRANSACTIONFires when a new transaction is created.
BROADCASTED_TRANSACTIONFires when a transaction is being broadcast to the blockchain network.
COMPLETED_TRANSACTIONFires when a transaction is confirmed and successfully completed.
COMPLIANCE_RULE_TRANSACTIONFires when a new compliance rule transaction is created
REJECTED_TRANSACTIONFires when a transaction is rejected by the admin.
ERROR_TRANSACTIONFires when an unexpected error occurs during transaction processing.
BLOCKCHAIN_REJECTED_TRANSACTIONFires when a transaction is rejected by the blockchain network.
CANCEL_TRANSACTIONFires when a transaction is cancelled.
Transaction Events, example payload
JSON
{
"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

EventDescription
ADD_ASSETFires when a new asset is added to a vault.
ACTIVATE_ASSETFires when an asset is activated and made available for use.
DEACTIVATE_ASSETFires when an asset is deactivated and becomes unavailable.
HOLD_ASSETTriggered when an asset is placed on hold or reactivated by a corporate admin or Roxcustody super admin.
Assets Events, example payload
JSON
{
"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

EventDescription
HOLD_NETWORKFires when a blockchain network is placed on hold or reactivated by a corporate admin or Roxcustody super admin.
Network Events, example payload
JSON
{
"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

EventDescription
TOKEN_CREATED_WITH_ASSETFires when a new security token is created.
Token Events, example payload
JSON
{
"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

EventDescription
CREATE_PAYMENT_VAULT_ORDERFires when a new payment vault order is created.
SELECT_ASSET_PAYMENT_VAULT_ORDERFires when an asset is selected for a payment vault order.
CANCELLED_PAYMENT_VAULT_ORDERFires when a payment vault order is cancelled.
PAID_PAYMENT_VAULT_ORDERFires when a payment vault order is marked as paid.
Payment Vault Order Events, example payload
JSON
{
"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.

What's next?