Idempotency and retries
Send an Idempotency-Key header on every request and retries are safe. A repeat of a successful call returns the stored response instead of parsing again.
One key per document#
Any unique string; a UUID is fine. Generate it once for a document and reuse it for every attempt, including attempts after a timeout where you never saw a response.
What a repeat does#
| State of the first call | The repeat | Charged |
|---|---|---|
| Succeeded, within 24 hours | Returns the stored response with Idempotent-Replayed: true. | No |
| Failed with any status | Runs fresh. Failures are not stored against a key. | Only if this attempt succeeds |
| Succeeded, more than 24 hours ago | 409 idempotency_key_not_replayable, reason: "expired". | No |
| Succeeded, response too large to store | 409 idempotency_key_not_replayable, reason: "too_large". | No |
| Still in flight | Counts towards the four concurrent documents and may return 429. Retry shortly with the same key. | No |
Retrying#
While a document keeps failing, every attempt runs fresh and none of them cost anything. Retry 429 and 5xx with backoff.
The 409#
Stored responses are kept for 24 hours and then deleted. After that the same key returns 409 rather than parsing again, which would charge a second time for one call. The reason field says whether the response expired or was too large to store. Retry with a new key if you do want the document parsed again.
Response headers#
| Header | Meaning |
|---|---|
Idempotent-Replayed: true | The body came from storage. Nothing was parsed or charged. |
X-Billable-Documents | 1 when the call is on your invoice, 0 when it is not. A replay is always 0. |