Deduplication is best-effort load reduction, not an exactly-once guarantee. Keep your own
handler idempotent — dedup reduces duplicates, it doesn’t promise their absence.
The default
Every endpoint starts on theidentifier mode with a 24-hour window. It keys each request on the
first stable signal it finds:
- a Standard Webhooks
webhook-idheader, - a recognized provider’s event id (header- or body-borne), then
- a content hash of the request — the HTTP method, a canonicalized path + query, and the body, within the time window.
Modes
Set a per-endpointdedupConfig to change how the key is derived:
| Mode | Keys on | Use it when |
|---|---|---|
identifier (default) | id ladder, then content hash | the sender supplies a stable id, or you want the safe default |
content | the canonical request content (method + path + query + body) | the sender’s ids are unreliable or reused across distinct events |
fields | operator-selected field paths | the sender has no stable id but a stable field (e.g. body.data.id) |
off | nothing — every request is its own event | you want to capture every request (testing, debugging) |
off) takes a windowSeconds (60–604800). off disables collapsing entirely.
Field paths
fields mode keys on values you select with field paths. A path starts with a root — headers, body,
query, or path — and addresses into it with dot notation and array accessors:
body.data.id— a nested body valueheaders.x-event-id— a header valuequery.id— a query parameterbody.items[*].sku— every element of an array ([*]wildcard, or[0]for one index)
include paths (the values that make up the key) and optionally exclude paths (volatile fields
to drop, like a per-delivery timestamp). If a configured field is missing from a request, that request is
treated as distinct rather than collapsed — webhook.co never silently drops an event it can’t key.
Configure it
Deduplication is configured identically across every surface — set it when you create an endpoint, or update it any time.--dedup-reset (CLI) or a null dedupConfig (API) returns an endpoint to the
default.
From the CLI:
PATCH it later: