Skip to main content

stapel-webhooks

The reaction layer. Your modules already emit facts — user.registered, listing.published, payment.completed — as schema-typed comm Actions riding a transactional outbox. This is the consumer side: a declarative "when X happens, deliver it to Y" that the app layer and external systems can both use.

comm Action (already there)
   │
   ▼  subscription registry + matcher
   ├─► webhook       HTTP POST, HMAC-signed, retried, dead-lettered
   ├─► notification  email/push/SMS via stapel-notifications
   ├─► ws            live frame on a realtime stream
   └─► custom        allowlisted dotted path in your app

Part of the Stapel framework.

Install

pip install stapel-webhooks
INSTALLED_APPS = [..., "stapel_webhooks"]

path("webhooks/", include("stapel_webhooks.urls"))   # -> /webhooks/api/v1/...

Then schedule the drain — with the default deferred dispatch, nothing is delivered until it runs:

from stapel_webhooks.tasks import get_webhooks_beat_schedule
CELERY_BEAT_SCHEDULE = {**get_webhooks_beat_schedule(), ...}

…or from cron: manage.py deliver_webhooks. (A system check tells you if you forget.)

Subscribe to something

POST /webhooks/api/v1/subscriptions
{
  "event_type": "listing.published",
  "delivery": "webhook",
  "target": {"url": "https://crm.example.com/hooks/stapel"},
  "filter": {"city": "berlin", "price": {"$gte": 500}}
}
→ 201 {"id": "3fa8…", "secret": "whsec_…"}

The secret is returned once, on creation (and again only on rotation) — like an API key.

What is subscribable

Not a list somebody maintains: every event any installed module ships a schema for, scanned out of schemas/emits/.

python manage.py webhooks_event_catalog

Install a module and its facts become subscribable. Uninstall it and they stop being offered. No release of this package either way.

What your receiver gets

X-Stapel-Delivery: 9aa1c0de-…      ← identical across retries; de-duplicate on it
X-Stapel-Event: listing.published
X-Stapel-Signature: t=1755993600,v1=6f1e…c3

{"id":"9aa1…","type":"listing.published","created_at":"…","data":{ … }}

Verify: HMAC-SHA256(secret, f"{t}.{raw_body}"), compared in constant time against the raw bytes — and refuse a t outside your tolerance window, which is the replay guard. In Python, stapel_webhooks.verify(secret, body, header) does it for you and accepts a list of secrets so rotation has an overlap.

When the receiver is down

Exponential backoff with a cap and jitter (8 attempts over ~2 h by default), then a dead letter — a row that keeps the payload and can be replayed from the API with the full ladder again. A 4xx that is not 408/425/429 skips the ladder entirely: eight identical refusals teach nobody anything. A rule that keeps dying deactivates itself and says so on the bus.

Closed by default

  • webhook targets must be https and must resolve to a public address — private, loopback, link-local and the cloud metadata endpoint are refused, with no second DNS lookup between check and connect;
  • delivery does not happen on your request thread;
  • the custom delivery type — a dotted path named by a database row — is unusable until you allowlist your handlers, and can be removed outright.

Each of those has a system check that reports it if you open it.

Documentation

  • MODULE.md — the integration contract: HTTP surface, comm surface, the delivery state machine, every extension point, and the known limitations.
  • CONFIG.MD — every setting, and the four that are decisions rather than tuning.

License

MIT

Metadata

Release files for stapel-webhooks 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stapel-webhooks 0.1.2
File Size Uploaded
stapel_webhooks-0.1.2.tar.gz 96.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stapel-webhooks 0.1.2
File Interpreter ABI Platform
stapel_webhooks-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 177.9 kB

Release files / stapel_webhooks-0.1.2.tar.gz

Download URL stapel_webhooks-0.1.2.tar.gz
Size 96.9 kB
Tags Source
SHA-256 checksum
How to use checksums
feb3f5be2ae63cf9594a01ec2b09347cd08b7223d332142e0494497b632b8e9e
BLAKE2b-256 checksum
How to use checksums
6f8703375c6a539574359a634b08a23c4106d274864a570b1448c741a2b05cd1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / stapel_webhooks-0.1.2-py3-none-any.whl

Download URL stapel_webhooks-0.1.2-py3-none-any.whl
Size 81.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17e87f670b8f469c92db4540cbff7b6baa902572c489007e9bf8e74927c89960
BLAKE2b-256 checksum
How to use checksums
4e4363b17d7a4a266e24a629b6491d9d4121752096b37ba3532c5370df4a751b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page