# Deduplication

Drop repeated requests from senders that retry, so you create and deliver each event once.

Senders retry. A Stripe webhook that took too long to answer, a GitHub redelivery, a partner's job that ran twice: all arrive more than once. Deduplication makes Ensue recognise a repeat and create nothing new.

## How it works

Give a source a **dedupe key**: the place in each request that identifies it, such as an event ID.

| Form | Example |
|---|---|
| A path into the JSON body | `id`, `data.event_id` |
| A request header | `headers.x-github-delivery` |

The first request with a given value is accepted as usual. A later request with the **same value** is recognised as a repeat. Ensue answers the sender exactly as it did the first time, with the first request's ID, and creates no request record, no events and no deliveries. The repeat is noted on the first request's [timeline](/gateway/events-and-timeline/).

Because the repeat is acknowledged, the sender stops retrying.

## Set it up

```bash
curl -X PATCH https://api.getensue.com/v1/sources/src_… \
  -H "authorization: Bearer ens_<key>" -H "content-type: application/json" \
  -d '{ "dedupe": "headers.x-github-delivery" }'
```

Choose a value that is **stable across the sender's retries** and **unique per thing that happened**. Prefer the sender's event ID over a timestamp or an object ID: an object (an order, say) appears in many different events.

## What is and isn't deduplicated

- Repeats are matched **per source**. The same value on two sources is not a duplicate.
- Dedupe values are remembered for **3 days**. A repeat after that creates a new event.
- Deduplication happens on **arrival**. It does not remove duplicate events that your own [replays](/gateway/replay-and-dead-letters/) create on purpose.
- It does not replace idempotent handlers. Delivery to your destination is at least once, so key your handler on `x-ensue-event-id` too.

> [!NOTE]
> A request that has no value at the dedupe path is accepted normally and is never treated as a duplicate.