Documentation Index
Fetch the complete documentation index at: https://docs.snackbase.dev/llms.txt
Use this file to discover all available pages before exploring further.
SnackBase’s Outbound Webhooks let you send HTTP notifications to external services whenever records are created, updated, or deleted. Instead of polling for changes, your external systems receive real-time push notifications.
Overview
Webhooks are configured per-collection and fire on specific events. When an event occurs, SnackBase sends a signed HTTP POST to your configured URL with the record data.
Key Features
- Event-Driven: Fire on
create, update, or delete events
- HMAC-SHA256 Signing: Every delivery is signed with a per-webhook secret
- Automatic Retries: Failed deliveries are retried up to 5 times with exponential backoff
- Delivery Tracking: Full history of every delivery attempt with status codes and response bodies
- Filter Expressions: Conditionally fire webhooks based on record data
- Custom Headers: Add custom HTTP headers to webhook deliveries
How It Works
┌──────────────┐ ┌────────────────────┐ ┌──────────────────┐
│ Record │ │ SnackBase │ │ Your Server │
│ Operation │────>│ Webhook Engine │────>│ (HTTPS endpoint)│
│ (create/ │ │ │ │ │
│ update/ │ │ 1. Match webhook │ │ Verify signature│
│ delete) │ │ 2. Evaluate filter│ │ Process payload │
│ │ │ 3. Sign payload │ │ │
└──────────────┘ └────────────────────┘ └──────────────────┘
Webhook Configuration
Each webhook is defined with:
| Field | Type | Required | Description |
|---|
url | string | Yes | Destination URL (max 2048 chars). HTTPS required in production. |
collection | string | Yes | Collection to watch (max 100 chars) |
events | string[] | Yes | Events to fire on: "create", "update", "delete" |
secret | string | No | HMAC signing secret. Auto-generated (64 hex chars) if not provided. |
filter | string | No | Rule expression to conditionally fire |
headers | object | No | Custom HTTP headers to include in deliveries |
enabled | boolean | No | Active status (default: true) |
Event Types
| Event | Fires When |
|---|
create | A new record is created in the collection |
update | An existing record is updated |
delete | A record is deleted |
Delivery Payload
Every webhook delivery sends a JSON POST request with this structure:
{
"event": "records.create",
"collection": "orders",
"record": {
"id": "abc-123",
"status": "pending",
"total": 99.99,
"created_at": "2025-01-15T10:30:00Z"
},
"previous": null,
"timestamp": "2025-01-15T10:30:01Z",
"webhook_id": "wh-uuid",
"account_id": "AB1234"
}
record: The current state of the record (null for delete events)
previous: The previous state (only present for update and delete events)
Security
HMAC-SHA256 Signing
Every delivery includes a signature header for verification:
X-SnackBase-Signature: sha256=a1b2c3d4e5f6...
The signature is computed as HMAC-SHA256(secret, request_body). To verify on your server:
import hmac
import hashlib
def verify_signature(payload: bytes, secret: str, signature_header: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
The webhook secret is only returned once — when the webhook is created. Store
it securely.
Every delivery also includes:
| Header | Description |
|---|
Content-Type | application/json |
X-SnackBase-Signature | HMAC-SHA256 signature |
X-SnackBase-Event | Event type (e.g., records.create) |
X-SnackBase-Webhook-Id | Webhook UUID |
URL Validation
In production, SnackBase enforces:
- HTTPS only — HTTP URLs are rejected
- No private IPs — Prevents SSRF attacks by blocking
127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, and IPv6 equivalents
Filter Expressions
Use filter expressions to conditionally fire webhooks based on record data:
status = "published"
rating >= 4.5
category IN ["electronics", "books"]
title ~ "Product%"
If a filter expression fails to evaluate, the webhook fires anyway (fail-open
design). This prevents silent data loss.
Retry Logic
Failed deliveries are automatically retried with exponential backoff:
| Attempt | Delay |
|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 12 hours |
A delivery is considered successful when it receives a 2xx HTTP response. Non-2xx responses or network errors trigger retries.
Delivery Statuses
| Status | Meaning |
|---|
pending | Not yet delivered |
delivered | Successfully received (2xx response) |
retrying | Failed, scheduled for retry |
failed | All retry attempts exhausted |
Testing
Use the built-in test endpoint to verify your webhook setup:
curl -X POST https://api.snackbase.dev/api/v1/webhooks/{webhook_id}/test \
-H "Authorization: Bearer {token}"
This sends a test payload to your configured URL and returns the result immediately (synchronous).
Limits
| Limit | Default |
|---|
| Max webhooks per account | 20 (configurable) |
| URL max length | 2048 characters |
| Response body storage | Truncated to 5000 characters |
| HTTP timeout per delivery | 30 seconds |
| Max retry attempts | 5 |
When to Use Webhooks vs Other Features
| Feature | Best For |
|---|
| Webhooks | Push notifications to external services |
| API-Defined Hooks | Internal automation (actions within SnackBase) |
| Workflows | Multi-step processes with conditions and delays |
| Realtime (WebSocket/SSE) | Client-side live updates |