Normal generation-event delivery
For the subscribed generation events, BabySea uses the normal delivery path in the webhook service.
Each delivery attempt includes:
X-BabySea-Signature
X-BabySea-Event
X-BabySea-Timestamp
X-BabySea-Delivery-Id
- A JSON body with the same event data
What triggers another attempt
BabySea retries a delivery when your endpoint:
| Condition | Description |
|---|
| Non-2xx response | Any HTTP status outside the 200-299 range, including 3xx redirects |
| Timeout | Your endpoint does not respond within 10 seconds |
| Connection error | TCP connection refused, DNS failure, TLS handshake error |
BabySea treats redirects as failures because only 2xx responses count as successful delivery.
Retry schedule
BabySea makes up to 5 attempts using this delay schedule:
| Attempt | Delay after previous attempt | Cumulative time |
|---|
| 1 | Immediate | 0 seconds |
| 2 | 1 second | 1 second |
| 3 | 4 seconds | 5 seconds |
| 4 | 16 seconds | 21 seconds |
| 5 | 60 seconds | 81 seconds |
After the fifth failed attempt, BabySea logs the failed delivery with the final status code or error.
Auto-disable
If a webhook endpoint accumulates 15 consecutive delivery failures (across any events, not just a single delivery), BabySea automatically disables it. This prevents hammering an endpoint that is persistently down.
When auto-disable triggers:
| What happens | Details |
|---|
| Webhook status changes to Disabled | Visible as a red badge in your dashboard |
| Matching events can queue to the dead letter queue | Queued items are held for up to 72 hours |
| No deliveries are attempted | Until you re-enable the webhook |
The consecutive failure counter resets to zero when any delivery succeeds (receives a 2xx response).
Dead letter queue (DLQ)
When BabySea finds no active webhook for the account, it checks disabled webhooks and can queue matching events into the dead letter queue.
| Property | Value |
|---|
| Retention | 72 hours from when the event was queued |
| Status values | pending, delivered, expired |
| Scope | Per webhook |
| Event filtering | Only events matching the webhook’s subscribed events are queued |
DLQ events expire after 72 hours. Re-enable a disabled webhook and drain the queue promptly to recover missed events.
Draining the DLQ
After re-enabling a webhook, you can deliver all queued events from the webhook details page:
Re-enable the webhook
Toggle the status switch to Enabled on the Webhook details page.
Click Deliver queued events
A banner appears when there are pending DLQ items. Click Deliver queued events to start draining.
BabySea re-delivers queued items
Each queued event is sent with a fresh delivery ID, fresh timestamp, and a fresh HMAC signature. The stored event payload is preserved.
DLQ drain behavior:
| Behavior | Details |
|---|
| Retries | Single attempt per item (no automatic retries) |
| Signatures | Fresh HMAC signature computed for each delivery |
| Delivery IDs | New UUID for each delivery (not the original) |
| Active webhook required | Yes. The endpoint must be enabled before drain can run |
The webhook.test event is never queued to the DLQ. Test events are for manual verification only.
Replaying deliveries
You can manually replay a previous delivery from the Webhook events table on Webhook details.
| Property | Value |
|---|
| Delivery ID | Fresh UUID (not the original) |
| Timestamp | Fresh ISO 8601 timestamp |
| Signature | Fresh HMAC computed with current secret |
| Payload | Original webhook_data preserved exactly |
| Retries | Single attempt (no automatic retries) |
| Rate limit | 1 replay per delivery log entry per 10 seconds |
| Active webhook required | Yes |
Replays are useful for:
- Recovering from transient processing failures in your handler.
- Testing changes to your webhook processing logic against real payloads.
- Re-delivering events after fixing a bug in your endpoint.
Events table
The webhook details page includes the Webhook events table with these columns:
| Column | Description |
|---|
| Event | The webhook_event value (e.g., generation.completed) |
| Generation ID | The generation_id from the payload |
| Status | HTTP response code from your endpoint, color-coded by outcome |
| Error | Error message if the delivery failed |
| Attempts | Number of delivery attempts made |
| Delivered at | The recorded delivery timestamp |
| Actions | Resend button for manual replay |
Status codes are color-coded:
| Color | Meaning |
|---|
| Green | 2xx success |
| Red | 4xx or 5xx failure |
| Amber | 429 rate limited |
The page also supports search, batch selection, and export or copy actions.
Webhook statuses
A webhook can be in one of two statuses:
| Status | Badge | Deliveries | DLQ behavior |
|---|
| Enabled | Green | Active | Not used |
| Disabled | Red | Paused | New events queue for up to 72 hours |
A webhook starts as Enabled when created. It becomes Disabled in two ways:
| Trigger | How it happens |
|---|
| Manual | You toggle the status switch on the webhook details page |
| Auto-disable | BabySea disables it after 15 consecutive delivery failures |
Enable and disable
Toggle the status switch on the Webhook details page to enable or disable a webhook. Only Owner and Primary Owner roles can toggle status.
When you disable a webhook:
- BabySea stops delivering events to the endpoint immediately.
- New events are queued in the dead letter queue (DLQ) for up to 72 hours.
- The delivery log is preserved.
When you re-enable a webhook:
- BabySea resumes delivering new events immediately.
- A banner appears if there are pending DLQ items. Click Deliver queued events to drain the queue.
Rotate secret
If your webhook secret is compromised or you want to refresh it on a regular schedule, generate a new secret from the webhook details page.
Open Webhook details
Navigate to the Webhook details page for the endpoint you want to update.
Click Rotate secret
Click Rotate secret. The dialog says the old secret will stop working immediately.
Copy the new secret
The new secret is displayed in a dialog:whsec_x9Y8z7W6v5U4t3S2r1Q0p9O8n7M6l5K4
Copy this secret immediately. It is shown only once and cannot be retrieved later.
Update your environment
Replace the old secret in your environment variables and redeploy before any new events arrive:BABYSEA_WEBHOOK_SECRET=whsec_x9Y8z7W6v5U4t3S2r1Q0p9O8n7M6l5K4
When you rotate a secret:
| What happens | Details |
|---|
| Old secret is invalidated immediately | All new deliveries use the new secret |
There is no grace period where both old and new secrets are accepted simultaneously. Update your endpoint to use the new secret before BabySea sends the next event.
Send test event
Click Send test event on the Webhook details page to verify your endpoint is reachable and correctly verifying signatures.
| Property | Value |
|---|
| Event type | webhook.test |
| Generation ID | 00000000-0000-0000-0000-000000000000 |
| Model identifier | test |
| Generation status | succeeded |
| Retries | None (single attempt) |
| Rate limit | 1 test per webhook per 30 seconds |
Delete endpoint
Click Delete on the Webhook details page to permanently remove a webhook endpoint.
| What is removed | Details |
|---|
| Webhook configuration | URL, events, secret, status |
| All delivery logs | Full event history for this endpoint |
| All DLQ items | Pending, delivered, and expired items |
Deletion is permanent and cannot be undone. All delivery history and queued events are lost. If you only need to temporarily stop deliveries, use the disable toggle instead.