# Handle idempotency and rate limits

> Give each intended write a stable key, replay safely after uncertainty, and back off from explicit limits.

Canonical: https://entirefeed.com/docs/operate/idempotency-and-rate-limits

Network uncertainty must not create duplicate paid work. Send an `Idempotency-Key` on generation create and retry requests, even though discovery, estimation, and reads do not need one.

## A key identifies one intent

Generate a unique, non-secret string for one logical create or retry. Reuse it when repeating that same request after a timeout or lost response. Do not rotate it merely because the response was uncertain.

Reusing the key with the same intent returns the existing generation. Reusing it for a different body returns `409 idempotency_conflict`. A retry key identifies the retry itself, not the original create.

## Back off from limits

Limits apply to authenticated request volume, generation creation frequency, and concurrent active generations. A rejected request returns `429 rate_limit_exceeded`. Do not fan out immediate retries; reduce concurrency and use bounded exponential backoff.

## Use one key for one write intent

- A key names one create or retry intent. It is not a secret.
- Reuse the same key after a timeout with the same intended request.
- Use a new key for new work; changing a request while reusing a key returns `idempotency_conflict`.

## Respond to explicit limits

- 60 authenticated requests per 60 seconds per API key.
- 10 generation creates or retries per 60 seconds per API key.
- 10 upload authorizations per 60 seconds per API key or MCP organization.
- 1 active upload per organization, with 2 active uploads across the service.
- 5 concurrent queued or running generations per organization.

A `429 rate_limit_exceeded` response means a limit was reached. Reduce concurrency and use bounded exponential backoff. Keep the original idempotency key when replaying the same write intent.
