Skip to main content

Writes that change an existing resource

No header is involved. Where a repeat used to return an error, it now returns the current state: Two exceptions return 409 instead:
  • Activating with a different activated_at. The collection time is what the lab report carries, so a retry must not silently overwrite it.
  • Cancelling after the point of no return — a confirmed blood draw, a collected shipment, an activated kit.
Confirm Blood Draw is the one endpoint deliberately not retry-safe: a second call returns 409.

Writes that create something

Four endpoints accept an optional Idempotency-Key header, at most 255 characters: Keys are scoped to your API key and to the endpoint, so they never collide with another partner’s or with the same key used elsewhere.
  • Same key, same body → for 24 hours you get the original response back, marked Idempotent-Replayed: true. Field order and whitespace don’t matter.
  • Same key, different body409.
  • An empty Idempotency-Key400, rather than being ignored.

When the key is released

Creation is not atomic — a 5xx does not mean nothing was written.
  • The request failed before anything was created → the key is released, so you can retry under it.
  • The request failed after something was created, or never returned at all → the key stays claimed and retries get 409. Fetch the resource to check whether it exists, then use a fresh key if it doesn’t.
A replay returns the response body recorded when the resource was created — a snapshot, not a live read. If the resource has changed since, fetch it directly.

Some creates also have a natural key

Two endpoints reject duplicates on their own, independently of any header:
  • Create Appointment allows one appointment per profile, location and instant. A repeat returns 409 carrying the existing appointment_id.
  • Create Profile returns 409 when email already has a profile. Omit email and a unique placeholder is generated per request, so repeats do create separate profiles.
When both apply, the natural-key 409 is what you see, and only it carries the extra field (appointment_id, or an errorName discriminator) — an idempotency 409 carries error alone, so read those fields defensively.