Delivery behaviors
Retry logic, ordering, deduplication, and webhook status semantics.
This section helps you understand different behaviors to expect regarding how Featurebase sends events to your webhook endpoint.
Retry behavior
Section titled “Retry behavior”If a webhook delivery fails, Featurebase will automatically retry up to 3 times:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute after the first attempt |
| 2nd retry | 1 hour after the second attempt |
| 3rd retry | 6 hours after the third attempt |
A delivery is considered failed if:
- Your endpoint returns a non-2xx status code
- The request times out
- A connection cannot be established
Event ordering
Section titled “Event ordering”Featurebase doesn’t guarantee that webhook events arrive in the order they were generated. For example, updating a post might generate the following sequence of events:
post.createdpost.updated
However, these events may not be delivered to your endpoint in that exact order. Your integration should not rely on receiving events sequentially, and it must be able to handle them regardless of arrival sequence.
Handle duplicate events
Section titled “Handle duplicate events”Webhook endpoints might occasionally receive the same event more than once. To prevent double-processing, log the unique event IDs that your endpoint has already handled. If a new incoming event’s ID matches a previously processed event, skip it.
{ "object": "notification_event", "topic": "post.updated", "id": "notif_0193a6e6-fb6b-78ef-b71f-15008d9f9cde"}Example deduplication logic
Section titled “Example deduplication logic”const processedEvents = new Set();
function handleWebhook(payload) { if (processedEvents.has(payload.id)) { console.log(`Skipping duplicate event: ${payload.id}`); return; }
processedEvents.add(payload.id); processEvent(payload);}Note: In production, you should persist processed event IDs to a database rather than keeping them in memory.
Quick response time
Section titled “Quick response time”Your endpoint should return a successful (2xx) status code promptly—before performing any lengthy operations that might lead to timeouts.
Good pattern
Section titled “Good pattern”Return 200 immediately, then process:
app.post("/webhook", async (req, res) => { res.status(200).send("OK");
processWebhookEvent(req.body).catch((err) => { console.error("Webhook processing error:", err); });});Bad pattern
Section titled “Bad pattern”Wait for processing before responding:
app.post("/webhook", async (req, res) => { await processWebhookEvent(req.body); res.status(200).send("OK");});This approach prevents timeouts and ensures Featurebase knows your endpoint received the event, even if processing takes longer.
Webhook status
Section titled “Webhook status”Your webhook can have one of the following statuses:
| Status | Description |
|---|---|
active | Webhook is functioning normally |
paused | Webhook is manually paused by you |
suspended | Webhook has been automatically suspended due to repeated failures |
If your webhook is suspended due to failures, you can reactivate it from your dashboard or via the Webhooks API after fixing the underlying issue.