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: A repeat writes nothing, and its response carries Idempotent-Replayed: true — that header is how you tell “I cancelled it” from “it was already cancelled”. Three 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 an already-cancelled appointment with a different cancellation_reason. Same reasoning: the recorded reason may since have been corrected, and a retry must not overwrite it. Re-send the recorded reason, or omit it.
  • Cancelling after the point of no return — a confirmed blood draw, a collected shipment, a dispatched or activated kit.
Three endpoints are deliberately not retry-safe:
  • Confirm Blood Draw — a second call returns 409.
  • Email Results (POST /v1/appointments/{id}/results/email) and Email Results (POST /v1/home-kit-orders/{id}/results/email) — each call sends one email. A retry after a timeout or a 5xx can send the customer a duplicate.

Writes that create something

Four endpoints accept an optional Idempotency-Key header, at most 255 characters: One key, four attempts, one order — what you get back depends on when you retry and whether the body matches: Sequence diagram: a duplicate fired 350 ms after the first request is answered 409 while that request is still running, the first returns 201, a later retry with the same key returns the same order marked Idempotent-Replayed, and the same key with a changed body returns 409. Sequence diagram: a duplicate fired 350 ms after the first request is answered 409 while that request is still running, the first returns 201, a later retry with the same key returns the same order marked Idempotent-Replayed, and the same key with a changed body returns 409. 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 body → 409.
  • An empty Idempotency-Key → 400, 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.