Idempotency

Retry mutating requests safely, without double-applying them.

Send an Idempotency-Key header on any POST/PATCH/PUT/DELETE call made with an API key. The first request with a given key runs normally and its response is cached for 24 hours; retries that reuse the key replay that response instead of re-running the operation.

$curl -X POST https://api.spreadspace.app/api/async-operations/extraction_export \
> -H "Authorization: Bearer ss_live_..." \
> -H "Content-Type: application/json" \
> -H "Idempotency-Key: 3f7c31c9-3a06-4a5f-9f6b-8d34ef9f2b41" \
> -d '{}'

The header is optional: omit it and every request is processed fresh.

Keys

  • Up to 255 characters. Generate a UUID per logical operation.
  • Scoped per API key: two credentials never share a cache entry.
  • Read calls (GET) ignore the header: they are already idempotent. Endpoints that don’t support it don’t list it on their reference page.

Replays

A replayed response is byte-for-byte the original, with one addition: the Idempotency-Replay: true response header marks it as a replay.

Client errors (4xx) are cached and replayed too, so retrying a failed validation returns the same error rather than re-running it. Server errors (5xx) are never cached: the key is released and a retry re-executes the operation.

Request fingerprint

The request body is fingerprinted alongside the key. Reusing a key with a different body returns 409 idempotency_request_mismatch: a key names one logical operation, not a slot to overwrite.

Concurrent retries

If a duplicate arrives while the original is still executing, it waits for the original to finish (up to 30 seconds) and replays its response. If the original is still running past that window, the duplicate returns 429 idempotency_in_progress with a Retry-After header: retry after the indicated pause.

Limits

Responses larger than 1 MiB can’t be cached. The request fails with 500 idempotency_response_too_large, the key is released, and a retry re-executes.

SDKs

The official SDKs send a generated idempotency key on every non-GET call automatically, so their built-in retries never double-apply an operation.