Welcome

A polyglot library for sending and receiving webhooks reliably and securely. It does two halves — inbound and outbound — and you can use either alone.

Sending and receiving webhooks is easy. Doing it reliably and securely is hard — retries, replay, signature verification, key rotation, idempotency, raw-bytes preservation. That's where Postel comes in: a polyglot library that handles those for you. It runs inside your application against your existing relational database (Postgres, MySQL, SQLite, …) — no Redis, no broker, no separate dispatcher process.

Svix is for when webhooks are your product. Postel is for when webhooks are a feature of your product.

Two halves, one library

Postel has two independent halves. Use either alone, or both together.

HalfWhat it doesStatus
InboundVerify Standard Webhooks-signed requests other services send to you. Constant-time signature checks, multi-secret rotation windows, JWKS, idempotent dedup, raw-bytes preservation.Available in @postel/core.
OutboundDeliver Standard Webhooks to your customers' endpoints. Transactional outbox, retries, replay, fanout, key rotation, JWKS publication, circuit breaker, dead-letter.Available in @postel/core, with durable Postgres, MySQL, and SQLite storage adapters.

The Postel({ inbound, outbound }) factory composes both — but everywhere else in these docs they're separated. You shouldn't have to wade through outbound material to integrate the receiver, or vice versa.

Picking a starting point

Where the project stands

Both halves are implemented and exercised end-to-end by the @postel/compliance suite. The receiver verifies any Standard Webhooks producer. The sender runs the transactional outbox, retries, replay, fanout, and signing against durable Postgres, MySQL, and SQLite adapters — or the in-process InMemoryStorage for tests and demos.

What's still ahead is tracked honestly, not hidden:

  • No release is cut yet. Every @postel/* package sits at 0.0.0 with no git tag, so nothing is on npm. Clone the repo to use it today; pin to a minor once releases ship.
  • Unwired config slots fail fast instead of lying. External job-queue workers (BullMQ, PgBoss), KMS-backed keys (AwsKms / GcpKms / Vault), retention, ephemeral keys, and the http.tls / http.dns knobs aren't wired yet — configuring any of them throws NotImplementedError rather than silently no-opping. observability.logger is wired and receives delivery / circuit events; full OpenTelemetry + Prometheus is deferred. Outbound marks each one.
  • Other languages are on the way. Go, Python, and Rust are on the roadmap; TypeScript ships first.

This site is the public surface of that work. If a page describes behavior the source doesn't have, open an issue.

On this page