Idempotency

Every POST /v1/validation requires an Idempotency-Key: 8–128 characters matching ^[A-Za-z0-9._:-]+$. Generate it once and save it with the request. Identity is scoped to the organization and credential, with the canonical validated request.

Same key, same request

Existing stateSame-key behavior
CompletedReturns the exact stored result: zero inference, zero inspection, zero additional VUs.
Active hybrid work with async acceptanceReuses the same execution and exposes active state.
Active work without async acceptance / direct workReturns 409; the in-progress response supplies Retry-After: 1.
Failed hybrid executionReplays the same sanitized terminal failure. GET also returns that stored failure.
Failed direct executionMay allow fresh ownership under the existing execution policy; this is not an automatic retry guarantee.

Same key with a different payload returns 409, with zero new work. Source metadata participates in canonical request identity; a JSON filename and transport preference do not.

Unknown outcome after transport failure

A lost connection does not prove execution failed. Preserve both request and key. If you have a validation_id, use GET retrieval. Otherwise, deliberately replay the same canonical request with the same key and credential to discover its state.

Do not blindly create a new key after an ambiguous failure: that could create and meter a second execution. A new key identifies genuinely new logical work.

Conflicts and failures

Distinguish a payload conflict from active execution. Respect Retry-After when supplied. If the API reports that a failed execution cannot be retried with that key, do not bypass it automatically; reconcile the recorded outcome before intentionally starting new work. Persistent unresolved state needs Support.

The API performs no automatic semantic retry or fallback. The cURL, Python, and TypeScript examples make one request per invocation. See Errors, Async Execution, and Usage and Limits.

Coordinated supplied/acquisition migration

Keep the original request and key for historical completed replay. Fresh text-plus-URL requests evaluate that text after cutover; only explicit acquire requests acquisition. Changing an old body to acquire with its original key is a 409 conflict. Historical failed direct requests cannot restart under new semantics; review intent and use a fresh key after reconciliation. During an admission pause, fresh work and failed-direct retries return 503 with Retry-After. Do not automatically retry unknown-outcome old queues across the cutover. GET and stored replay remain available and add zero VUs.