Webhooks
Webhooks allow you to receive real-time notifications when events occur in the Helix platform.
Overview
Helix sends HTTP POST requests to your configured webhook endpoints when specific events occur. This allows your application to react to changes without polling.
Understanding Webhooks
Treat webhooks as signals that something changed, not as the source of truth.
Webhooks are designed to notify your system that data has changed, prompting you to synchronize by fetching the current state from our API. This design pattern is intentional and has important implications for how you should handle webhooks.
Why Minimal Payloads?
Our webhook payloads are intentionally minimal (typically just IDs and timestamps). This design:
- Prevents stale data - You always fetch the current state from the API
- Handles race conditions - Multiple rapid changes result in one sync, with you getting the final state
- Simplifies your logic - Your sync code handles any state, not incremental changes
- Reduces payload size - Smaller payloads are more reliable to deliver
How to Handle Webhooks
The API is the source of truth. When you receive a webhook, always fetch the current state from our API rather than relying on the webhook payload. The payload tells you what changed; the API tells you the current state.
Make your handlers idempotent. The same webhook may be delivered multiple times due to network issues, retries, or edge cases. Your code should handle receiving the same notification twice without causing duplicate actions or errors.
Don't assume delivery order. Webhooks may arrive in a different order than the changes actually occurred. If event A happens before event B, you might receive the webhook for B first. Always fetch current state rather than applying incremental changes.
Rapid changes are debounced. If the same resource is updated multiple times within a short window (typically 2 minutes), you'll receive a single webhook notification rather than one per change. This is why fetching current state matters—you'll get the final result regardless of intermediate changes.
Acknowledge receipt immediately. Return a 200 status code as soon as you receive the webhook, then process it asynchronously. If your processing takes too long, we may retry the delivery thinking it failed, leading to duplicate processing.
Webhook Types
We support webhooks for the following domains:
Fact Checking
Receive notifications about fact-check operations:
fact_check.completed- Fact-check finished successfullyfact_check.failed- Fact-check encountered an errorfact_check.status_changed- Fact-check status transitioned
News
Get notified about news feed changes:
news.item_added- New news item added to feed
Events
Receive updates about event feed changes:
event.item_added- New event added to feedevent.item_updated- Existing event was updatedevent.item_removed- Event(s) removed from feed
Configuration
Webhook endpoints can be configured through the Helix dashboard or API. Each webhook requires:
- Endpoint URL - The HTTPS URL where notifications will be sent
- Event Types - Select which events should trigger this webhook
- Secret Key - Used to verify webhook authenticity
HTTP Headers
All webhooks include the following HTTP headers for security and tracking:
| Header | Description | Example |
|---|---|---|
Content-Type | Content type of the request | application/json |
User-Agent | User agent identifying the webhook sender | Helix-Data-Feeds/1.0 |
X-Webhook-Signature | HMAC-SHA256 signature for verifying webhook authenticity | v1=a3c8d9e7f2b1a4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9 |
X-Webhook-Timestamp | Unix timestamp (milliseconds) when the webhook was sent | 1704123456789 |
X-Webhook-ID | Unique identifier for the webhook configuration | 123e4567-e89b-12d3-a456-426614174000 |
X-Webhook-Event-ID | Unique identifier for this specific webhook event | 987e6543-e21b-12d3-a456-426614174111 |
Security & Verification
To verify webhook authenticity, validate the signature in the X-Webhook-Signature header using your webhook secret.
// Example signature verification
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const timestamp = payload.timestamp;
const signedPayload = timestamp + '.' + JSON.stringify(payload);
const expectedSignature = 'v1=' +
crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Best Practices
- Always verify the signature before processing webhook data
- Check the timestamp to prevent replay attacks (reject requests older than 5 minutes)
- Use HTTPS endpoints only
- Return a 2xx status code promptly to acknowledge receipt
Retry Policy
Failed webhook deliveries are automatically retried with exponential backoff:
- 1st retry: after 1 minute
- 2nd retry: after 5 minutes
- 3rd retry: after 15 minutes
- 4th retry: after 1 hour
- 5th retry: after 6 hours
Webhooks are considered successful on HTTP 2xx responses. Other status codes trigger retries.
After all retries are exhausted, the webhook delivery is marked as failed and you'll need to manually retrieve the missed data via the API.