Configure webhooks to receive real-time notifications when security events occur for monitored entities.
Supported Events
entity.risk_changed: Risk score changed significantly.
entity.threat_detected: New threat detected.
address.interaction: Monitored address interacted with a risky entity.
approval.new: New token approval detected.
approval.revoked: Token approval revoked.
All webhook payloads follow this structure:
interface WebhookPayload {
id: string; // Unique event ID
type: string; // Event type
timestamp: string; // ISO 8601 timestamp
data: object; // Event-specific data
signature: string; // HMAC-SHA256 signature
}
Example Payload
{
"id": "evt_1a2b3c4d5e6f7g8h",
"type": "entity.risk_changed",
"timestamp": "2024-01-15T14:32:00.847Z",
"data": {
"entity": "0x742d35Cc6634C0532925a3b844Bc454c459dFE2C",
"entityType": "contract",
"previousScore": 25,
"currentScore": 78,
"change": 53,
"factors": [
"Honeypot behavior detected",
"Liquidity removed"
]
},
"signature": "sha256=a1b2c3d4e5f6..."
}
Create Webhook
Request Body
HTTPS URL to receive webhook events
Event types to subscribe to
Specific entities to monitor (optional, monitors all if empty)
Signing secret for payload verification (auto-generated if not provided)
Example Request
curl --request POST \
--url https://api.chainguardai.dev/v1/webhooks \
--header 'Authorization: Bearer cg_live_xxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://your-app.com/webhooks/chainguard",
"events": ["entity.risk_changed", "entity.threat_detected"],
"entities": ["0x742d35Cc6634C0532925a3b844Bc454c459dFE2C"]
}'
Response
{
"success": true,
"data": {
"id": "wh_abc123def456",
"url": "https://your-app.com/webhooks/chainguard",
"events": ["entity.risk_changed", "entity.threat_detected"],
"entities": ["0x742d35..."],
"secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxx",
"status": "active",
"createdAt": "2024-01-15T14:32:00Z"
}
}
Store the secret securely. It’s only shown once upon creation.
List Webhooks
Response
{
"success": true,
"data": {
"webhooks": [
{
"id": "wh_abc123def456",
"url": "https://your-app.com/webhooks/chainguard",
"events": ["entity.risk_changed"],
"status": "active",
"lastTriggered": "2024-01-15T10:00:00Z",
"createdAt": "2024-01-01T00:00:00Z"
}
]
}
}
Delete Webhook
DELETE /v1/webhooks/{webhookId}
Verify Webhook Signature
Always verify webhook signatures to ensure authenticity:
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express.js example
app.post('/webhooks/chainguard', (req, res) => {
const signature = req.headers['x-ChainGuard-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, webhookSecret)) {
return res.status(401).send('Invalid signature');
}
// Process the event
const event = req.body;
console.log('Received event:', event.type);
res.status(200).send('OK');
});
import hmac
import hashlib
def verify_signature(payload: str, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
# Flask example
@app.route('/webhooks/chainguard', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-ChainGuard-Signature')
payload = request.get_data(as_text=True)
if not verify_signature(payload, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
event = request.json
print(f"Received event: {event['type']}")
return 'OK', 200
Retry Policy
Failed webhook deliveries are retried with exponential backoff:
- Attempt 1: Immediate.
- Attempt 2: 1 minute.
- Attempt 3: 5 minutes.
- Attempt 4: 30 minutes.
- Attempt 5: 2 hours.
After 5 failed attempts, the webhook is marked as failing and requires manual re-activation.
Event Details
entity.risk_changed
Triggered when an entity’s risk score changes by 15+ points.
{
"type": "entity.risk_changed",
"data": {
"entity": "0x...",
"entityType": "contract",
"previousScore": 25,
"currentScore": 78,
"change": 53,
"factors": ["Honeypot detected", "Liquidity removed"]
}
}
entity.threat_detected
Triggered when a new threat is identified.
{
"type": "entity.threat_detected",
"data": {
"entity": "0x...",
"threatType": "honeypot",
"severity": "critical",
"description": "Contract now prevents selling"
}
}
approval.new
Triggered when a monitored wallet makes a new token approval.
{
"type": "approval.new",
"data": {
"wallet": "0x...",
"token": "0x...",
"tokenSymbol": "USDC",
"spender": "0x...",
"spenderLabel": "Unknown",
"amount": "unlimited",
"riskLevel": "high"
}
}
Webhooks are available on Pro and Enterprise plans only.