Idempotency-Key header. When present, Formo de-duplicates retries so a flaky network or a crashed client never causes a double-write.
The header is opt-in - omit it and every request is processed independently.
How it works
- The first request runs normally; the response (status code + body) is cached for 24 hours under
idem:{teamId}:{projectId}:{key}along with a fingerprint of the request (method + full mount path + body). - Subsequent requests with the same key and matching fingerprint replay the cached response byte-for-byte - retries can never double-create or double-charge.
- The cache is scoped to
projectIdas well asteamId, so two project-scoped API keys in the same workspace can use the same key without colliding.
What gets cached
The in-flight lock is also released on
4xx so a corrected retry under the same key can proceed immediately.
Failure modes
400 INVALID_IDEMPOTENCY_KEY - key reused for a different request
Reusing the same key for a different operation (different method, path, or body) returns 400 INVALID_IDEMPOTENCY_KEY. This prevents silent dropped writes when a client accidentally reuses a key across distinct requests.
Also returned if the key exceeds 255 characters.
409 IDEMPOTENCY_IN_PROGRESS - concurrent retry
Two concurrent requests with the same key in flight return 409 IDEMPOTENCY_IN_PROGRESS. Wait briefly (typically under 1 second) and replay - the server will return the cached response of the original request.
Cache outage
If the idempotency cache is unavailable, the request runs without caching - a cache outage doesn’t block writes. Concurrent retries during such an outage may double-execute; the contract is best-effort.Recommended client patterns
- Generate a fresh UUID v4 per logical operation. Don’t reuse keys across different actions, even if the body looks similar.
- Persist the key before the first attempt. Save it to disk / DB before calling the API so an in-flight crash doesn’t lose it. On restart, retry with the same key.
- Scope to a single workspace. Two API keys for different projects can safely share an idempotency key - but don’t rely on that; scope per workspace anyway.
- Pair with retry-with-backoff for
429/503/5xx. Idempotency makes those safe to replay. - Maximum length: 255 characters. Use a UUID v4 (36 chars) or any random ≤255-char string.