Skip to main content
Public unsafe methods (POST / PUT / PATCH / DELETE) on the Alerts, Charts, Contracts, Segments, and Import APIs honour an optional 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 projectId as well as teamId, 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.
  1. Generate a fresh UUID v4 per logical operation. Don’t reuse keys across different actions, even if the body looks similar.
  2. 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.
  3. 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.
  4. Pair with retry-with-backoff for 429 / 503 / 5xx. Idempotency makes those safe to replay.
  5. Maximum length: 255 characters. Use a UUID v4 (36 chars) or any random ≤255-char string.

Examples

See Errors for the full list of error codes and remediation guidance.