Skip to content
Last updated

Event delivery behaviors

This section helps you understand different behaviors to expect regarding how Featurebase sends events to your webhook endpoint.

Retry behavior

If a webhook delivery fails, Featurebase will automatically retry up to 3 times:

AttemptDelay
1st retry1 minute after the first attempt
2nd retry1 hour after the second attempt
3rd retry6 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

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:

  1. post.created
  2. post.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

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

const processedEvents = new Set();

function handleWebhook(payload) {
  // Check if we've already processed this event
  if (processedEvents.has(payload.id)) {
    console.log(`Skipping duplicate event: ${payload.id}`);
    return;
  }

  // Mark as processed
  processedEvents.add(payload.id);

  // Process the event
  processEvent(payload);
}

Note: In production, you should persist processed event IDs to a database rather than keeping them in memory.

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

Return 200 immediately, then process:

app.post("/webhook", async (req, res) => {
  // 1. Return 200 OK right away
  res.status(200).send("OK");

  // 2. Process the webhook asynchronously
  processWebhookEvent(req.body).catch((err) => {
    console.error("Webhook processing error:", err);
  });
});

Bad pattern

Wait for processing before responding:

app.post("/webhook", async (req, res) => {
  // Don't do this - it could timeout
  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

Your webhook can have one of the following statuses:

StatusDescription
activeWebhook is functioning normally
pausedWebhook is manually paused by you
suspendedWebhook 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.