Skip to main content

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

Webhooks Are Synchronization Signals

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:

  1. Prevents stale data - You always fetch the current state from the API
  2. Handles race conditions - Multiple rapid changes result in one sync, with you getting the final state
  3. Simplifies your logic - Your sync code handles any state, not incremental changes
  4. 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 successfully
  • fact_check.failed - Fact-check encountered an error
  • fact_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 feed
  • event.item_updated - Existing event was updated
  • event.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:

HeaderDescriptionExample
Content-TypeContent type of the requestapplication/json
User-AgentUser agent identifying the webhook senderHelix-Data-Feeds/1.0
X-Webhook-SignatureHMAC-SHA256 signature for verifying webhook authenticityv1=a3c8d9e7f2b1a4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9
X-Webhook-TimestampUnix timestamp (milliseconds) when the webhook was sent1704123456789
X-Webhook-IDUnique identifier for the webhook configuration123e4567-e89b-12d3-a456-426614174000
X-Webhook-Event-IDUnique identifier for this specific webhook event987e6543-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.