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

# Rate limits and idempotency

> Stay under 20 requests per second and retry safely.

Each API key may make 20 requests per second. Above that the API answers `429` with a `Retry-After` header in seconds and `RateLimit` headers that show your remaining budget. The SDKs wait and retry for you.

## Headers

| Header | Meaning |
| - | - |
| `Retry-After` | On a `429`, the number of seconds to wait before the next request |
| `RateLimit-Limit` | Requests allowed per second for this key (20) |
| `RateLimit-Remaining` | Requests left in the current window |
| `RateLimit-Reset` | Seconds until the window resets |

Spread bursts out instead of firing them at once. For a batch of documents, send jobs at a steady pace, or limit yourself to a few requests in flight.

## Idempotency-Key

A network error leaves you unsure whether `POST /v1/printjobs` created a job. If you retry blindly you might print twice. Send an `Idempotency-Key` header to make the retry safe:

```bash theme={null}
curl https://api.inkrelay.app/v1/printjobs -H "Authorization: Bearer $INKRELAY_API_KEY" -H "Idempotency-Key: order-1042-label" -H "Content-Type: application/json" -d @job.json
```

* The key is any unique string of up to 255 characters. Use something that names the thing you are printing, such as `order-1042-label`, or a random UUID you store with your own record.
* Keys are kept for 24 hours per organization.
* The same key with the same body returns the original job, with the header `Idempotent-Replayed: true`, and creates nothing new.
* The same key with a different body is refused with `422 idempotency_key_reused`. Use a new key for a different job.
* A request that arrives while the first one with the same key is still being processed answers `409 idempotency_in_progress`. Wait a moment and retry with the same key.
* A key longer than 255 characters answers `400 invalid_request`, because the header is validated before the request is processed.
* If the first request fails (a `4xx` or `5xx` response), the key is released and the retry runs normally.

## Retrying safely

Retry on `429`, on `5xx` responses and on network errors, waiting longer each time (exponential backoff with some randomness), and honour `Retry-After` when it is present. Do not retry other `4xx` responses, because the same request will fail again.

Always send the same `Idempotency-Key` on every retry of one job. The SDKs do this for you: they set a key automatically on `printJobs.create` (`print_jobs.create` in Python) and reuse it on every retry, so a retried request never prints twice.


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