All Glossary Terms
Core

What is a webhook event?

A webhook event is a single occurrence in a source system that triggers one webhook delivery — for example, a payment succeeding. Events are typed (Stripe has `payment_intent.succeeded`, GitHub has `pull_request.opened`) and the type string is the most important field in the payload because it tells your handler which code path to run. Each event has an event ID — a string the source generates to identify this specific occurrence — which serves as the natural idempotency key when retries arrive. One event can produce zero, one, or many deliveries depending on retries; treat events as facts about the past, not commands.

An event is the abstract thing that happened. A webhook delivery is the HTTP request that announces it. The two are not the same: one event can produce zero, one, or many deliveries depending on retries, fan-out subscriptions, and provider-side filtering.

Events are typed. Stripe has payment_intent.succeeded, payment_intent.payment_failed, customer.subscription.created, and ~150 others. GitHub has push, pull_request.opened, pull_request.synchronize. The event type string is the most important field in the payload because it tells your handler which branch of code to run. Always switch on the type string explicitly — never assume "any webhook from Stripe means a payment happened."

Each event has an event ID — a string the source generates to identify this specific occurrence. Stripe calls it id (evt_1MnHyz...). GitHub uses a X-GitHub-Delivery header. The event ID is the idempotency key for your handler: if you see the same event ID twice (and you will, because providers retry on timeout), you should not double-process it.

Subscriptions vary. Some providers send all events to all registered endpoints. Others let you filter — Stripe, for example, lets you choose which event types each endpoint receives. Pick narrowly: every event your endpoint receives is one your handler must validate and consider. Subscribing to "everything" creates more attack surface and more code paths to maintain.

The relationship between events and ordering is subtle. Most providers do not guarantee delivery order. Stripe's docs say "events may not arrive in the order they occurred." If your business logic depends on order — "the subscription must be created before the first invoice is paid" — your handler must be ordering-agnostic, usually by re-fetching the source object's current state instead of trusting the event payload to be the latest version.

Treat events as facts about the past, not as commands. The payment_intent.succeeded event is asserting "at time T, this payment succeeded." Your handler's job is to make your system reflect that fact, idempotently.

See Webhook Event in real traffic

WebhookWhisper captures every webhook with full headers, body, signature, and timing — so concepts like webhook event stop being abstract and become something you can inspect.

Start Free