Skip to content

Labs

Lab orders placed through Cuvo's lab network, the reports that come back, corrections, and the short-lived PDF link.

A lab order is one panel a patient is tested for through Cuvo's lab network. It was asked for by the clinic, by a clinician reviewing a case, or by the patient. A lab result is a report that came back for an order. Both are read-only here: the lab rail owns every transition, and you hear about them as events.

Every operation on this page needs labs:read. A clinic decides that scope separately from the rest, because lab values are the most sensitive read the API offers.

Lab orders

GET /v1/lab_orders lists the organization's orders, newest first.

curl "https://api.cuvo.co/v1/lab_orders?patient=pat_9f2c1a7b&updated_after=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer cuvo_sk_live_…"
{
  "data": [
    {
      "id": "lbo_3c9e1f20",
      "patient": "pat_9f2c1a7b",
      "case": "case_7d1e4b2a",
      "panel": { "slug": "testosterone", "name": "Testosterone, total and free" },
      "status": "at_lab",
      "collection_method": "at_home_kit",
      "lab": "quest",
      "requested_by": "clinician",
      "cancelled_at": null,
      "created_at": "2026-10-12T15:02:11Z",
      "updated_at": "2026-10-14T09:40:03Z"
    }
  ],
  "has_more": false
}
  • patient, status and updated_after filter the list. updated_after returns orders changed strictly after that moment, so pass back the newest updated_at you have seen.
  • limit and starting_after page it. See Pagination.
  • GET /v1/lab_orders/{id} reads one.

status is one of awaiting_patient, placed, collecting, at_lab, final, cancelled or failed. awaiting_patient waits for the patient to choose how they are collected; final means the report is in or on its way.

patient is null only while an order a patient placed for themselves is not linked to a chart yet. case names the case whose clinician asked for the order, when one did. collection_method and lab are null until the patient chooses. Nothing here names the lab network's own ids, a price, or the person who placed the order beyond requested_by.

Results

GET /v1/lab_orders/{id}/results lists an order's reports, highest version first. GET /v1/lab_results/{id} reads one.

{
  "id": "lbr_8a41d7c2",
  "lab_order": "lbo_3c9e1f20",
  "patient": "pat_9f2c1a7b",
  "version": 1,
  "flag": "abnormal",
  "collected_at": "2026-10-13T08:15:00Z",
  "reported_at": "2026-10-14T09:38:51Z",
  "released_at": "2026-10-14T09:40:03Z",
  "values": [
    {
      "biomarker": "2986-8",
      "name": "Testosterone, total",
      "value_numeric": 212,
      "value_text": "212",
      "unit": "ng/dL",
      "reference_range": { "low": 264, "high": 916, "text": "264-916" },
      "flag": "abnormal",
      "observed_at": "2026-10-13T08:15:00Z"
    }
  ],
  "pdf_url": "https://…",
  "pdf_url_expires_at": "2026-10-14T09:45:03Z",
  "created_at": "2026-10-14T09:40:03Z"
}
  • biomarker is the stable key to trend a marker by: its LOINC code, else the lab's own marker id.
  • value_text is always what the lab printed. value_numeric is the same value as a number, when it is one.
  • flag is normal, abnormal, critical or unknown. A report's flag is the worst of its values.

Only released reports

A report appears here once it is released, the moment the patient can see it, and never before. A report a clinic filed by hand from an outside lab is part of the clinic's own record and is never served, whether or not it was shared with the patient.

Corrections

When the lab corrects a report, the correction is a new result with its own lbr_ id and the next version, and it fires its own lab_result.final.v1. Earlier versions stay readable. The highest version is current.

The PDF link

pdf_url is minted for the response that carries it and expires five minutes later, at pdf_url_expires_at. Follow it right away and never store it: read the result again for a fresh link. It is null when no PDF is on file.

Events

lab_order.placed.v1 and lab_order.status_changed.v1 carry the order's status when the event was written; read the order for the current one. An order is first announced when it is placed, so one still waiting on the patient shows up only in the list. An order a clinician requested during a case review also carries case. lab_result.final.v1 fires once per released version and carries no status. No lab event carries patient: read it from the order or the result. See Events and realtime for the shape.

Lab events reach an integration only when the organization's grant includes labs:read. A grant without it hears nothing about lab work, by webhook, poll or realtime, and a grant that gains the scope hears from that point on.

Test mode

The sandbox places no lab orders. Under a test key GET /v1/lab_orders answers an empty list, and any lab order or result id answers 404 not_found. To build a receiver for lab events, POST /v1/test/webhooks/trigger sends any of the three types about a fabricated resource. See Test mode.