API reference
Generated from the code that serves the API: the same sources the partner kit's reference index is built from, and checked against the routes the API mounts. Request and response bodies, and machine-readable contract packages with every fixture, are provided with your sandbox credentials.
Contract versions
| Contract | Version | How it is pinned |
|---|---|---|
| Order contract (orders, quotes, prescribers) | 3.2.0 | responses carry contractVersion; a new major is published beside this one |
| Regimen quote | 1.0.0 | its own number |
| Pre-sign checks | 1.0.0 | its own number |
| Prescriber sync | 1.0.0 | its own number |
| Catalog | 10.0.0 by default, 11.0.0 on request | send TrueRoute-Catalog-Contract: 11 to opt in |
| Modules (patients, labs, collection, invoices) | 2.9.0 | every module response carries X-TrueRoute-Modules-Contract |
A minor release only adds; a breaking change is a new major published beside the old one. See the changelog.
Scopes
| Scope | What it opens |
|---|---|
catalog:read | read the catalog projection: products, packages, categories, availability, block reasons. Carries no cost, no pharmacy identity and no margin. |
collection:read | list collection sites and slots; read appointments, kit shipments and requisitions |
collection:write | book, reschedule and cancel collection appointments |
critical:acknowledge | record critical-value acknowledgement statements. Escalation owner consumer (customer_supplied authority, or trueeval_supplied on an integration a TrueRoute operator has flagged trueEvalOwnedConsumer): first escalated_to_responsible_clinician (delivered to the clinic's responsible clinician), then the clinician's clinical follow-up. Escalation owner trueroute (customer_supplied only): the clinician's clinical follow-up. |
diagnostics:read | read the lab catalog, collection devices, quotes, journeys and their state machines, and invoice records |
diagnostics:write | quote, place and cancel a diagnostic order |
modules:read | read the clinic's platform modules and vendor rails (diagnostics, collection, devices), each with its derived readiness and blockers. Carries no cost, no vendor credential and no patient data. |
orders:read | read one order by id or by externalOrderId. There is no bulk listing form. |
orders:write | submit an order. Requires an Idempotency-Key and a request signature. |
patients:read | read a patient reference, by TrueRoute id or by your own external id (it carries no demographics) |
patients:write | create a patient reference and append a demographics version (reading one is patients:read) |
prescribers:write | map an upstream prescriber onto a TrueRoute provider. Separate from orders:write on purpose -- a bad order is one script, a bad prescriber sync is every future script naming them. |
quotes:read | obtain a clinic-facing price and the per-pharmacy gate outcomes. Named read because it is what the PARTNER does; the quote row we keep is our own bookkeeping. |
results:read | read results, their versions and source documents, critical facts and unmatched results. Granted per clinic to named result readers only; never implied by another scope. |
A credential holds the narrowest set its use needs. results:read is granted per clinic to named result readers only.
Prescriptions
| Method | Path | Scope | Signature | Idempotency-Key | Purpose |
|---|---|---|---|---|---|
| GET | /v1/integrations/catalog | catalog:read | not signed | not read | products and packages the clinic may prescribe; key everything on packageId |
| POST | /v1/integrations/prescribers | prescribers:write | unkeyed form | not read | sync a prescriber when it is created in the EHR (upsert on upstreamPrescriberId); optional clinicId names a clinic this integration holds a prescribers:write grant for (prescriber sync contract) |
| GET | /v1/integrations/prescribers/:upstreamPrescriberId | prescribers:write | not signed | not read | read a synced prescriber and whether it is routable (optional ?clinicId=, as the sync) |
| POST | /v1/integrations/quotes | quotes:read | unkeyed form | not read | price one product for one patient; returns the eligible pharmacies and totals |
| POST | /v1/integrations/regimen-quotes | quotes:read | keyed form | required | price an 84-day titration bundle as one course; required before a bundle order |
| POST | /v1/integrations/orders | orders:write | keyed form | required | submit a signed order (one prescription, or three with a regimen) |
| POST | /v1/integrations/orders/validate | orders:write | unkeyed form | not read | dry-run an order BEFORE the prescriber signs: every refusal the order would get, nothing written |
| POST | /v1/integrations/prescription-checks | quotes:read | unkeyed form | not read | the script pad's dose assistance for a product and its directions; advisory only |
| POST | /v1/integrations/orders/:externalOrderId/clinical-release | orders:write | keyed form | required | release a funded order that was accepted and held |
| POST | /v1/integrations/orders/:externalOrderId/funding-reversal | orders:write | keyed form | required | tell TrueRoute the EHR refunded the patient |
| GET | /v1/integrations/orders | orders:read | not signed | not read | read one order by YOUR id: ?externalOrderId=... (the recovery path) |
| GET | /v1/integrations/orders/:orderId | orders:read | not signed | not read | read one order by TrueRoute orderId |
Modules
Every module request names clinicId: in the signed body of a POST, in the query of a GET. Every module route can also answer unauthorized, authentication_failed, environment_mismatch, integration_suspended, insufficient_scope, clinic_id_required, grant_missing, clinic_not_leaf, rate_limited, internal_error; every module POST also signature_required, signature_expired, timestamp_out_of_window, unsupported_media_type, unknown_field, missing_field, idempotency_key_required, idempotency_key_reuse, request_in_flight.
Availability, patients and invoices
GET /v1/modules/availability
The clinic's modules and rails, each with honest readiness and its blockers.
- Scope
modules:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
ModuleAvailabilityResponse,ModuleState,RailState,RailCapabilities,PatientFacingBrand
POST /v1/modules/patients
Create (write once) the patient reference for (integration, environment, clinic, externalPatientId).
- Scope
patients:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
PatientRefCreateRequest- Response shapes
PatientRefView- Route errors
invalid_identifier,invalid_demographics,patient_ref_conflict
GET /v1/modules/patients/:patientRefId
Read a patient reference by TrueRoute id. Carries no demographics.
- Scope
patients:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
PatientRefView- Route errors
patient_ref_not_found
GET /v1/modules/patients/by-external-id/:externalPatientId
Read a patient reference by the consumer's own (opaque) patient id.
- Scope
patients:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
PatientRefView- Route errors
patient_ref_not_found
POST /v1/modules/patients/:patientRefId/demographics
Append a demographics version to an existing reference. Never an overwrite, never a merge.
- Scope
patients:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
PatientDemographicsAppendRequest- Response shapes
PatientRefView- Route errors
invalid_demographics,patient_ref_not_found
GET /v1/modules/invoices
Invoice and credit-note records for reconciliation, in both billing modes.
- Scope
diagnostics:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId,from,to,cursor- Response shapes
ModuleInvoicesResponse,ModuleInvoiceView,ModuleChargeLine- Route errors
invalid_time_window
GET /v1/modules/invoices/:invoiceId
One invoice or credit-note record.
- Scope
diagnostics:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
ModuleInvoiceView,ModuleChargeLine- Route errors
invoice_not_found
Diagnostics (labs)
GET /v1/modules/diagnostics/catalog
A lab's catalog for this clinic: performing lab, components with LOINC, AOE questions, clinic price.
- Scope
diagnostics:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId,lab- Response shapes
LabCatalogResponse,LabCatalogTest,PerformingLabRef,CatalogComponent,LoincRef,AoeQuestion,AoeQuestion.options[],PatientPrepItem,LabCatalogEligibility- Route errors
module_not_enabled,rail_not_enabled,module_suspended
POST /v1/modules/diagnostics/quotes
Eligibility (eligible / ineligible / unknown), binding and a frozen, server-derived price, before any charge.
- Scope
diagnostics:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
DiagnosticQuoteRequest- Response shapes
DiagnosticQuoteResponse,DiagnosticQuoteTestLine,PerformingLabRef,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice- Route errors
module_not_enabled,rail_not_enabled,module_suspended,readiness_not_live,clinic_suspended_by_consumer,clinic_mapping_pending,tests_empty,test_not_found,collection_rail_not_offered_for_lab,patient_ref_not_found,invalid_demographics,billing_arrangement_missing,authority_mode_not_enabled,collection_device_required,collection_device_not_found,device_setting_not_permitted,rail_capability_unavailable,lab_bill_type_not_permitted,lab_billing_conditions_unmet,authority_mode_state_restricted
GET /v1/modules/diagnostics/quotes/:quoteId
Read a frozen quote.
- Scope
diagnostics:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
DiagnosticQuoteResponse,DiagnosticQuoteTestLine,PerformingLabRef,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice- Route errors
quote_not_found
POST /v1/modules/diagnostics/orders
Place a diagnostic order on a frozen quote. 201 with the journey; the lab outcome follows on the lab order machine.
- Scope
diagnostics:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
DiagnosticOrderRequest- Response shapes
DiagnosticJourneyView,PerformingLabRef,OrderingClinicianView,PrescriberContact,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice,MachineState,DiagnosticJourneyView.specimens[],RequisitionSummary,AppointmentSummary,ResultSummary- Route errors
module_not_enabled,rail_not_enabled,module_suspended,readiness_not_live,clinic_suspended_by_consumer,clinic_mapping_pending,quote_not_found,quote_expired,quote_input_mismatch,quote_not_orderable,patient_contact_missing,price_changed,external_order_id_conflict,patient_ref_not_found,tests_empty,test_not_orderable,collection_rail_not_offered_for_lab,authority_mode_mismatch,authority_mode_not_enabled,clinician_selection_required,clinician_not_found,clinician_not_authorized,npi_verification_synthetic_not_live,clinician_licence_state,billing_arrangement_missing,card_on_file_required,responsible_party_missing,critical_escalation_owner_missing,critical_escalation_owner_not_permitted,patient_facing_brand_missing,patient_state_not_served,aoe_answer_missing,diagnosis_code_invalid,collection_device_required,collection_device_not_found,device_setting_not_permitted,rail_capability_unavailable,payment_method_required,vendor_unavailable,lab_bill_type_not_permitted,lab_billing_conditions_unmet,authority_mode_state_restricted,critical_contact_missing
GET /v1/modules/diagnostics/orders/:journeyId
The authoritative read of a journey and its four machines, by TrueRoute id.
- Scope
diagnostics:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
DiagnosticJourneyView,PerformingLabRef,OrderingClinicianView,PrescriberContact,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice,MachineState,DiagnosticJourneyView.specimens[],RequisitionSummary,AppointmentSummary,ResultSummary- Route errors
journey_not_found
GET /v1/modules/diagnostics/orders/by-external-id/:externalOrderId
The same read by the consumer's own order id: the reconciliation path after an ambiguous submit.
- Scope
diagnostics:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
DiagnosticJourneyView,PerformingLabRef,OrderingClinicianView,PrescriberContact,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice,MachineState,DiagnosticJourneyView.specimens[],RequisitionSummary,AppointmentSummary,ResultSummary- Route errors
journey_not_found
POST /v1/modules/diagnostics/orders/cancel
Cancel by journeyId or externalOrderId: 200 with the cancelled journey, or order_not_cancellable when too late.
- Scope
diagnostics:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
DiagnosticOrderCancelRequest- Response shapes
DiagnosticJourneyView,PerformingLabRef,OrderingClinicianView,PrescriberContact,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice,MachineState,DiagnosticJourneyView.specimens[],RequisitionSummary,AppointmentSummary,ResultSummary- Route errors
cancel_target_ambiguous,journey_not_found,order_not_cancellable,vendor_unavailable
GET /v1/modules/diagnostics/results
A journey's results, by id and current revision.
- Scope
results:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId,journeyId- Response shapes
DiagnosticResultListResponse,ResultSummary- Route errors
journey_not_found
GET /v1/modules/diagnostics/results/:resultId
The AUTHORITATIVE result read: every revision, each a full snapshot with lineage.
- Scope
results:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
DiagnosticResultView,OrderingClinicianView,PrescriberContact,ResultRevision,ResultRevision.correction,ResultRevision.rawPayload,SpecimenFacts,PerformingSite,PerformingSite.address,ResultObservation,LoincRef,MissingResult,SourceDocumentRef- Route errors
result_not_found
GET /v1/modules/diagnostics/results/:resultId/revisions/:revision
One revision of a result, current or prior.
- Scope
results:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
DiagnosticResultRevisionResponse,ResultRevision,ResultRevision.correction,ResultRevision.rawPayload,SpecimenFacts,PerformingSite,PerformingSite.address,ResultObservation,LoincRef,MissingResult,SourceDocumentRef- Route errors
result_not_found,result_version_not_found
GET /v1/modules/diagnostics/critical-facts/:criticalFactId
A critical fact with value, unit, range and raw flag, and its escalation timestamps.
- Scope
results:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
CriticalFactView,CriticalFactView.escalation,CriticalFactView.escalation.acknowledgedBy,CriticalAcknowledgementStatement,LoincRef,PerformingSite,PerformingSite.address,OrderingClinicianView,PrescriberContact- Route errors
critical_fact_not_found
POST /v1/modules/diagnostics/critical-facts/:criticalFactId/acknowledgements
Record one acknowledgement statement: under escalation owner consumer, first escalated_to_responsible_clinician (receipt, may name no clinician), then the clinical follow-up (customer_supplied, or trueeval_supplied on a trueEvalOwnedConsumer integration).
- Scope
critical:acknowledge- Signature
- keyed form
- Idempotency-Key
- required
- Request body
CriticalAcknowledgementRequest- Response shapes
CriticalFactView,CriticalFactView.escalation,CriticalFactView.escalation.acknowledgedBy,CriticalAcknowledgementStatement,LoincRef,PerformingSite,PerformingSite.address,OrderingClinicianView,PrescriberContact- Route errors
critical_fact_not_found,critical_ack_not_permitted,critical_ack_clinician_invalid,critical_already_acknowledged,clinician_not_found
Collection
GET /v1/modules/collection/sites
Collection sites near a postal code on a rail.
- Scope
collection:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId,rail,postalCode,radiusMiles- Response shapes
CollectionSitesResponse,CollectionSiteView,CollectionSiteView.address,CollectionSiteView.hours[]- Route errors
module_not_enabled,rail_not_enabled,rail_capability_unavailable
GET /v1/modules/collection/slots
Bookable slots at a site, or for a mobile visit to the patient on a journey.
- Scope
collection:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId,rail,siteId,journeyId,from,to- Response shapes
CollectionSlotsResponse,CollectionSlotView- Route errors
module_not_enabled,rail_not_enabled,rail_capability_unavailable,site_not_found,journey_not_found,invalid_time_window,vendor_unavailable
POST /v1/modules/collection/appointments
Book a collection appointment for a journey. The outcome may be pending or ambiguous, then reconciled.
- Scope
collection:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
AppointmentBookRequest- Response shapes
AppointmentView- Route errors
module_not_enabled,rail_not_enabled,module_suspended,readiness_not_live,clinic_suspended_by_consumer,clinic_mapping_pending,journey_not_found,site_not_found,slot_not_found,appointment_slot_unavailable,appointment_not_modifiable,order_closed,patient_contact_missing,rail_capability_unavailable,patient_facing_brand_missing,vendor_unavailable
POST /v1/modules/collection/appointments/:appointmentId/reschedule
Move an appointment to a new slot (a new appointment that names the one it replaces).
- Scope
collection:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
AppointmentRescheduleRequest- Response shapes
AppointmentView- Route errors
appointment_not_found,slot_not_found,appointment_slot_unavailable,appointment_not_modifiable,order_closed,patient_contact_missing,rail_capability_unavailable,vendor_unavailable
POST /v1/modules/collection/appointments/:appointmentId/cancel
Cancel an appointment. The lab order is not cancelled by this.
- Scope
collection:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
AppointmentCancelRequest- Response shapes
AppointmentView- Route errors
appointment_not_found,appointment_not_modifiable,rail_capability_unavailable,vendor_unavailable
GET /v1/modules/collection/appointments/:appointmentId
Read an appointment.
- Scope
collection:read- Signature
- not signed
- Idempotency-Key
- not read
- Query
clinicId- Response shapes
AppointmentView- Route errors
appointment_not_found
Sandbox only
Mounted on the sandbox, never on production.
POST /v1/sandbox/modules/journeys/:journeyId/advance
Fire a sandbox journey's next scheduled fake steps now. Never mounted on a live host.
- Scope
diagnostics:write- Signature
- keyed form
- Idempotency-Key
- required
- Request body
SandboxAdvanceRequest- Response shapes
DiagnosticJourneyView,PerformingLabRef,OrderingClinicianView,PrescriberContact,ModulePriceSummary,ModuleChargeLine,CollectionDeviceChoice,MachineState,DiagnosticJourneyView.specimens[],RequisitionSummary,AppointmentSummary,ResultSummary- Route errors
journey_not_found
Published, not mounted yet
These answer 404. Do not build a dependency on them until a contract release marks them implemented.
| Method | Path | Scope |
|---|---|---|
| GET | /v1/modules/clinics | modules:read |
| POST | /v1/modules/clinics | clinics:write |
| POST | /v1/modules/clinics/:clinicId/brand | clinics:write |
| POST | /v1/modules/clinics/:clinicId/consumer-state | clinics:write |
| GET | /v1/modules/clinicians | modules:read |
| POST | /v1/modules/clinicians | clinicians:write |
| GET | /v1/modules/events | modules:read |
| POST | /v1/modules/events/resend | diagnostics:write |
| GET | /v1/modules/diagnostics/documents/:documentId | results:read |
| GET | /v1/modules/diagnostics/unmatched-results | results:read |
| GET | /v1/modules/collection/devices | diagnostics:read |
| GET | /v1/modules/collection/kits/:kitShipmentId | collection:read |
| GET | /v1/modules/collection/requisitions/:journeyId | collection:read |
| POST | /v1/modules/devices/connect-sessions | devices:write |
| GET | /v1/modules/devices/connect-sessions/:connectSessionId | devices:read |
| GET | /v1/modules/devices/connections | devices:read |
| POST | /v1/modules/devices/connections/:connectionId/disconnect | devices:write |
| GET | /v1/modules/devices/observations | devices:read |