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.
- 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 a5xxcan send the customer a duplicate.
Writes that create something
Four endpoints accept an optionalIdempotency-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:
- 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 — a5xx 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
409carrying the existingappointment_id. - Create Profile returns
409whenemailalready has a profile. Omitemailand a unique placeholder is generated per request, so repeats do create separate profiles.
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.