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. Postel is a library that handles those for you, inside your application, against your existing relational database (Postgres, MySQL, SQLite, …) — no Redis, no broker, no separate dispatcher process.
Two halves, one library
Postel has two independent halves. Use either alone, or both together.
| Half | What it does |
|---|---|
| Inbound | Verify webhooks other services send you — Standard Webhooks, plus ready-made Stripe / GitHub / Shopify / Twilio / Slack verifiers. Constant-time checks, rotation windows, JWKS, dedup. |
| Outbound | Deliver Standard Webhooks to your customers' endpoints. Transactional outbox, retries, replay, fanout, key rotation, JWKS publication, circuit breaker, dead-letter — durable on Postgres, MySQL, or SQLite. |
The Postel({ inbound, outbound }) factory composes both — but everywhere else in these docs they're separated, so you never wade through sender material to integrate the receiver, or vice versa.
Start here
Quickstart
Verify an inbound webhook and send an outbound one, from scratch.
Is Postel for me?
The decision gate — run it before you spend more time evaluating.
How Postel works
The mental model: outbox, worker pool, delivery lifecycle, receiver.
Why Postel
The design rationale and the comparison vs Svix, Outpost, Convoy, DIY.
Go deeper
Inbound
Verification, provider verifiers, key rotation, deduplication.
Outbound
send(), retries, replay, endpoints, introspection, tenants.
Web adapters
Hono, Express, Fastify, NestJS, Next.js — or any Fetch runtime.
Storage
pg / sqlite / mysql, or your Kysely, Drizzle, Prisma, TypeORM, MikroORM instance.
On an Effect-TS stack? @postel/effect wraps the whole API — Layer-managed lifecycle, typed error channel, Effect-wrapped send/verify. Want to see it running first? The nextjs-prisma example round-trips a webhook offline, crash demo included.
Where the project stands
Both halves are implemented and exercised end-to-end by the @postel/compliance suite. Three things to know before you build on it:
- No release is cut yet — nothing is on npm. Run it from source today; pin to a minor once releases ship.
- Unwired config slots fail fast: external job-queue workers, KMS-backed keys, retention, ephemeral keys, and a few HTTP knobs throw
NotImplementedErrorinstead of silently no-opping. Outbound marks each one. - Go, Python, and Rust ports follow the TypeScript implementation, each gated on the same compliance suite — see Polyglot.
If a page describes behavior the source doesn't have, open an issue.