Idempotency and recovery
Save an idempotency key with each intended API execution. If a response is lost, the same key and request identify the original work and allow a delivered result to be replayed.
On this page
Customer workspace calls to POST /v1/sources/{source_id}/run and /stream require the Idempotency-Key header. These rules describe those execution endpoints; builds, key creation, checkout, and other operations have their own contracts.
Save the request before sending#
Use a UUID or another unique string containing 1–200 letters, numbers, periods, underscores, colons, or hyphens. Save it in your job record together with:
- The workspace and source identifier.
- The full definition version.
- The execution endpoint:
/runor/stream. - The exact input values.
For the documentation examples, load this saved value into CLEANEDWEB_IDEMPOTENCY_KEY. Keep it stable across an interrupted attempt. Generating a new key every time a retry function runs creates new work.
Idempotency-Key: 72ad1b16-20ad-4ef4-a578-d8b893601d7e
This key is illustrative. Generate your own for a new execution. The connection details supplied by the console also include an example key. Fetching those details again creates a new example key, so retain the one you actually used.
What a key identifies#
Within an authenticated workspace, a key binds the source, resolved definition version, input, and execution surface. Object property order does not create a new identity. Changing a limit, adding an input, selecting another version, or switching from /run to /stream changes the request.
| Situation | Behavior |
|---|---|
| New key and valid request | Starts a new execution. |
| Same key and same request, result delivered | Returns the retained result and its delivery receipt without another collection or debit. |
| Same key, execution output saved but delivery unsettled | Attempts settlement of the saved output; source collection is not repeated. |
| Same key, request still running or recorded as failed | Returns 409 with result_already_running_or_failed; it does not restart the execution. |
| Same key with a changed request | Returns 409 with delivery_identity_conflict. |
| Missing or invalid key | Returns 422 with idempotency_key_required. |
An expected_version check still applies before replay. If the active definition has changed, a request can return a version conflict. Preserve the original identity and use recorded run details or support to resolve it; do not silently update the version on the saved request.
Recover a lost response#
- Keep the original key, source, version, endpoint, and inputs. A timeout does not tell you whether execution completed.
- If you retained
delivery.runId, readGET /v1/sources/{source_id}/runs/{run_id}/resultusing a credential withresultsaccess. This retrieves the existing delivery. - If the run identifier is unavailable, resubmit the same execution request with the original key. A delivered result is replayed; pending or failed work can return a conflict.
- Respect
Retry-Afterwhere supplied. Aresult_already_running_or_failedconflict does not distinguish a slow run from a failed one. Inspect the workspace's recorded run before deciding to wait, request help, or start a new execution. - Validate the recovered response's version, records, and summary as you would the initial response.
Use a bounded recovery policy and stop when the state remains uncertain. Do not generate replacement keys in a loop. A new key can execute the source again and create new usage.
Keep delivery evidence#
Store delivery.runId, delivery.chargeReceiptId, and delivery.recordCount with the request identity and output. The charge receipt identifies a delivered execution charge; it is separate from a credit-purchase receipt or invoice.
For review, provide the source identifier, definition version, run and trace identifiers, error code, and request timing. Never share API credentials. See errors and retries and Run an API.