Skip to content

How requests are processed

Every request that reaches an endpoint walks the same fixed pipeline, in the same order — and it is acknowledged and durably buffered before any of your configuration runs. Verification, routing, transforms and delivery all happen after the event is safe on disk, so a misconfigured endpoint can never lose a webhook. This page walks the pipeline stage by stage; the console's endpoint Overview shows the same stages live for your latest request.

The pipeline

sender ──▶ ① ack & buffer ──▶ ② respond ──▶ ③ verify ──▶ ④ store ──▶ ⑤ route ──▶ ⑥ deliver
              (edge)             (edge)        (processing plane ──────────────────────▶)

                                                            └──▶ ⚲ mirror   (additive, pre-verification)
#StageWhereWhat happens
Ack & bufferedgeThe request is accepted and durably buffered, and a time-sortable event id (ULID) is minted — this id follows the event through every later stage and log.
RespondedgeThe sender gets its synchronous answer immediately: the default 200 · {"received":true}, a provider handshake (Slack url_verification, Meta hub.challenge, …), or your custom response rules / response proxy. The sender is never kept waiting on your downstream.
Verifyprocessing planeIf the endpoint has signature verification configured, the signature is checked here — after the ack, per the verify-as-verdict model. A passing event continues; a failing signature is quarantined — durable and inspectable, never delivered, never a 401, never silently dropped.
Storeprocessing planeThe event and the raw request (headers + body) are written to the log — replayable for the retention window (30 days by default). Bodies over the claim-check threshold are spilled to object storage and resolved transparently on read.
Routeprocessing planeThe endpoint's routes fan the event out to its destinations, applying any per-route filters and transforms. No destinations configured means the pipeline stops here by design — the event is stored and pullable. No matching route parks the event as unrouted, replayable once a route exists.
Deliverprocessing planeEach destination gets the request envelope{ url, method, headers, data, received_at } (or your transform's output with the original under original) — with Standard-Webhooks signing, a 15 s timeout, jittered retries (8 attempts over ~28 h), a per-destination circuit breaker, and a dead-letter queue on exhaustion. Every attempt is logged.

The guarantee that falls out of the ordering: configuration can never drop a webhook. Stages ③–⑥ only ever decide what happens to an event that already exists durably.

Mirror: an additive parallel tee

If the endpoint has a mirror attached, a byte-exact copy of the request is teed to the mirror URL in parallel — branching off after the event is buffered (stage ①) and before verification (stage ③), so a signature-failed (quarantined) request still mirrors, and the downstream verifies the provider's original signature itself. Mirroring is purely additive: it uses the same delivery machinery (15 s timeout, jittered retries, per-destination circuit breaker, DLQ, every attempt logged) but never affects the sender's response, the verdict, routing, or delivery. A held (paused-endpoint) request mirrors on unpause/replay; a dropped_unknown request never mirrors. In the console trace the mirror shows as a Mirrored stage on your latest request when an attempt exists.

Every outcome, named

A request always ends in exactly one outcome, and the event it creates can then reach one of a few downstream states. The console label and the underlying pipeline name line up:

Pipeline outcome / stateConsole showsMeaningRecoverable?
acceptedstoredReceived, responded, stored. Routed and delivered if routes exist.— (this is success)
parked_inactiveheldThe endpoint exists but is paused — the event is stored, nothing is delivered.Yes — resumes on unpause, or replay
dropped_unknownrejectedNo endpoint matched the path. Counted and inspectable in the request log; no event is created.Replay after creating the endpoint
event quarantinedquarantinedSignature verification failed. Stored, inspectable, never delivered.Yes — inspect, fix the secret, replay
event unroutedunroutedEndpoint active but no route matched.Yes — add a route, replay
event dlqdead-letterDelivery exhausted all retries.Yes — redrive

See it happen

Send a request to your endpoint, then read back exactly what the pipeline did with it:

bash
# 1) A provider (or you) POSTs to your endpoint
curl -s https://<ingest-domain>/<your-slug> \
  -H "Content-Type: application/json" -d '{"hello":"world"}'
# → 200 {"received":true}   (stage ② — answered at the edge)

# 2) The raw request, as the front door saw it (stage ④)
curl -s "https://api.emithook.com/v1/requests?endpoint=<endpoint-id>" \
  -H "Authorization: Bearer $EMITHOOK_API_KEY"

# 3) The event with every delivery attempt (stages ⑤–⑥)
curl -s "https://api.emithook.com/v1/events/<event-id>" \
  -H "Authorization: Bearer $EMITHOOK_API_KEY"

In the console, the endpoint's Overview renders this as the Your latest request trace — one row per stage that actually ran, with per-stage timestamps.

Where to go next

Emithook · a Finnoto product