Skip to main content
Build a lab status report for a project

Path Parameters

project_id
string
required

Query Parameters

sections
enum<string>[] | null

Sections to include. Repeat the parameter for several. Omit for the full report.

The selectable sections of a lab report.

Used both as the sections query parameter on the report endpoint and as the key for the corresponding field on :class:LabReport.

Available options:
highlights,
utilization,
recently_stopped,
stopping_soon,
past_due,
queue,
unscheduled_requests,
maintenance,
idle_channels
recently_stopped_hours
integer
default:24

Lookback for stopped channels

Required range: 1 <= x <= 2160
stopping_soon_hours
integer
default:24

Forecast window for channels freeing up

Required range: 1 <= x <= 2160
idle_thresholds_days
integer[] | null

Idle thresholds in days, e.g. 2 and 3. Channels past the lowest are listed; the rest become counts. Defaults to 2 and 3.

Required range: 1 <= x <= 365
queue_limit
integer
default:20

Maximum queued measurements to list

Required range: 1 <= x <= 200
queue_horizon_days
integer
default:7

How far ahead the queue looks

Required range: 1 <= x <= 365
service_horizon_days
integer
default:30

How far ahead booked service is reported

Required range: 1 <= x <= 365
trend_window_days
integer
default:7

Length of the momentum trend window

Required range: 1 <= x <= 90

Response

Successful Response

A rendered lab operations report plus the data behind it.

markdown is the whole report as a document (the intended payload for PDF conversion or messaging); the structured sections are the same content unformatted, for consumers that want to re-render or post-process it. Sections not requested are None.

project_id
string
required

Project the report covers

generated_at
string<date-time>
required

Server time the report was generated (UTC)

parameters
LabReportParameters · object
required

The parameters this report was built with

markdown
string
required

The full report rendered as Markdown

project_name
string | null

Project name

organization_name
string | null

Organization the project belongs to

prepared_for_email
string | null

Email of the user the report was generated for

highlights
HighlightsSection · object | null

Momentum: what the lab produced over the trend window, and how hard it ran.

Two subjects only — output (channel-hours, tests started and finished) and the utilization trend — both reconstructed by replaying measurement intervals. Equipment service lives in :class:MaintenanceSection instead, beside the channels currently down: repairs are a different subject from output, and the multi-period repair ladder reaches further back than this section's window, so presenting it under a "last N days" heading was a contradiction.

Every point divides by today's channel count, because channels itself keeps no history: a channel added last week is in the denominator of samples from before it existed. That makes the shape of the series trustworthy and its absolute values approximate whenever equipment moved inside the window — and is why the trend window is capped.

utilization
UtilizationSection · object | null

Utilization for the whole project, by site and by program, vs yesterday.

The day-over-day comparison is reconstructed rather than stored: there is no utilization history table, so yesterday's figure is derived by replaying the measurement intervals that were open 24 hours ago. Its denominator is today's channel count, because the equipment tables carry no history either — so a lab that added channels overnight will see a small artificial dip. Over a single day that error is negligible; over months it would not be, which is why nothing here reaches further back than the trend window.

recently_stopped
RecentlyStoppedSection · object | null

Tests that finished in the lookback window, and what the list left out.

A list rather than a bare count because the useful question is which channels came free and what was on them. It is capped for the same reason the other list sections are: recently_stopped_hours reaches back up to 90 days, and a large lab on short protocols finishes thousands of runs in that time — too many to fetch, hold, or render as one table.

stopping_soon
StoppingSoonSection · object | null

Channels forecast to free up, and what the forecast could not place.

A scheduled release can be missing from the list for two unrelated reasons, counted separately because they need different responses and would be uninterpretable summed together: the list hit its cap (planned_beyond_cap), or the plan has no channel assigned yet (unassigned_count) and so cannot be attributed to one.

Running tests are bounded by the channel count and so are never capped.

.. note::

past_due
PastDueSection · object | null

Plans that should have started and have not.

Split out of the queue rather than filtered into it. The queue answers "what is coming up", and a plan whose start time has passed is not upcoming work — counting it there both inflates the horizon total and hides the more urgent fact that something slipped. These need a decision (start it, reschedule it, cancel it) rather than a slot.

queue
QueueSection · object | null

The near-term queue, with enough context to trust what is missing.

A queue is only meaningful if the reader knows what was left out, so the section carries its own horizon and totals rather than silently truncating: total_in_horizon is every plan starting inside the window (not just the listed ones) and undated_count is the backlog of requests with no date yet, which have no place in a time-ordered queue but should not vanish.

Bounded on both sides: only plans starting between the report time and the horizon. A plan whose start time has already passed is not upcoming work and belongs in :class:PastDueSection.

unscheduled_requests
UnscheduledRequestsSection · object | null

Requested tests with no slot, longest-waiting first.

Sorted oldest-request-first rather than newest: the point of the section is to surface what has been forgotten, and the request that has waited longest is the one most likely to have been.

maintenance
MaintenanceSection · object | null

Equipment service: what is down, what is due, and what is booked.

Carries the outage list, the repair counts, the calibration schedule, and upcoming visits, because they answer one question together — "are we on top of the equipment?" — and none is much use alone. Six down channels reads very differently next to "eight repaired this week" than next to "none", and a lab that is current on repairs can still be three months overdue on calibration.

Outages are reported at the level the work happens at: a channel-local fault is a channel row, an instrument-level visit is one cycler row carrying its channel count. Without that split, one calibration on a 40-channel cycler would bury every genuine channel fault in the project.

retired_count exists so the section can never silently disagree with the Lab wall: the wall counts every out-of-commission channel, this section lists only the ones a repair could return, and without the count the difference would read as a missing row.

idle_channels
IdleChannelsSection · object | null

Idle healthy channels, plus a count at each requested threshold.

Rows are every channel past the lowest threshold, longest-idle first; the tier counts then say how many also cross the higher ones (the classic "N idle over 2 days, of which M over 3" phrasing) without listing a channel more than once.