Skip to main content
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:
FieldTypeRequiredDescription
urlstringYesDestination URL (max 2048 chars). HTTPS required in production.
collectionstringYesCollection to watch (max 100 chars)
eventsstring[]YesEvents to fire on: "create", "update", "delete"
secretstringNoHMAC signing secret. Auto-generated (64 hex chars) if not provided.
filterstringNoRule expression to conditionally fire
headersobjectNoCustom HTTP headers to include in deliveries
enabledbooleanNoActive status (default: true)

Event Types

EventFires When
createA new record is created in the collection
updateAn existing record is updated
deleteA 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.

Additional Headers

Every delivery also includes:
HeaderDescription
Content-Typeapplication/json
X-SnackBase-SignatureHMAC-SHA256 signature
X-SnackBase-EventEvent type (e.g., records.create)
X-SnackBase-Webhook-IdWebhook 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:
AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry12 hours
A delivery is considered successful when it receives a 2xx HTTP response. Non-2xx responses or network errors trigger retries.

Delivery Statuses

StatusMeaning
pendingNot yet delivered
deliveredSuccessfully received (2xx response)
retryingFailed, scheduled for retry
failedAll 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

LimitDefault
Max webhooks per account20 (configurable)
URL max length2048 characters
Response body storageTruncated to 5000 characters
HTTP timeout per delivery30 seconds
Max retry attempts5

When to Use Webhooks vs Other Features

FeatureBest For
WebhooksPush notifications to external services
API-Defined HooksInternal automation (actions within SnackBase)
WorkflowsMulti-step processes with conditions and delays
Realtime (WebSocket/SSE)Client-side live updates