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

# Idempotency and ETags

> Safe retries on creates, and optimistic concurrency on updates.

Two different problems, two different mechanisms. `Idempotency-Key` makes a **retry** safe. `If-Match` makes a **concurrent update** safe.

## Idempotency-Key

Required on shipment creation and cancellation.

```bash theme={null}
-H "Idempotency-Key: merchant-order-20260822-0001"
```

<Info>
  **Contract note.** The key is **16–128 characters**. Some older material describes a 1–128 range; the OpenAPI contract published here is authoritative, and a key shorter than 16 characters is rejected.
</Info>

### Scope

A key is scoped by the **operation**, the **merchant company**, and the **OAuth client**. The same key used for a different operation is a different key — you do not need to keep keys globally unique across your whole system, only unique per intent.

### Replay semantics

| Situation                   | Result                                                              |
| --------------------------- | ------------------------------------------------------------------- |
| Same key, same payload      | The original result is returned — `200` rather than `201` on create |
| Same key, different payload | Rejected with `409`                                                 |
| New key, same payload       | A new request. A second shipment is created.                        |

<Warning>
  Reusing a key with a changed payload is a conflict, not an update. If you genuinely want to create a different shipment, use a different key.
</Warning>

### Choosing a key

Derive it from the business intent that must happen at most once — your order identifier plus the operation, for example. Do not generate a fresh random key on each retry: that is precisely the case idempotency exists to prevent.

```bash theme={null}
IDEMPOTENCY_KEY="create-shipment-$ORDER_ID"
```

## ETags and If-Match

Mutable resources carry a **strong numeric entity tag**, matching `^"[0-9]+"$` — quotes included. It is the resource's `version` in ETag form.

Conditional requests are required for:

* revoking an API credential and rotating its secret
* updating, deleting, or rotating the secret of a webhook endpoint
* revoking a tracking link

```bash theme={null}
curl -X PATCH "$BASE_URL/v2/external/webhook-endpoints/$ENDPOINT_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "If-Match: \"7\"" \
  -H 'Content-Type: application/json' \
  -d '{"status":"PAUSED"}'
```

### The two failure modes

| Status                      | Meaning                                      | What to do                                  |
| --------------------------- | -------------------------------------------- | ------------------------------------------- |
| `428 Precondition Required` | You sent no `If-Match`                       | Read the resource, then retry with its ETag |
| `412 Precondition Failed`   | Your ETag is stale — someone else changed it | Re-read, reconcile, retry                   |

<Tip>
  Never work around a `412` by fetching the current ETag and immediately resubmitting the same change. That defeats the check. Re-read, decide whether your change still makes sense against the new state, and only then retry.
</Tip>

### Reading the current tag

The ETag comes back on the representation you read, and on the response to a successful state-changing request — so a sequence of updates can use each response's tag for the next call without an extra `GET`.
