Webhook delivery
you run yourself

Sparrow is an open-source webhook delivery server: at-least-once delivery, retries with error classification, signed deliveries, and OpenTelemetry tracing. One Go binary. One PostgreSQL database.

MIT licensed Go + PostgreSQL OpenAPI 3.1 llms.txt
PUSH AN EVENT

One POST. Sparrow does the rest.

Push an event with an idempotency key and Sparrow validates it, persists it, and fans out to every matching subscription. Duplicate pushes are detected and returned as such.

Each delivery arrives signed per Standard Webhooks — HMAC-SHA256 with a shared secret by default, or switch a webhook to Ed25519 to verify with a public key instead.

Quickstart
terminal
$ curl -X POST "http://localhost:8080/v1/consumers/payments/events?event=invoice.created" \ -H "Content-Type: application/json" \ -H "X-API-Key: sk_live_..." \ -d '{ "payload": '{"id":"inv_01","amount":4999}', "idempotency_key": "idem_abc123" }' // 201 Created { "event_id": "evt_7f3a...", "duplicate": false }
DELIVERY PIPELINE

Five stages, all in PostgreSQL

River workers drive the pipeline over the same database that stores your events. Fan-out matches subscriptions and applies per-subscription Go template transforms; delivery POSTs with signatures and per-webhook rate limits.

When a delivery fails, the error is classified before anything else happens. Retryable failures back off exponentially; permanent ones stop immediately and mark webhook health.

How it works
01
Push event Validate, persist, dedup
02
Fan-out Match subscriptions, transform
03
Queue River workers, rate limiting
04
Deliver HTTP POST, signed (HMAC / Ed25519)
05
Retry Classify, backoff, health track
SATELLITES

Satellites orbit the core — they never touch it

Companion tools built entirely on the public REST API and signed-webhook contract. The core stays one small server; every satellite — including yours — inherits retries, signing, and the delivery audit trail. How satellites work →

COMPARISON

How Sparrow stacks up

Directional snapshot against the main alternatives — vendors change packaging often, so verify details against their docs. Full feature comparison →

SparrowSvixConvoyHookdeckDIY
Fully open source (MIT)YesPartialNo (Elastic 2.0)PartialYes
Core infrastructurePostgreSQL onlyPostgreSQL + RedisPostgreSQL + RedisSaaSVaries
Webhook signingHMAC-SHA256 + Ed25519HMAC-SHA256HMAC-SHA256HMAC-SHA256Manual
Secrets at restEnvelope encryption, per-record DEKsEncrypted at restDeployment-dependentVendor-managedManual
Payload transformsGo templates, cached, no JS runtimePlan-dependentJavaScriptJavaScriptManual
Prebuilt integrationsRecipes: Slack, Discord, PagerDuty, ntfy, ClickHouseLimitedLimitedYesManual
Self-monitoring alertsSystem events + email alertsOperational webhooksAlert configsIssue alertsManual
Tracing & metricsOpenTelemetry end-to-endLoggingPrometheusDashboardManual
Consumer portalYes — self-hosted, token-scopedYesYesYesNo
GET STARTED

Two commands to try it

Download the Compose file and bring it up. No clone, no secrets, no .env -- PostgreSQL included, migrations run automatically on first boot.

terminal
$ curl -O https://raw.githubusercontent.com/sarathsp06/sparrow/main/deploy/docker-compose.yml $ docker compose up -d Creating sparrow-postgres-1 ... done Creating sparrow-sparrow-1 ... done $ open http://localhost:8080