---
title: "Idempotent requests"
---
The API supports idempotency so you can safely retry a write without performing the same operation twice. An idempotency key identifies repeated attempts of the same operation.

To make an idempotent request, generate an Idempotency-Key and include it in the request header. You can create keys however you prefer, but we recommend using UUIDv4 or another high-entropy random string to avoid collisions.

## When an idempotency key is required

All authenticated `POST` requests require an `Idempotency-Key` except the external-account verification endpoint and routes under `/v1/webhooks/*`. `GET`, `PUT`, `PATCH`, and `DELETE` requests do not currently require it.

Use a different key for each operation. Reuse a key only when retrying the same method, path, and payload:

```bash title="using idempotency keys in requests"
curl --request POST \
     --url https://api.gravv.xyz/v1/customers \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: 979879887678789_attempt_1' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "first_name": "john",
  "middle_name": "sample",
  "last_name": "doe",
  "email": "john.doe@example.com",
  "phone": "+15555550101",
  "type": "individual",
  "gender": "male",
  "date_of_birth": "2024-04-16",
  "external_id": "individual_12345",
  "address": {
    "address_line1": "1800 N Pole St",
    "address_line2": "Suite 202",
    "city": "Orlando",
    "postal_code": "32801",
    "state": "US-FL",
    "country": "US"
  }
}
'
```

## Retry behavior

Gravv stores the first non-server-error response for 24 hours:

| Situation | Result |
| :-- | :-- |
| Same key and identical payload after completion | The original response is replayed with `Idempotency-Replayed: true` |
| Same key while the original request is running | `409 Conflict` with `Retry-After: 1` |
| Same key with a different payload | `422 Unprocessable Entity` |
| Missing or invalid key | `400 Bad Request` |

When you receive `409`, wait for the number of seconds in `Retry-After` and retry with the same key and payload. Generate a new key when the operation or payload changes.

