# Retries and Idempotency-Key

A request can fail on the way: a timeout, a dropped connection. Send an `Idempotency-Key` with it, and trying again is safe: you get the same screenshot, charged once.

## Send an Idempotency-Key

Choose a value that is unique for each screenshot you want, and send it in the `Idempotency-Key` header.

**A request you can repeat**

```bash
curl -X POST "https://api.localscreenshot.com/v1/screenshot" \
  -H "Authorization: Bearer $LOCALSCREENSHOT_API_KEY" \
  -H "Idempotency-Key: order-2026-10-08-001" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.wikipedia.org",
    "full_page": true
  }'
```

- 8 to 128 characters: letters, digits, dashes, underscores, dots and colons.
- A random id works well, or an id from your own system, such as an order number.
- Keys belong to your account. Another account using the same value gets its own screenshot.

## What the same key does

| You send | You get |
| --- | --- |
| A key for the first time | A new screenshot. |
| The same key, the same options | The same screenshot again. Nothing new is charged. |
| The same key, different options | The error `idempotency_conflict`, with status 409. |
| The same key while the first request is still running | The same screenshot, in the state it has reached. |

`response` and `async` describe the answer, not the screenshot: you can change them between two tries with the same key.

A key is remembered as long as its screenshot is kept, which is 7 days. Deleting a screenshot frees its key at once.

## When to retry

Look at `retryable` in the error. See [Errors](https://docs.localscreenshot.com/errors) for every code.

- `retryable` is `true`: try again as is. Wait for the `Retry-After` header when there is one.
- `retryable` is `false`: the same request would fail the same way. Change it first.
- No answer at all (your own timeout, a lost connection): try again with the same `Idempotency-Key`. If the first request did go through, you get its screenshot.

**429, wait and retry**

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 12
```

## A good retry loop

1. Send the request with an `Idempotency-Key`.
2. On an error with `retryable: true`, wait. Use `Retry-After` if it is there, otherwise 2 seconds, then 4, then 8.
3. Send the same request with the same key.
4. Stop after 3 or 4 tries and report the error.

The number of failed screenshots per day is limited: 15 on free credits, 300 after a first payment. A loop that never stops would use it up, and you would get `failure_budget_exceeded` until the next day.

## A screenshot that takes a long time

A request waits up to 50 seconds. If the screenshot is still running then, you get `202` and its id: this is not an error, and there is nothing to send again. Read the screenshot until it is done. See [Run in the background](https://docs.localscreenshot.com/async).
