Webhooks Overview
Receive real-time notifications when events occur in RevKeen
Webhooks enable your application to receive real-time HTTP notifications when events occur in your RevKeen account. Instead of polling the API, webhooks push data to you.
How Webhooks Work
- Configure an endpoint — Register a URL in your dashboard
- Event occurs — Something happens (payment, subscription change, etc.)
- RevKeen sends POST — We send a JSON payload to your URL
- You respond — Return
200 OKto acknowledge receipt - We retry if needed — Failed deliveries are retried automatically
Webhook Payload
All webhooks have a consistent structure:
{
"id": "evt_xxxxxxxx",
"type": "invoice.paid",
"created": "2025-01-15T10:30:00Z",
"data": {
"id": "inv_xxxxxxxx",
"customerId": "cus_xxxxxxxx",
"status": "paid",
"totalMinor": 9900,
"currency": "USD"
}
}| Field | Type | Description |
|---|---|---|
id | string | Unique event identifier |
type | string | Event type |
created | string | ISO 8601 timestamp |
data | object | Event payload (varies by type) |
Setting Up Webhooks
Via Dashboard
- Go to Settings → Webhooks in your dashboard
- Click Add Endpoint
- Enter your endpoint URL
- Select events to subscribe to
- Copy the signing secret for verification
Via API
curl -X POST "https://api.revkeen.com/v1/webhooks" \
-H "Authorization: Bearer rk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/revkeen",
"events": ["invoice.paid", "subscription.created", "subscription.cancelled"]
}'Verifying Signatures
Always verify webhook signatures to ensure requests are from RevKeen:
Signature Header
Every webhook includes a X-RevKeen-Signature header:
X-RevKeen-Signature: t=1673856000,v1=5d2c67...abc123TypeScript Verification
import crypto from 'crypto';
function verifyWebhook(
payload: string,
signature: string,
secret: string
): boolean {
const [timestamp, sig] = signature.split(',').map(s => s.split('=')[1]);
// Reject old timestamps (>5 minutes)
const age = Date.now() - parseInt(timestamp) * 1000;
if (age > 300000) {
throw new Error('Webhook timestamp too old');
}
// Compute expected signature
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex');
// Constant-time comparison
return crypto.timingSafeEqual(
Buffer.from(sig),
Buffer.from(expected)
);
}
// Express.js example
app.post('/webhooks/revkeen', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-revkeen-signature'] as string;
const payload = req.body.toString();
try {
if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET!)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(payload);
switch (event.type) {
case 'invoice.paid':
handleInvoicePaid(event.data);
break;
case 'subscription.cancelled':
handleSubscriptionCancelled(event.data);
break;
}
res.json({ received: true });
} catch (err) {
res.status(400).send(`Webhook Error: ${err.message}`);
}
});Best Practices
Return
200 OK as soon as possible. Process events asynchronously using a queue.Events may be delivered multiple times. Use the event
id for idempotency.Always verify
X-RevKeen-Signature to ensure webhooks are authentic.Only register HTTPS endpoints. HTTP endpoints will be rejected.
Log incoming webhooks for debugging and audit purposes.
Use
revkeen webhook test to send test events to your local endpoint.Retry Policy
If your endpoint doesn't return 2xx:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 8 hours |
| 6 | 24 hours |
After 6 failed attempts, the event is marked as failed. View failed events in your dashboard.