On most platforms, ‘tell my system when a subscription lapses’ becomes a support ticket and an engineering estimate. On an event-driven core it’s a checkbox: subscribe an endpoint to any event the platform or its plugins publish, and signed deliveries start arriving. The difference between a platform where integration is a project and one where it’s configuration.
On most platforms, ‘tell my system when a subscription lapses’ becomes a support ticket and an engineering estimate.
There’s a request every product team hears eventually. It sounds trivial coming from the customer’s mouth: “Can you notify our system when X happens?” When an order is paid. When a subscription is cancelled. When stock drops below a threshold. When a booking is confirmed. To the person asking, it’s obviously a small thing — the event clearly happens somewhere inside your software, so surely you can just… tell them about it.
What happens next tells you almost everything about how a platform is built. On some platforms that sentence becomes a support ticket, then a scoping call, then a line item on next quarter’s roadmap. On others it’s a checkbox the customer ticks themselves in an afternoon. Same request, wildly different cost — and the difference is architecture, not effort.
Why “just notify us” turns into a project
On a platform that wasn’t designed around events, the state change the customer cares about lives inside a specific function, in a specific code path, and nothing outside that function knows it happened. So “notify us when X happens” expands into real work:
- An engineer has to find every place X can occur — and there are usually more than they think.
- At each of those places, add an outbound HTTP call, then add signing so the receiver can trust it.
- Add retries and backoff, because networks fail and the customer’s endpoint will be down sometimes.
- Make sure a failed notification doesn’t roll back or block the original transaction.
- Persist every attempt so someone can debug it when the customer says “we never got the callback.”
None of that is exotic, but all of it is fiddly, and all of it has to be re-done, or copy-pasted and subtly broken, for the next event a different customer asks about. That’s why so many platforms ship a “webhooks” feature that supports a short, fixed menu of events: those were the ones somebody had budget to wire up by hand. Ask for an event outside the menu and you’re back to a ticket.
What it looks like when the core is event-driven
An event-driven platform inverts the default. Instead of state changes being private facts buried in a handler, every meaningful one is published as an event. In VBWD, code that does something important calls event_bus.publish("payment.captured", {…}). The event is a first-class thing the moment it happens.
Then there’s one more trick that changes the economics entirely: a single wildcard subscriber listens to every published event and relays it to the outbound webhook layer. That relay is deliberately agnostic — it doesn’t know or care which part of the system produced the event, and it never hard-codes a list of “supported” types. It forwards whatever comes through.
So when a customer says “notify our system when X happens,” nobody goes hunting through code. If X is already published as an event — and across VBWD’s plugins a great many things are: subscription.activated, subscription.cancelled, subscription.expired, shop stock and line-item events, booking events, dataset and discount events, marketplace invoice.paid and invoice.refunded — then subscribing to it is a configuration step through the /admin/webhooks API. The customer registers an endpoint and picks their events. A subscription can be surgical, listening only for ["payment.captured"], or a firehose listening on ["*"]. Because the relay carries whatever is published, an event that a newly enabled plugin starts emitting automatically reaches the firehose subscribers — no core change, no deployment, no ticket.
The parts you’d otherwise have to build, already built
The checkbox only feels safe because the hard engineering sits underneath it, done once and done properly. Deliveries are HMAC-SHA256 signed over the exact JSON body with a per-subscription secret, carrying X-VBWD-Signature, X-VBWD-Event, X-VBWD-Delivery-Id and X-VBWD-Timestamp headers; the receiver verifies by recomputing the HMAC over the raw body with a constant-time compare. Enqueue is synchronous — publishing writes a pending delivery row — while a background scheduler makes the actual HTTP POST out of band, so a webhook failure never breaks event emission. Retries use capped exponential backoff (base 30 seconds, cap six hours, up to five attempts), every attempt is persisted with its status and response, and a subscription that fails five times in a row auto-disables and is surfaced as failed so a dead endpoint is visible rather than silently swallowing events.
An honest caveat: this is durable near-real-time, not sub-second. The scheduler dispatches on a short cycle rather than the instant of publication — a deliberate trade of a little latency for reliability. For “update our warehouse when an order ships” that’s exactly right; for a hard real-time control loop it’s worth knowing up front.
Two more things matter for the people who’ll live with the decision. Because VBWD is written in tested Python with conventions structured for coding agents to follow, adding a new event to publish is a small, reviewable change. And because it’s self-hosted and source-available under BSL 1.1 (free while annual VBWD-attributable sales stay under the value of 6.7 BTC a year), the event bus, the delivery records and the signing secrets all live inside your perimeter, not a vendor’s. If you want the full mechanics, they’re laid out in Webhooks in VBWD, Part 1: the event-driven engine.
The tell is simple. Ask a platform how long it takes to be notified when something happens inside it. If the answer is a scoping call, you’re paying an architecture tax. If it’s a checkbox, you’re not. When that difference maps to a conversation happening in your own organisation, the useful next step is concrete: Request an enterprise installation and bring the notifications your customers keep asking for.
VBWD is source-available — get the SDK on GitHub.