Lab Test Lifecycle
Introduction
We encapsulate our lab test modalities in the order
object. This is the main object you will interact with, as it contains all the information related to that lab test. An order has a high-level status which represents where the order is throughout its lifecycle, e.g. received/delivered/completed/cancelled etc.
The high-level status is the same across test modalities. On top of that, each modality has its own sub-statuses, to represents lifecycle stages specific to that modality. For example, test-kits involve shipping of the box, so we have a whole set of statuses to track the shipment.
Statuses
Statuses are namespaced with the following format:
[HIGH-LEVEL STATUS].[TEST MODALITY].[LOW-LEVEL STATUS]
As an example, the status collecting_sample.at_home_phlebotomy.appointment_scheduled
means the patient has scheduled an at-home phlebotomy appointment.
High-level statuses
The high-level statuses of an order, are represented by order.status
:
received
: we received the order, stored it into our system, and started processing it.collecting_sample
: these track collecting the sample from the patient. In the case of test-kits, these track the shipment of the kit. For at-home phlebotomy, these track the patient scheduling an appointment. Walk-in tests don’t have this status because the patient can turn up at the lab anytime.sample_with_lab
: the lab received the sample and is currently analyzing it.completed
: the order is complete and the results are ready.cancelled
: the order has been cancelled, by you or the patient.failed
: we failed to process the order.
Modality specific sub-statuses are encapsulated in the order.events
list. These include a list of all the events for that test:
{
...,
"status": "cancelled",
"events": [
{
"id": 1,
"created_at": "2022-01-01T00:00:00Z",
"status": "received.testkit.ordered",
},
{
"id": 2,
"created_at": "2022-01-01T00:00:00Z",
"status": "received.testkit.requisition_created",
},
{
"id": 3,
"created_at": "2022-01-01T00:00:00Z",
"status": "collecting_sample.testkit.transit_customer"
},
],
}
Below is a full list of all the available statuses by test modality. The names should be self-descriptive. Please do not hesitate to contact us if you need any additional clarification!
Test-kit statuses
received.testkit.ordered
received.testkit.awaiting_registration
received.testkit.testkit_registered
received.testkit.requisition_created
collecting_sample.testkit.transit_customer
collecting_sample.testkit.out_for_delivery
collecting_sample.testkit.with_customer
collecting_sample.testkit.transit_lab
sample_with_lab.testkit.delivered_to_lab
completed.testkit.completed
failed.testkit.failure_to_deliver_to_customer
failed.testkit.failure_to_deliver_to_lab
failed.testkit.sample_error
failed.testkit.lost
cancelled.testkit.cancelled
cancelled.testkit.do_not_process
Walk-in visit statuses
received.walk_in_test.ordered
received.walk_in_test.requisition_created
sample_with_lab.walk_in_test.partial_results
completed.walk_in_test.completed
failed.walk_in_test.sample_error
cancelled.walk_in_test.cancelled
At-home phlebotomy statuses
received.at_home_phlebotomy.ordered
received.at_home_phlebotomy.requisition_created
collecting_sample.at_home_phlebotomy.appointment_scheduled
collecting_sample.at_home_phlebotomy.draw_completed
collecting_sample.at_home_phlebotomy.appointment_cancelled
sample_with_lab.at_home_phlebotomy.partial_results
completed.at_home_phlebotomy.completed
cancelled.at_home_phlebotomy.cancelled
Critical Results
When our Lab partners return results to Vital, they may return specific interpretations for each Marker:
normal
, the marker value is inside the lab reference range.abnormal
, the marker value is outside the lab reference range.critical
, the marker value falls in the critical range for that marker, which can be life-threatening.
These values are returned in an interpretation
field for results, both in each individual marker and the overall results object:
{
"metadata": {
"age": 19,
"dob": "18/08/1993",
"clia_number": "12331231",
"patient": "Bob Smith",
"provider": "Dr. Jack Smith",
"laboratory": "LabCorp",
"date_reported": "2020-01-01",
"date_collected": "2022-02-02",
"specimen_number": "123131",
"date_received": "2022-01-01",
"status": "final",
"interpretation": "critical"
},
"results": [
{
"name": "Hemoglobin",
"slug": "hemoglobin",
"unit": "g/dL",
"notes": null,
"value": 100.2,
"timestamp": null,
"max_range_value": 17.7,
"min_range_value": 13.0,
"is_above_max_range": true,
"is_below_min_range": false,
"interpretation": "critical"
},
{
"name": "Sodium",
"slug": "unknown",
"unit": "mmol/L",
"notes": null,
"value": 136,
"timestamp": null,
"max_range_value": 144,
"min_range_value": 134,
"is_above_max_range": false,
"is_below_min_range": false,
"interpretation": "normal"
}
]
}
Besides the interpretation
field, there is also the status
field, which can assume the values of final
or partial
, as the critical results are notified as soon as they’re available, not all tests are guaranteed to have been processed by the lab.
For critical results, the Lab that published the results must call a physician to contact the patient to inform them about the critical results and give the correct orientation. The physician called will be the Vital assigned physician who acts as the ordering physician when placing the Lab Test order. After the call has been made and Vital has received the results from the Lab, a labtest.result.critical
event will be fired to customers, with the webhook payload containing the following information:
{
"data": {
"created_at": "2023-09-04T19:02:33.042533+00:00",
"updated_at": "2023-09-04T19:02:47.106778+00:00",
"order_id": "93ae03a7-626f-4cf4-802b-1fb6b3c339c7",
"sample_id": "W4123LKB3VTL",
"status": "final",
"interpretation": "critical",
"team_id": "482gh249-cd9d-4049-bb42-db5682cdf1d2",
"user_id": "db5d34d5-bf7b-4e25-b119-9asd53694f45"
},
"event_type": "labtest.result.critical"
}
After you receive the webhook, you can use the GET /order/{order_id}/result
endpoint to fetch the raw results.
You can test the webhook event by using the Vital Dashboard Webhooks section,
where you can register an endpoint and subscribe to the labtest.result.critical
event.
The following images shows what the screen should look like after you have an endpoint registered
and has selected the Testing
section inside the endpoint configurations.

You can then click the Send Example
button and should receive a HTTP call in the registered url.