Sign in to run requests with your own sandbox key. Sign in

Concepts

Idempotency

Which endpoints require an Idempotency-Key, how the key is scoped, what happens on replay and on conflict, and how to choose good keys.

A screening run pulls reports and may bill. A retried request must therefore never start a second run. Every endpoint that creates a run requires an Idempotency-Key header and uses it to return the original result on replay.

Which endpoints require a key?

Endpoint Key scope
POST /workflows/{id}/trigger Per API client (the key is stored as execution_key = api_client:<client id>:<your key>)
POST /workflows/{id}/batches Per API client, compared against a SHA-256 of the rows JSON
POST /executions/{id}/re_evaluations Per source execution (reeval:<execution id>:<your key>)

Omitting the header returns 422 missing_idempotency_key. The header value is limited to 200 characters (the trigger namespace prefix consumes some of the stored key, so keep values comfortably shorter).

What happens on replay?

  • Same key, same body → the original response, again: 202 Accepted with the same execution or batch. Nothing new is created.
  • Same key, different body → 409 idempotency_conflict. The stored request is not overwritten. A trigger answers with the message below; a batch says "…with a different request." instead.
  • Concurrent identical requests are race-safe: both callers receive the same execution; the loser of the insert race re-reads the winner's row.
JSON
{
  "error": {
    "code": "idempotency_conflict",
    "message": "The Idempotency-Key has already been used with a different request payload.",
    "details": [],
    "request_id": "7d4c2f48-…",
    "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/idempotency_conflict"
  }
}

How do I choose a key?

Derive it from the upstream business event, not from the attempt: an application id, an order id, a submission id. Then a retry from a timeout, a crashed worker or a redeploy naturally carries the same key. Never reuse a key across distinct events, and never generate a fresh UUID per attempt — that defeats the protection entirely.

HTTP
Idempotency-Key: rv-app-20491        # good: the application id
Idempotency-Key: 3fa85f64-…          # fine, if you persist it before the first attempt
Idempotency-Key: $(uuidgen)          # bad: every retry is a new run

The same discipline applies to external_reference: it is not an idempotency key (two triggers with the same reference create two runs), but it is what you correlate results and webhooks back to.

Was this page helpful?