Skip to main content
A home kit order sends a DIY mail-home test kit to a patient. Aniva ships the kit, the patient self-collects a sample at home and mails it back. This is distinct from an appointment, which is a venous draw performed at a physical test location by a healthcare professional.
Home kit order endpoints require the home_kit_orders_view (read) or home_kit_orders_manage (write) scope. Activate also accepts the narrower home_kit_orders_activate scope. Get Results and Email Results additionally require results_view — lab results and documents are always gated by it.

Fields

string
required
UUID auto-generated by Aniva. Use this to update the order, swap its panel, activate it, cancel it, and retrieve results.
string
required
The UUID of the profile this home kit order belongs to.
string
required
Current lifecycle status. One of pending, dispatched, activated, or cancelled. See Lifecycle below. Lab-result completion granularity (in_progress vs completed) is derived from Get Results.
object
required
The address to mail the kit to — one of two shapes: either {location_id} referencing a known test location, or the inline address fields (name, street, city, postal_code, country_code; company_name / house_number / address_line_2 / state / phone / email optional — the same vocabulary as the locations API). Provide exactly one — a location reference or an inline address, not both.
Packstation or Postfiliale (Germany only): set street to Packstation or Postfiliale, house_number to the three-digit station number, and address_line_2 to the recipient’s DHL Postnummer (6–10 digits, spaces allowed). Without the Postnummer, the parcel cannot be booked. A Postfach is not supported.
string
required
ISO 8601 timestamp of when the home kit order was created.
string
ISO 8601 timestamp of the most recent update. Null if the home kit order has never been updated.
object
The full profile object for the patient, embedded in every home kit order response.
object[]
The panel attached to the home kit order — always exactly one entry of { panel_id, added_at }, because a home kit maps 1:1 onto a physical kit product. Cross-reference the panel_id against List Panels.
object[]
Biomarkers attached to the home kit order outside its panel. Each entry is { biomarker_id, added_at }. Cross-reference each biomarker_id against List Biomarkers with home_kit=true. On a normal order these are à-la-carte tests on top of the panel; on a replacement kit they are what the laboratory re-runs.
string
The home kit order this one replaces, when it is a replacement kit. null on a normal order.
string
Why the replacement was sent, in one sentence. null on a normal order.
string[]
Addresses that each get one email once every lab result is final, lowercased. Always present — empty when off. Set it on Create or Update. See Results-ready emails.
object
Your own key/value pairs, echoed back verbatim and never interpreted by Aniva. Always present on a read — {} when you set none. At most 20 keys; keys match [A-Za-z0-9_-] and are at most 40 characters; values are a string, number, or boolean, with strings at most 500 characters; 16384 bytes serialized overall. Keys beginning aniva_ are reserved. On Update, metadata is merged: keys you omit survive, a key sent as null is deleted, and {} clears everything. Validation is all-or-nothing. Never put personal or clinical data in metadata — it is not treated as patient data.
string
The laboratory sample code. One code, three roles: what lab results report under, what is printed on the physical kit, and what the patient reads off the box as the activation code. Allocated when the kit is packed — null while the order is pending, except after Aniva re-ships a kit (see Lifecycle). Read-only always. Resolve a kit in hand back to its order with GET /api/v1/home-kit-orders?lab_code=….
string
The collection timestamp reported via Activate — when the patient actually collected their sample, as a UTC instant. null until the kit is activated. This is the collection time the lab report carries.
object[]
The parcels linked to this order, oldest-link first, each { id, added_at } — the kit on its way to the patient and, for kits whose return leg is tracked, the sample on its way back to the laboratory, appearing the moment the labels are printed. Empty while the order is pending, except after Aniva re-ships a kit. Read the full parcels in one call with GET /api/v1/shipments?home_kit_order_id={id} — see Shipments.

Lifecycle

Home kit orders expose four lifecycle states:
When Aniva re-ships a lost kit, the order goes back to pending but keeps its lab_code and its earlier parcels in shipments. The new kit carries the same code. An unused return label goes into the new box. Only Aniva makes these two moves; the API does not offer them. Each move sends a home_kit_order.pending or home_kit_order.cancelled webhook.
The home kit order status surface is intentionally coarse. Delivery progression to and from the patient is tracked on the order’s shipments — dispatched means the kit has a label and a lab code, not that it has moved; the outbound shipment’s status says whether it has. Lab result processing lives on submissions. Lab-result completion (in_progress vs completed) is exposed via Get Results — the top-level status field is in_progress until every submission closes, then completed — or fault when every submission died without reporting.

Tracking the parcels

What comes back depends on the kit. A blood kit arrives as two shipments once Aniva has packed it: the parcel from Aniva to the patient, and the one from the patient to the laboratory (its destination is the lab), paired through paired_with. The return parcel sits pending — with its tracking number already known — until the patient posts it. A gut-microbiome kit arrives as one shipment: the kit to the patient. Its return envelope is prepaid and untracked, so nothing is booked for the way back. booked_by says who booked the label: "aniva" or "external". Only an "aniva" parcel can be changed here, and only its notes once the label is printed. Each parcel carries the carrier’s full status_updates, including DHL’s detail_code for a redirect to a post office. home_kit_orders on the shipment lists only the orders in your access context. See Access.
A home kit order’s composition can only be changed while it is pending. Once the order is dispatched (or later — activated/cancelled), panel swaps and the /biomarkers endpoints return 409 Conflict: the physical kit is packed from the selected panel, so its contents are frozen the moment it leaves for the patient. If you do need to change the tests on an order that’s already locked, reach out to Aniva directly — it’s usually still possible, and we’ll make the change for you to keep the kit’s contents consistent. If the kit has already been used and could not deliver its results, order a replacement kit instead.

Listing home kit orders

Retrieve all home kit orders accessible to your API key:
Optionally pass ?profile_id={uuid} to filter by a specific profile, or ?lab_code={code} to resolve a physical kit in hand back to its order — the natural first step of an activation flow.

Creating a home kit order

Request a home kit order for a patient profile:
Pass the profile_id, a delivery_address, and a single panel_id. The order is created in pending status. Pass an optional Idempotency-Key header so a retry does not order a second kit — see Idempotency. Exactly one panel, because a home kit maps 1:1 onto a physical kit product — the panel is the kit. Only panels Aniva has configured as home kits are orderable; any other panel is rejected with 422. It is required at creation because the order joins the packing queue immediately and packing can start straight away. While the order is pending you can swap the panel via Update. To send a second kit for one that could not deliver its results, pass replaces_home_kit_order_id instead of choosing a panel — see Replacement kits.

Replacement kits

Sometimes a kit cannot deliver its results: the patient could not fill the tube, the sample arrived with too little material, the laboratory could not analyse part of it. Order a replacement for it:
A replacement is a new order with a new lab code, also when the first kit was never activated: the laboratory needs a new requisition, and two samples under one code cannot be told apart. Both orders stay readable, linked through replaces_home_kit_order_id. The order you replace is not touched. It keeps its status, its lab code and any results already filed under it, so a patient who still posts the first kit gets whatever the laboratory can read from it. The panel is inherited. Leave panel_id out and the replacement carries the panel of the order it replaces — that is what the patient bought and how the box is branded. Send a different panel only for a whole-panel replacement; a panel and a marker subset together are rejected with 422, because a subset only means what it says under the panel it was picked from. The panel of a replacement cannot be swapped afterwards either. You choose what is re-run. Send biomarker_ids with the markers that failed and the laboratory re-runs only those, so the kit ships only the tubes they need. Leave it out to re-run the whole panel — the right choice when nothing was analysed at all. This needs no extra scope: re-running markers the patient already paid for is not an à-la-carte selection. Those markers cannot be removed afterwards, because they are the whole requisition.
Markers are re-run as the panel’s groups, not one by one. Naming one marker of a group re-runs that whole group, because a laboratory order that reports more than was asked for cannot be placed. A replacement for a single marker can therefore come back with more than one result, and its tube count can be larger than the marker list suggests.
Only one replacement per kit may be on its way at a time — while a replacement is pending or dispatched, a second create for the same order returns 409 naming it. Results arrive under the replacement’s own lab_code, through its own Get Results. A replacement is not how you handle a parcel that never arrived. Tell Aniva instead: that is a re-ship of the same order under the same lab code, not a new one.

Updating a home kit order

Change the delivery address, swap the panel, update your metadata, or replace the results-ready emails:
Only include the fields you want to change. panel_id replaces the attached panel — with exactly one panel per kit, a swap is the only meaningful panel operation, which is why there are no add/remove panel endpoints. The address and the panel are mutable only while pending; metadata stays writable for the whole life of the order. results_ready_emails stays writable until the order is cancelled.

Cancelling a home kit order

Cancel a home kit order that is no longer needed:
This sets the home kit order status to cancelled. The cancelled home kit order is returned in the response. Only a pending order can be cancelled. From dispatched onwards the kit has been packed and labelled — there is no automated recall — and the call returns 409. If a kit that has already shipped needs to be stopped, reach out to Aniva directly. Cancelling a pending order whose kit has already been ordered from fulfilment cancels it there too, and the call succeeds only if fulfilment accepts:
  • 409 — the kit was already packed and labelled, so it can no longer be called back, even though the order still reads pending.
  • 502 — fulfilment refused the cancellation (the error carries their reason), or could not be reached. Nothing was changed — the order is still live and can be cancelled again.
A cancel that returns an error leaves the order exactly as it was, so a 200 is the only confirmation that no kit is coming. Cancelling an order that is already cancelled returns the same 200, whatever status it was cancelled from.

Activating a home kit order

When the patient has collected their sample, report it:
Pass activated_at — the moment the patient actually collected the sample, as a UTC instant. This is the collection time the lab report will carry, so send the real collection moment, not your processing time. Activation is terminal: the order moves to activated and can no longer be cancelled or changed. The home-kit counterpart of Confirm Blood Draw, without a barcode — the kit’s code is applied when the kit is packed, so you never need to know it. The order must have its lab_code by then; an order without one returns 409. Activation is also what places the laboratory order: the kit’s panel is ordered at the lab under its lab_code, so the returned sample is expected and results attach as the lab reports them. This runs after the response, and a laboratory-side problem is handled by Aniva rather than surfaced on your request.

Individual biomarkers

You can attach individual biomarkers to a home kit order as à la carte tests, outside the panel. This is useful when you want a tailored selection on top of the kit. The attached biomarkers surface on the home kit order response as an individual_biomarkers array (a sibling of panels). Both biomarker endpoints require the home_kit_orders_individual_biomarker_selection capability scope on top of home_kit_orders_manage — home kits are ordered by panel, so à-la-carte markers are enabled per partner. Ask Aniva if your integration needs it. Add biomarkers (idempotent — already-attached biomarkers are kept):
Remove biomarkers (idempotent — an ID that is not attached is ignored):
Both endpoints take a biomarker_ids array. Use List Biomarkers with home_kit=true to discover biomarker IDs. Biomarkers can only be changed while the kit is pending (see Lifecycle).

Retrieving lab results

Once the lab has processed the returned sample, retrieve clinical and genetic results:
The response includes planned tests (status planned) alongside received results, so you can track what is still pending. Results file under the order’s lab_code and arrive marker by marker as the lab analyses them, so partial payloads are normal. The top-level status field is in_progress until the final report, then completed (or fault when every lab order died without reporting) — use this to derive whether the home kit order’s lab work is done. A home_kit_order.results.completed webhook tells you when that happens, so you do not need to poll. Lab report PDFs are referenced in the documents array — use GET /api/v1/documents/{id} to download them.

Example home kit order