REST API for the Habitat tissue-culture automation platform by Open Culture Science. All endpoints accept and return JSON.
schedule
GET /schedule/events
List Events
Description
List scheduled events with optional filters.
Call with no params for the full list (backward compatible).
Every row carries a computed display category (see
:mod:habitat.models.categories); the X-Total-Count
response header reports how many events matched the filters
BEFORE limit/offset, so a capped consumer (the GUI's
20-row upcoming queue) can say "+N more" truthfully.
Input parameters
Parameter
In
Type
Default
Nullable
Description
action
query
No
date_from
query
No
date_to
query
No
limit
query
No
offset
query
integer
0
No
sample_id
query
No
search
query
No
series_id
query
No
status
query
No
Responses
[{}]
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response List Events Schedule Events Get"}
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
start_time is coerced to an aware-UTC ISO string on write
(naive input = host-local time, issue #227); the 201 response
echoes the canonical string.
Request body
{"action":"drain_fill","sample_id":"sample_001","start_time":"2026-05-13T22:00:00+00:00","duration_min":3.0,"parameters":{"chip_id":"chip_A","source_role":"reagent","fill_volume_ul":100.0,"drain_volume_ul":100.0,"air_backpad_ul":200.0},"notes":"Drug bolus at t+5 min from protocol start"}
{"properties":{"action":{"type":"string","title":"Action","description":"Action type (e.g. 'feed', 'wash')"},"sample_id":{"type":"string","title":"Sample Id","description":"Target sample ID"},"start_time":{"type":"string","title":"Start Time","description":"Scheduled start (ISO 8601). Stored as aware UTC: a naive timestamp is interpreted as host-local time and converted; the response echoes the canonical +00:00 string."},"duration_min":{"type":"number","exclusiveMinimum":0.0,"title":"Duration Min","default":5.0},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"series_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Series Id"},"notes":{"type":"string","title":"Notes","default":""},"color":{"type":"string","title":"Color","default":"#8FB87A"}},"type":"object","required":["action","sample_id","start_time"],"title":"CreateEventRequest","description":"Request body for POST /schedule/events."}
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
List grouped series summaries (one row per series + one per singleton).
Input parameters
Parameter
In
Type
Default
Nullable
Description
action
query
No
date_from
query
No
date_to
query
No
limit
query
No
offset
query
integer
0
No
sample_id
query
No
search
query
No
status
query
No
Responses
[{}]
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response List Series Schedule Series Get"}
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
Delete a scheduled event (removes the row entirely).
Prefer POST /schedule/events/{id}/cancel for operator kills
— it preserves the row as cancelled history. This endpoint
remains for callers that genuinely want the row gone.
Input parameters
Parameter
In
Type
Default
Nullable
Description
event_id
path
string
No
Responses
Schema of the response body
{"type":"object","additionalProperties":true,"title":"Response Delete Event Schedule Events Event Id Delete"}
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
Cancel one still-scheduled event (kept as history).
The row flips to cancelled and its trigger is removed, so it
never fires — including the race where it already fired and is
queued on the engine's execution lock (the engine re-checks
status under the lock). 404 for an unknown id; 409 when the
event is already running (cancel its Job via
DELETE /jobs/{id}) or already terminal.
Input parameters
Parameter
In
Type
Default
Nullable
Description
event_id
path
string
No
Responses
Schema of the response body
{"type":"object","additionalProperties":true,"title":"Response Cancel Event Schedule Events Event Id Cancel Post"}
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
Cancel EVERY still-scheduled event — the schedule kill switch.
Pending events flip to cancelled (kept as history); running
events and history are untouched. Idempotent: a second call
finds nothing pending and reports cancelled: 0.
Responses
Schema of the response body
{"additionalProperties":true,"type":"object","title":"Response Cancel All Schedule Cancel All Post"}
POST /schedule/refresh
Refresh
Description
Force reload from SQL and return all events.
The manual override for out-of-band edits to the
schedule_events table (issue #205 moved persistence off
data/schedule.json) — the schedule counterpart of
POST /system/refresh-registries.
Responses
[{}]
⚠️This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.Schema of the response body
Atomic parameters keyed by the names declared in the manifest.
provenance
AtomicManifest
Name
Type
Description
authored_by
string
belongs_to_routines
Array<string>
blocking
description
string
device_kind
string
emits_metrics
Array<string>
Advisory list of metric names this atomic is expected to emit. Not populated by any atomic today and not enforced or cross-checked against the telemetry layer -- agent-read-only metadata, not a live emission guarantee.
estimated_fluid_volume_ul
estimated_wear
string
Advisory relative wear estimate. Not derived from any measurement and not read by the runtime -- agent-read-only metadata for planning, not a calibrated cost model.
Advisory pointer to the atomic that would undo this one. Not populated by any atomic today and not enforced or invoked by the runtime -- agent-read-only metadata, not a guarantee a reverse operation exists or is registered.
reversible
boolean
side_effects
Array<string>
summary
string
tier
string
typical_predecessors
Array<string>
typical_successors
Array<string>
validated_on_hardware
Array<string>
version
string
CreateEventRequest
Name
Type
Description
action
string
Action type (e.g. 'feed', 'wash')
color
string
duration_min
number
notes
string
parameters
sample_id
string
Target sample ID
series_id
start_time
string
Scheduled start (ISO 8601). Stored as aware UTC: a naive timestamp is interpreted as host-local time and converted; the response echoes the canonical +00:00 string.
Optional one-shot post-init plunger gap in increments. If provided, ``set_init_gap`` is called BEFORE the Z command on this initialization only. ``None`` means use the previously-configured gap (firmware default ~1600 if never set). DANGER: see ``POST /pumps/{addr}/init-gap`` for hazard details. This path requires ``gap_increments >= 100`` (the safety floor) — there is no override field on this endpoint. Persisting a sub-floor value requires human confirmation via the HITL-gated atomics/job path (``POST /atomics/centris.initialization.set_init_gap`` async + ``POST /jobs/{id}/confirm``); do that first, then initialize without ``init_gap_increments``.
input_port
integer
Distribution-valve input port for homing. Use ``0`` (or omit) for auto-selection from the pump YAML ``port_map``: first waste role, else first port not listed in the map, else port 1. JSON may use the field name ``init_port`` as an alias.
output_port
integer
Init output port (0=default)
speed_ul_per_s
Initialization speed as a volumetric rate in µL/s. None = firmware default homing speed. The driver snaps the value to the nearest firmware-supported discrete rate internally.
ABSOLUTE directory on this host where `habitat.action` records are being written — the input the OCS rig-runner reads for the fluidics ledger. Absolute because the consumer is a DIFFERENT PROCESS: a relative path would be resolved against its working directory, not habitat's, silently naming a directory that does not exist. Null means no action handler is installed (this device writes no action records).
device_name
string
Unique physical unit identifier, e.g. 'MistyForest'.
hostname
string
OS hostname of the device.
product_line
string
Product-line string, e.g. 'Habitat'.
started_at
string
UTC ISO-8601 timestamp when the process started.
uptime_s
number
Seconds since the process started.
version
string
Application semantic version.
SystemStatus
Name
Type
Description
active_jobs
integer
Count of jobs in the RUNNING state.
device_name
string
Unique physical unit identifier.
drivers_initialized
boolean
True once all drivers have connected and are ready for commands.
emergency_stop
boolean
True if an emergency stop is currently active.
kinds
Device-kind name → list of per-kind summary entries.
queued_jobs
integer
Count of jobs in the QUEUED state.
scheduled_events_pending
integer
Count of pending scheduled events.
TestRunRoutineRequest
Name
Type
Description
params
Routine parameters. Merged on top of the routine's manifest defaults before the executor walks the steps.
TimezoneResponse
Name
Type
Description
timezone
string
Display-timezone label — 'UTC', 'local', an IANA name like 'America/Los_Angeles', or a fixed offset like '+06:00'.
ValidateProtocolRequest
Name
Type
Description
yaml_text
string
Raw YAML text of the protocol manifest to validate.
ValidateRoutineRequest
Name
Type
Description
yaml_text
string
Raw YAML text of the routine manifest to validate.