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

# Idempotent requests

> Best practices on handling retries in an idempotent way.

The API supports idempotent requests allowing the safe retrying of
requests without accidentally performing the same operation again. When making an
idempotent request, if an error occurs in the request to the API (such as
a timeout or loss of connection), the request can be safely retried without the
risk of creating a second resource or performing the update twice.

Idempotency works by storing the status code and body of the first
response for a given idempotency key, regardless of whether the request
succeeded or failed. Subsequent requests with the same idempotency key return
the same response.

An idempotency key is a unique key generated that the API uses to
identify subsequent retries of the same request. It is recommended to use V4 UUIDs,
or another random string with enough entropy to avoid collisions. Idempotency
keys can be up to 255 characters long, and remain valid for 24 hours, after
which the idempotency key may be reused for another request.

The response of an idempotent request is only saved if the API started
executing. If the request fails validation or the request conflicts with
another that was performed concurrently, no response is saved. It is safe to
retry these requests.

## Supported endpoints

The following endpoints support idempotent requests.

* `POST /transactions`
* `POST /transactions/:id/capture`
* `POST /transactions/:id/authorization/increment`
* `POST /transactions/:id/void`
* `POST /transactions/:id/refunds`
* `POST /transactions/:id/refunds/all`

The `POST /gift-cards/activations` and `POST /gift-cards/issuances` endpoints also accept an
`Idempotency-Key` header. For these endpoints, the key is forwarded to the gift card service,
which makes the request idempotent if the service supports it. Gr4vy doesn't store the response.

## Making an idempotent request

To make an idempotent request, specify the `Idempotency-Key` header in the
request.

```bash theme={"system"}
curl -i -X POST "https://api.example.gr4vy.app/transactions" \
    -H "Authorization: Bearer [JWT]" \
    -H "Idempotency-Key: bffa9ce6-7a8a-449c-889a-65bd2ee86903" \
    -d "{...}"
```

<Note>
  Most of [the SDKs](./authentication) support passing through this header on
  the API call.
</Note>

## Concurrent requests

When making an idempotent request using the same `Idempotency-Key` as a previous
request, and the original request is still being processed, an
error is received. This request can be safely retried. It is recommended to apply an exponential
back-off when retrying transactions.

```json theme={"system"}
{
  "type": "error",
  "code": "concurrent_request",
  "status": 409,
  "message": "A request with this idempotency key is still being processed. Retry later.",
  "details": []
}
```

## Retrying after a timeout

A request that takes too long can end with a `504` response, even though the operation continues
and can still complete. Don't retry such a request straight away. Wait for the
[webhook](/guides/features/webhooks/overview), or look up the result, for example by searching
transactions by `external_identifier`, before you retry with the same `Idempotency-Key` and an
exponential back-off. See [handling timeouts](/guides/timeouts) for more strategies.

## Conflicting requests

When making an idempotent request using the same `Idempotency-Key` as a previous
request, and the request is not the same (for example, the request body is
different), an error is received. Retrying this request will not change the
error response. The request should be checked.

```json theme={"system"}
{
  "type": "error",
  "code": "bad_request",
  "status": 400,
  "message": "Idempotency key already in use.",
  "details": []
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.