Events Webhooks
Receive real-time notifications when events are added, updated, or removed from your feeds.
Event Types
| Event Type | When it fires | Page |
|---|---|---|
event.item_added | A new event is discovered and added to a feed | event.item_added |
event.item_updated | An existing event's data changes (time, venue, status…) | event.item_updated |
event.item_removed | One or more events are removed from a feed (batched) | event.item_removed |
See the per-event-type pages for the authoritative data schemas. The sections below cover events-domain behavior that applies across all three.
Webhooks Are Signals, Not Source of Truth
Event webhooks tell you something changed. They do not carry the full event data — only enough to identify what to re-fetch. Always query the Event Feed API for current state.
Why minimal payloads:
- Stale-data prevention. Between the source change and your handler, the event may have been updated again. Re-fetching guarantees you act on current state.
- Out-of-order safety. Network conditions can deliver webhooks out of order. The API has the authoritative state, so re-fetching makes order irrelevant.
- Debouncing. Multiple rapid changes to the same event collapse into a single webhook. The webhook says "sync me", not "here's the diff".
item_added vs item_updated vs item_removed
| Event type | data.eventId | data.eventIds | Typical batch size |
|---|---|---|---|
event.item_added | yes | — | 1 |
event.item_updated | yes | — | 1 |
event.item_removed | — | yes (array) | 1+ |
item_removed is the only one that batches. If you write a generic handler, branch on eventType and read the right field — do not assume data.eventId exists for removals.
Debouncing Behavior
- Window: 2 minutes per organization per feed per event.
- Scope: debounced independently per event — updating event A does not delay notifications about event B.
- Implication: during high activity you receive one webhook per (event, 2-minute window), not one per change. Re-fetch from the API to see the final state.
Comprehensive Example
import type { Request, Response } from 'express';
import { verifyWebhookSignature } from './verify'; // see Webhook Overview
app.post('/webhooks/events', async (req: Request, res: Response) => {
// 1. Verify signature against the RAW body (see Webhook Overview).
if (
!verifyWebhookSignature(
req.rawBody,
req.headers,
process.env.WEBHOOK_SECRET!
)
) {
return res.status(401).send('Invalid signature');
}
// 2. Acknowledge receipt immediately. Process async.
res.status(200).send('OK');
// 3. Use envelope `id` for idempotency — stable across retries.
const { eventType, id, data } = req.body;
if (await alreadyProcessed(id)) return;
try {
switch (eventType) {
case 'event.item_added':
case 'event.item_updated': {
const event = await helixApi.getFeedItem(data.feedId, data.eventId);
if (!event) {
// Already removed by the time we re-fetched — treat as removal.
await markEventRemoved(data.eventId);
} else {
await upsertEvent(event);
}
break;
}
case 'event.item_removed': {
// data.eventIds is an array — handle batches.
await markEventsRemoved(data.feedId, data.eventIds);
break;
}
default:
console.warn(`Unknown event type: ${eventType}`);
}
await markProcessed(id);
} catch (err) {
// Already 200'd — log, don't rethrow. Failed sync is recoverable
// on the next webhook or a periodic full reconcile.
console.error('Webhook processing failed', { id, eventType, err });
}
});
Between the webhook firing and your re-fetch, the event may have been removed. A 404 from the API on item_added / item_updated is normal — convert it to a removal in your store.
How Webhooks Are Sent
Standard Helix webhook protocol — see the Webhook Overview for envelope shape, signature verification, retry policy, and HTTP headers.
Testing Webhooks
curl -X POST https://api.feeds.onhelix.ai/webhooks/test \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/webhooks/events",
"eventType": "event.item_added"
}'
Repeat with event.item_updated or event.item_removed to test each type.
Next Steps
- Event Feed API Reference — fetch complete event data
- Event Feed Concepts — understanding the event data model
- Webhook Overview — envelope schema, signing, retries
- Authentication — API key management