> ## Documentation Index
> Fetch the complete documentation index at: https://getconvoy.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotency

Idempotent HTTP requests refer to the characteristic of certain HTTP methods that
allows them to be safely and repeatedly executed without altering the state of the server
beyond the initial request. These methods include GET, HEAD, PUT, and DELETE, while POST
stands apart as a non-idempotent member. With convoy, you can now deduplicate events by
specifying parts of the request for convoy to use as the idempotency key.

While POST requests aren’t normally non-idempotent, the introduction of an Idempotency
key passed via a header can be used to de-duplicate them. When sending out webhook
requests we set the `X-Convoy-Idempotency-Key` header whenever the event has an idempotency
key, and your receiver can use it to de-duplicate events sent by Convoy. In the next two sections, we will talk about how to configure
idempotency keys for both incoming and outgoing projects and how to de-duplicate events sent or received.

## Idempotency in Incoming Projects

With Convoy, you can inspect parts of a request to extract the idempotency key. You can define idempotency keys in both the request body or header. When creating a source you can specify the location of the idempotency key which convoy will use to generate a SHA256 checksum value.

To get started create a source and specify the idempotency key locations, this is an ordered set of locations— valid parts of the request where the keys might be found. The locations include the request header, body and query params.

For request body key:

```
request.body.<field-in-body>
```

For request header key:

```
request.header.<header-name>
```

For request query param key:

```
request.query.<query-param-name>
```

Using the key(s) you provide convoy will generate a SHA256 checksum, and use it to check for duplicates, this same key will be sent to your endpoint which can also be used to de-duplicate events. Any duplicate event will be marked as a duplicate and be discarded.

## Idempotency in Outgoing Projects

In outgoing projects you would need to specify an idempotency key in the request payload when creating the event. This works the same way when creating dynamic and fanout events. The idempotency key should be a unique value generated by the client. It is recommended to use the SHA256 of a UUID v4 string or any other sufficiently random string to ensure avoidance of collisions. We recommend a SHA256 string because the idempotency keys we generate for incoming projects are SHA256 strings.

```json theme={null}
{
	"endpoint_id": "01H3PECSZYDEES152G7DDBW7MP",
	"data": {
		"name": "{{$randomAdjective}}",
		"email": "{{$randomEmail}}",
		"age": 10
	},
	"idempotency_key": "12d851d0255ea37d2a0253016e62d35047ab4a737b5bcd75fb8fddff4b029249",
	"custom_headers": {
		"header": "valve"
	},
	"event_type": "read"
}
```

As expected if you send the same idempotency key in a request it would create the event but no event delivery will be sent.

### Overriding the outbound idempotency header

The `idempotency_key` field above is the **ingestion** key Convoy uses to de-duplicate events coming *into* the project. Convoy also reuses that same key as the default value of the `X-Convoy-Idempotency-Key` header it sends *out* to your endpoint, and you can override that outbound value independently.

When Convoy delivers a webhook it sets the `X-Convoy-Idempotency-Key` header on the outbound request so your receiver can de-duplicate on it. By default this is the event's own idempotency key; if the event has none, the header is omitted entirely. To override it, Convoy merges the event's `custom_headers` first and only fills in the default when you didn't supply an `X-Convoy-Idempotency-Key`, so your value wins. Set it in the event's `custom_headers` when you want your receiver to dedupe on a key you control:

```json theme={null}
{
	"endpoint_id": "01H3PECSZYDEES152G7DDBW7MP",
	"data": { "name": "{{$randomAdjective}}" },
	"custom_headers": {
		"X-Convoy-Idempotency-Key": "order-7f3a9c"
	},
	"event_type": "read"
}
```

If you don't send an override, Convoy falls back to its default value, and when there is no idempotency key at all the header is omitted entirely.
