Skip to main content

Idempotency

Every POST request to the Journeybee API must include a unique Idempotency-Key header. The SDK also sends one for PUT, PATCH, and DELETE; raw non-POST clients remain compatible without a header unless they explicitly opt in. Journeybee uses Redis as a 24-hour replay authority. Within that window, a retry of the same logical request receives the recorded terminal response. It reduces ambiguity after a lost response, but it is not a database transaction and cannot promise no duplicate outside the replay window or across a crash boundary.

Quick start

Generate a UUID per logical operation and send it with your request:
If the network times out, retry with the same key and exact request. Within the replay window, Journeybee returns the recorded response instead of running the handler again.

Rules

Fastify validates request schemas before idempotency acquisition, and live authorization guards run before a cached response can be replayed. A schema validation or authorization failure is therefore not cached and does not consume the key: after correcting the request or restoring access, retry with the same key. Only responses produced after idempotency acquisition, including terminal handler 4xx, 429, and 5xx responses, are recorded.

Key format

  • 1–255 characters
  • Alphanumeric, underscore, hyphen ([A-Za-z0-9_-])
  • UUIDs recommended — they’re collision-free and easy to generate
  • A key is scoped by company, stable actor fingerprint, canonical operation, and logical ID, so the same logical ID can be used for different operations
The canonical request includes the HTTP method, OpenAPI operation identity, path parameters, normalized query parameters, and canonical JSON body. Object key order does not change the request identity.

Retention

Each terminal response is retained in Redis for 24 hours. After that, the same logical ID is no longer protected by this replay authority and may run again.

What to use as a key

Pick a value that uniquely identifies the logical operation the client intends, not the physical HTTP request:
  • crm-lead-7841-sync — one key per lead you’re syncing.
  • ✅ A UUID generated when the user clicked “Save”.
  • Date.now() — changes on every retry, defeats deduplication.
  • ❌ A constant string — every request collides.

Client examples

Node.js

Python

Mutation methods

POST always requires Idempotency-Key. Headerless PUT, PATCH, and DELETE requests retain their legacy behaviour. Supplying a valid header on those methods enables the same replay protection, and the Journeybee SDK does this automatically for all mutation methods without overwriting an explicit key.

Reliability boundary

Idempotency is a Redis replay protocol, not an atomic transaction with the business database. It cannot guarantee that a mutation was never applied if the 24-hour window expires or a failure occurs at the database/Redis crash boundary. Preserve the logical ID for a lost-response retry; use a new logical ID only when intentionally starting a new operation.