Skip to main content
Networks fail after a request is sent and before its response arrives. An Idempotency-Key lets you retry a supported mutation without creating a second check or generation. The sandbox’s POST replay and the initial live check/generation custody are described below. Live verification currently returns a fresh verification ID on each call and does not provide exact response replay; broader planned POST operations do not have a live implementation.

Send a key

Every POST accepts Idempotency-Key, up to 255 characters. Initial live check and generation creation require a nonempty key. Use a random UUID, created once for each operation and stored with its exact request body before the first attempt: This sandbox example uses Bash, cURL and Node.js. Export your own REFLECTIONS_KEY as shown in the quickstart. Save the following block as idempotency.sh in an empty directory, then run bash idempotency.sh. Retry the script from that same directory to reuse the saved key and body; use a new directory for a new request.
Sandbox keys are kept for 24 hours and scoped to your account and mode. Each key is bound to a digest of the endpoint and request body. The broader delegated-account contract additionally scopes keys to the licensee, but delegated Reflections-Account requests remain unsupported. Live check and generation creation each keep a separate account-scoped retry record for 24 hours from creation, bound to the same caller key and full body. Use a distinct idempotency key for each operation even though these two live endpoints have separate namespaces.

Sandbox replay outcomes

Live check and generation replay

Within the same live creation operation, the same body and key replay the admitted object; a different body with that key returns 422 idempotency_key_reused. Keep using the same API key. A pending check returns 202 with status: "checking" and decision: null; retry with the same body and key after Retry-After. A pending check is not an error. A completed check replay returns the same sealed response, including its decision and authorization; it does not use another generation from max_generations. Read the check’s GET endpoint for current authorization consumption or expiry. In the initial live image implementation, generation creation seals an accepted 202 response. Every successful POST replay returns that same response even after evaluation or release. Use GET /v1/generations/{generation_id} for its current state and final receipt. A POST replay does not rerun the evaluator, submit another candidate or release the output. Retry 429, 500, 503, 409 idempotency_key_in_use and a 202 check that is still checking with the same body and key after Retry-After. These transient responses are not final outcomes. A retry resumes or reconciles the same logical operation; it never authorizes another paid evaluation start. Unknown provider spend is not automatically retried or refunded.

Retry with the same key

When you do not know whether a request succeeded (a timeout, a dropped connection, a 500 or a 503), retry with the same body and key. Never generate a new key for a retry: a new key is a new request.
If the retries run out, treat the outcome as unknown. For a check, do not generate. For a generation, do not deliver, and retry later with the same key. A later retry within 24 hours still returns the original result if the first attempt completed. If the 24-hour retry window has elapsed while the outcome is still unknown, reconcile the existing operation before submitting anything new. Expiry does not prove that no work occurred.

Keys across calls

Use one key per operation, not per call site. A check and the generation that follows it are two operations with two keys. In the planned usage-record contract, a batch is one operation: keep the same key and the same records when you retry it. That contract also rejects duplicate usage records with duplicate; live usage submission remains unsupported.

Errors

Which codes are safe to retry.

Caching and outages

What to do when Reflections cannot be reached.