Webhooks
Receive real-time notifications when events happen in your ConsentProof account.
Overview
Webhooks allow you to receive HTTP POST requests to your server whenever specific events occur. This enables you to:
- Sync consent data with your CRM or database
- Trigger workflows when users grant or withdraw consent
- Update your application in real-time
- Build audit logs and compliance reports
Creating a Webhook
Create a webhook via the API or dashboard:
curl -X POST https://api.consentproof.io/v1/webhooks \
-H "X-API-Key: your_api_key" \
-H "X-API-Secret: your_api_secret" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/consentproof",
"events": ["consent.created", "consent.withdrawn"]
}'Note: The secret field is optional. If not provided, a secure secret will be auto-generated (prefixed with whsec_).
Response:
{
"success": true,
"data": {
"id": "whk_abc123",
"url": "https://your-app.com/webhooks/consentproof",
"events": ["consent.created", "consent.withdrawn"],
"secret": "whsec_a1b2c3d4e5f6...",
"is_active": true,
"created_at": "2024-01-15T10:30:00Z"
},
"meta": {
"message": "Save the webhook secret now - it will not be shown again."
}
}Important
The webhook secret is only returned once when the webhook is created. Save it securely - you'll need it to verify webhook signatures.
Available Events
Subscribe to any of these events:
| Event | Description |
|---|---|
| consent.created | A new consent record was created |
| consent.updated | A consent record was updated |
| consent.withdrawn | Consent was withdrawn |
| consent.batch_created | Multiple consents were created in batch |
| policy.created | A new policy version was created |
| policy.updated | A policy was updated |
| policy.deleted | A policy was deleted |
Use * to subscribe to all events.
Webhook Payload
Each webhook delivery includes a JSON payload with the event details:
{
"id": "evt_xyz789",
"type": "consent.created",
"created_at": "2024-01-15T10:35:00Z",
"data": {
"id": "con_abc123",
"subject_id": "user_123",
"subject_email": "user@example.com",
"policy_id": "pol_def456",
"consent_type": "marketing",
"granted": true,
"consent_hash": "sha256:a1b2c3d4e5f6...",
"metadata": {
"ip_address": "192.168.1.1",
"source": "signup_form"
},
"recorded_at": "2024-01-15T10:35:00Z"
}
}Verifying Signatures
Every webhook includes an HMAC-SHA256 signature in the X-Signature header. Always verify this signature to ensure the webhook is from ConsentProof.
Headers Included
| Header | Description |
|---|---|
| X-Signature | HMAC-SHA256 signature of the payload |
| X-Timestamp | Unix timestamp of when the webhook was sent |
| X-Webhook-ID | Unique identifier for this webhook configuration |
Verification Example
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express.js example
app.post('/webhooks/consentproof', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-signature'];
const payload = req.body.toString();
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(payload);
// Handle the event
switch (event.type) {
case 'consent.created':
handleConsentCreated(event.data);
break;
case 'consent.withdrawn':
handleConsentWithdrawn(event.data);
break;
default:
console.log('Unhandled event type:', event.type);
}
res.json({ received: true });
});Security Warning
Always verify webhook signatures before processing. Never trust webhooks without verification.
Retry Policy
If your endpoint doesn't respond with a 2xx status code, we'll retry the webhook:
- • Attempt 1: Immediately
- • Attempt 2: After 1 minute
- • Attempt 3: After 5 minutes
- • Attempt 4: After 30 minutes
- • Attempt 5: After 2 hours
After 5 failed attempts, the webhook is marked as failed. You can view delivery history in your dashboard.
Best Practices
- Respond quickly
Return a 200 response immediately, then process the event asynchronously
- Handle duplicates
Use the event ID to deduplicate in case of retries
- Use HTTPS
Webhook URLs must use HTTPS for security
- Test with the dashboard
Use the "Send Test" feature to test your endpoint