Skip to main content

API Reference (Leader /api)

Conventions

  • Only the leader Pioreactor has the /api endpoints exposed.
  • Async endpoints return 202 Accepted with a task_id and result_url_path.
  • Poll GET /unit_api/task_results/{task_id} until status is succeeded or failed.
  • $broadcast may be used in path parameters where documented to target all units/workers.
  • File download endpoints return binary bodies; use the response content-type to handle them.
  • Path parameters are shown inline in the endpoint URL.
  • Request/response examples are the canonical shapes; omit optional fields you do not need.
  • Errors have the following schema:
{
"error": "Human-readable error message",
"cause": "Human-readable cause (defaults to error if not set)",
"remediation": "Suggested fix or next step",
"status": 400
}

Use /api/workers/... for worker-only targets (experiment-scoped jobs/logs) and /api/units/... when the leader is also a valid target; both accept $broadcast where supported.

Pioreactor Leader API

Generated from core/pioreactor/web/api.py.

This file is generated. Edit the API source or generator instead of editing this file by hand.

Endpoint count: 138

Endpoint Index

MethodPathHandler
GET/api/automations/descriptors/{automation_type}get_automation_descriptors
GET/api/bioreactor/descriptorsget_bioreactor_variable_descriptors
GET/api/charts/descriptorsget_chart_descriptors
GET/api/config/sharedget_shared_config
PATCH/api/config/sharedupdate_shared_config
GET/api/config/shared/historyget_shared_config_history
GET/api/config/units/{pioreactor_unit}get_config_for_pioreactor_unit
GET/api/config/units/{pioreactor_unit}/specificget_specific_config_for_pioreactor_unit
PATCH/api/config/units/{pioreactor_unit}/specificupdate_specific_config_for_pioreactor_unit
GET/api/config/units/{pioreactor_unit}/specific/historyget_specific_config_history_for_pioreactor_unit
GET/api/datasets/exportableget_exportable_datasets
GET/api/datasets/exportable/{target_dataset}/previewpreview_exportable_dataset
POST/api/datasets/exportable/exportexport_exportable_datasets
GET/api/experiment_profilesget_experiment_profiles
POST/api/experiment_profilescreate_experiment_profile
DELETE/api/experiment_profiles/{filename}delete_experiment_profile
GET/api/experiment_profiles/{filename}get_experiment_profile
PATCH/api/experiment_profiles/{filename}update_experiment_profile
GET/api/experimentsget_experiments
POST/api/experimentscreate_experiment
DELETE/api/experiments/{experiment}delete_experiment
GET/api/experiments/{experiment}get_experiment
PATCH/api/experiments/{experiment}update_experiment
GET/api/experiments/{experiment}/experiment_profiles/recentget_recent_experiment_profile_runs
GET/api/experiments/{experiment}/experiment_profiles/runningget_running_profiles
GET/api/experiments/{experiment}/historical_worker_assignmentsget_list_of_historical_workers_for_experiment
GET/api/experiments/{experiment}/logsget_exp_logs
GET/api/experiments/{experiment}/media_ratesget_media_rates
GET/api/experiments/{experiment}/recent_logsget_recent_logs
GET/api/experiments/{experiment}/time_series/{data_source}/{column}get_fallback_time_series
GET/api/experiments/{experiment}/time_series/growth_ratesget_growth_rates
GET/api/experiments/{experiment}/time_series/od_readingsget_od_readings
GET/api/experiments/{experiment}/time_series/od_readings_filteredget_od_readings_filtered
GET/api/experiments/{experiment}/time_series/od_readings_fusedget_od_readings_fused
GET/api/experiments/{experiment}/time_series/raw_od_readingsget_od_raw_readings
GET/api/experiments/{experiment}/time_series/temperature_readingsget_temperature_readings
GET/api/experiments/{experiment}/unit_labelsget_unit_labels
PATCH/api/experiments/{experiment}/unit_labelsupsert_unit_labels
PUT/api/experiments/{experiment}/unit_labelsupsert_unit_labels
DELETE/api/experiments/{experiment}/workersremove_workers_from_experiment
GET/api/experiments/{experiment}/workersget_list_of_workers_for_experiment
PUT/api/experiments/{experiment}/workersadd_worker_to_experiment
DELETE/api/experiments/{experiment}/workers/{pioreactor_unit}remove_worker_from_experiment
GET/api/experiments/activeget_active_experiments
GET/api/experiments/assignment_countget_experiments_worker_assignments
GET/api/experiments/latestget_latest_experiment
GET/api/historical_mediaget_historical_media_used
GET/api/historical_organismsget_historical_organisms_used
GET/api/jobs/descriptorsget_job_descriptors
GET/api/local_access_pointget_local_access_point
GET/api/logsget_logs
GET/api/modelsget_models
POST/api/system/update_from_archiveupdate_app_from_release_archive
POST/api/system/update_next_versionupdate_app
POST/api/system/uploadupload_system_file
POST/api/system/utc_clockset_system_utc_clock
GET/api/unitsget_list_of_units
GET/api/units/{pioreactor_unit}/capabilitiesget_capabilities
POST/api/units/{pioreactor_unit}/experiments/{experiment}/logspublish_new_log
POST/api/units/{pioreactor_unit}/import_zipped_dot_pioreactorimport_dot_pioreactor_archive
PATCH/api/units/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}run_job_on_unit_in_experiment
POST/api/units/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}run_job_on_unit_in_experiment
GET/api/units/{pioreactor_unit}/jobs/runningget_jobs_running
PATCH/api/units/{pioreactor_unit}/jobs/stop/experiments/{experiment}stop_all_jobs_on_unit_for_experiment
POST/api/units/{pioreactor_unit}/jobs/stop/experiments/{experiment}stop_all_jobs_on_unit_for_experiment
PATCH/api/units/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}stop_specific_job_on_unit
POST/api/units/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}stop_specific_job_on_unit
PATCH/api/units/{pioreactor_unit}/jobs/update/job_name/{job_name}/experiments/{experiment}update_job_on_unit
GET/api/units/{pioreactor_unit}/logsget_logs_for_unit
PATCH/api/units/{pioreactor_unit}/plugins/installinstall_plugin_across_cluster
POST/api/units/{pioreactor_unit}/plugins/installinstall_plugin_across_cluster
GET/api/units/{pioreactor_unit}/plugins/installedget_plugins_on_machine
PATCH/api/units/{pioreactor_unit}/plugins/uninstalluninstall_plugin_across_cluster
POST/api/units/{pioreactor_unit}/plugins/uninstalluninstall_plugin_across_cluster
POST/api/units/{pioreactor_unit}/system/rebootreboot_unit
POST/api/units/{pioreactor_unit}/system/shutdownshutdown_unit
GET/api/units/{pioreactor_unit}/system/utc_clockget_unit_utc_clock
GET/api/units/{pioreactor_unit}/system_logsget_system_logs_for_unit
GET/api/units/{pioreactor_unit}/versions/appget_app_versions
GET/api/units/{pioreactor_unit}/zipped_dot_pioreactorget_zipped_dot_pioreactor
GET/api/workersget_list_of_workers
PUT/api/workersadd_worker
DELETE/api/workers/{pioreactor_unit}delete_worker
GET/api/workers/{pioreactor_unit}get_worker
GET/api/workers/{pioreactor_unit}/active_calibrationsget_all_active_calibrations
DELETE/api/workers/{pioreactor_unit}/active_calibrations/{device}remove_active_status_calibration
PATCH/api/workers/{pioreactor_unit}/active_calibrations/{device}/{calibration_name}set_active_calibration
GET/api/workers/{pioreactor_unit}/active_estimatorsget_all_active_estimators
DELETE/api/workers/{pioreactor_unit}/active_estimators/{device}remove_active_status_estimator
PATCH/api/workers/{pioreactor_unit}/active_estimators/{device}/{estimator_name}set_active_estimator
GET/api/workers/{pioreactor_unit}/automations/descriptors/{automation_type}get_automation_descriptors_for_worker
PATCH/api/workers/{pioreactor_unit}/bioreactor/update/experiments/{experiment}update_bioreactor_on_unit
POST/api/workers/{pioreactor_unit}/blinkblink_worker
GET/api/workers/{pioreactor_unit}/calibration_protocolsget_calibration_protocols
GET/api/workers/{pioreactor_unit}/calibrationsget_all_calibrations
GET/api/workers/{pioreactor_unit}/calibrations/{device}get_calibrations
POST/api/workers/{pioreactor_unit}/calibrations/{device}create_calibration
DELETE/api/workers/{pioreactor_unit}/calibrations/{device}/{calibration_name}delete_calibration
GET/api/workers/{pioreactor_unit}/calibrations/{device}/{calibration_name}get_calibration
POST/api/workers/{pioreactor_unit}/calibrations/sessionsstart_calibration_session
GET/api/workers/{pioreactor_unit}/calibrations/sessions/{session_id}get_calibration_session
POST/api/workers/{pioreactor_unit}/calibrations/sessions/{session_id}/abortabort_calibration_session
POST/api/workers/{pioreactor_unit}/calibrations/sessions/{session_id}/inputsadvance_calibration_session
GET/api/workers/{pioreactor_unit}/capabilitiesget_capabilities
GET/api/workers/{pioreactor_unit}/estimatorsget_all_estimators
GET/api/workers/{pioreactor_unit}/estimators/{device}get_estimators_by_device
DELETE/api/workers/{pioreactor_unit}/estimators/{device}/{estimator_name}delete_estimator
GET/api/workers/{pioreactor_unit}/estimators/{device}/{estimator_name}get_estimator
GET/api/workers/{pioreactor_unit}/experimentget_experiment_assignment_for_worker
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/logsget_logs_for_unit_and_experiment
POST/api/workers/{pioreactor_unit}/experiments/{experiment}/logspublish_new_log
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/recent_logsget_recent_logs_for_unit_and_experiment
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/{data_source}/{column}get_fallback_time_series_per_unit
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/growth_ratesget_growth_rates_per_unit
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/od_readingsget_od_readings_per_unit
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/od_readings_filteredget_od_readings_filtered_per_unit
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/od_readings_fusedget_od_readings_fused_per_unit
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/raw_od_readingsget_od_raw_readings_per_unit
GET/api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/temperature_readingsget_temperature_readings_per_unit
PUT/api/workers/{pioreactor_unit}/is_activechange_worker_status
GET/api/workers/{pioreactor_unit}/jobs/descriptorsget_job_descriptors_for_worker
PATCH/api/workers/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}run_job_on_unit_in_experiment
POST/api/workers/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}run_job_on_unit_in_experiment
GET/api/workers/{pioreactor_unit}/jobs/runningget_jobs_running
GET/api/workers/{pioreactor_unit}/jobs/settings/job_name/{job_name}/experiments/{experiment}get_job_settings_for_worker
GET/api/workers/{pioreactor_unit}/jobs/settings/job_name/{job_name}/setting/{setting}/experiments/{experiment}get_job_setting_for_worker
PATCH/api/workers/{pioreactor_unit}/jobs/stop/experiments/{experiment}stop_all_jobs_on_unit_for_experiment
POST/api/workers/{pioreactor_unit}/jobs/stop/experiments/{experiment}stop_all_jobs_on_unit_for_experiment
PATCH/api/workers/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}stop_specific_job_on_unit
POST/api/workers/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}stop_specific_job_on_unit
PATCH/api/workers/{pioreactor_unit}/jobs/update/job_name/{job_name}/experiments/{experiment}update_job_on_unit
GET/api/workers/{pioreactor_unit}/modelget_worker_model_and_metadata
PUT/api/workers/{pioreactor_unit}/modelchange_worker_model
GET/api/workers/{pioreactor_unit}/zipped_calibrationsget_zipped_calibrations
DELETE/api/workers/assignmentsremove_all_workers_from_all_experiments
GET/api/workers/assignmentsget_workers_and_experiment_assignments
GET/api/workers/discoverdiscover_available_workers
POST/api/workers/setupsetup_worker_pioreactor

Get Automation Descriptors

Get Automation Descriptors endpoint.

Endpoint

GET /api/automations/descriptors/{automation_type}

Request

Path Parameters

NameTypeRequiredDescription
automation_typestringYesAutomation type, for example dosing, temperature, or led.

Response

Success

Status: 200 OK

Example body:

[
{
"display_name": "Only record temperature",
"automation_name": "only_record_temperature",
"description": "Apply no heating, only record the temperature.",
"source": null,
"fields": []
},
{
"display_name": "Thermostat",
"automation_name": "thermostat",
"description": "Vary the amount of applied heating to keep the culture near a target temperature, using a control-loop.",
"source": null,
"fields": [
{
"key": "target_temperature",
"default": 30,
"label": "Target temperature",
"disabled": false,
"unit": "\u2103",
"type": "numeric",
"options": null
}
]
}
]

Get Bioreactor Variable Descriptors

Get Bioreactor Variable Descriptors endpoint.

Endpoint

GET /api/bioreactor/descriptors

Response

Success

Status: 200 OK

Example body:

[
{
"key": "current_volume_ml",
"label": "Current volume",
"description": "Current estimated liquid volume in the vial.",
"type": "numeric",
"unit": "mL",
"min": 0.0,
"max": null
},
{
"key": "efflux_tube_volume_ml",
"label": "Efflux tube level",
"description": "Liquid volume equivalent to the height of the waste/efflux tube.",
"type": "numeric",
"unit": "mL",
"min": 0.0,
"max": null
},
{
"key": "alt_media_fraction",
"label": "Alt media fraction",
"description": "Fraction of the current volume estimated to be alt media.",
"type": "numeric",
"unit": null,
"min": 0.0,
"max": 1.0
}
]

Get Chart Descriptors

Get Chart Descriptors endpoint.

Endpoint

GET /api/charts/descriptors

Response

Success

Status: 200 OK

Example body:

[
{
"chart_key": "implied_growth_rate",
"data_source": "growth_rates",
"title": "Implied growth rate",
"source": "app",
"y_axis_label": "Growth rate, h\u207b\u00b9",
"fixed_decimals": 2,
"down_sample": true,
"mqtt_topic": "growth_rate_calculating/growth_rate",
"lookback": 100000,
"data_source_column": null,
"payload_key": "growth_rate",
"y_transformation": "(y) => y",
"y_axis_domain": [
-0.02,
0.1
],
"interpolation": "stepAfter"
},
{
"chart_key": "implied_daily_growth_rate",
"data_source": "growth_rates",
"title": "Implied daily growth rate",
"source": "app",
"y_axis_label": "Growth rate, d\u207b\u00b9",
"fixed_decimals": 2,
"down_sample": true,
"mqtt_topic": "growth_rate_calculating/growth_rate",
"lookback": 100000,
"data_source_column": null,
"payload_key": "growth_rate",
"y_transformation": "(y) => 24 * y",
"y_axis_domain": [
-0.1,
1.0
],
"interpolation": "stepAfter"
},
{
"chart_key": "fraction_of_volume_that_is_alternative_media",
"data_source": "alt_media_fractions",
"title": "Fraction of volume that is alternative media",
"source": "app",
"y_axis_label": "Fraction",
"fixed_decimals": 3,
"down_sample": false,
"mqtt_topic": "bioreactor/alt_media_fraction",
"lookback": 100000,
"data_source_column": "alt_media_fraction",
"payload_key": null,
"y_transformation": "(y) => y",
"y_axis_domain": [
0.0,
0.05
],
"interpolation": "stepAfter"
}
]

Get Shared Config

Get Shared Config endpoint.

Endpoint

GET /api/config/shared

Response

Success

Status: 200 OK

Response body is plain text.

Update Shared Config

Update Shared Config endpoint.

Endpoint

PATCH /api/config/shared

Request

Request Body

NameTypeRequiredDescription
codestringYescode.
{
"code": "[section]\nkey=value\n"
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Shared Config History

Get Shared Config History endpoint.

Endpoint

GET /api/config/shared/history

Response

Success

Status: 200 OK

Example body:

[
{
"filename": "config.ini",
"timestamp": "2026-02-19T15:56:45.596Z",
"data": "[PWM]\n# map the externals to the PWM\n# hardware PWM are available on channels 1 & 3.\n1=stirring\n2=waste\n3=media\n4=test\n5=heating\n\n\n[leds]\nA=IR\nB=white_light\nC=\nD=\n\n\n[bioreactor]\n# max_working_volume_ml is determined by the volume that just touches the outflow tube. I.e. if you\n# where to keep running the waste pump, what would the stable volume be.\n# see docs\nmax_working_volume_ml=14\ninitial_volume_ml=14\ninitial_alt_media_fraction=0.0\n\n\n[stirring.config]\ninitial_target_rpm=500\ninitial_duty_cycle...<truncated>"
},
{
"filename": "config.ini",
"timestamp": "2026-01-19T16:38:19.492Z",
"data": "[PWM]\n# map the externals to the PWM\n# hardware PWM are available on channels 1 & 3.\n1=stirring\n2=waste\n3=media\n4=alt_media\n5=heating\n\n\n[leds]\nA=IR\nB=white_light\nC=\nD=\n\n\n[bioreactor]\n# max_working_volume_ml is determined by the volume that just touches the outflow tube. I.e. if you\n# where to keep running the waste pump, what would the stable volume be.\n# see docs\nmax_working_volume_ml=14\ninitial_volume_ml=14\ninitial_alt_media_fraction=0.0\n\n\n[stirring.config]\ninitial_target_rpm=500\ninitial_duty_...<truncated>"
},
{
"filename": "config.ini",
"timestamp": "2026-01-15T01:12:24.848Z",
"data": "[PWM]\n# map the externals to the PWM\n# hardware PWM are available on channels 1 & 3.\n1=stirring\n2=waste\n3=media\n4=alt_media\n5=heatingf\n\n\n[leds]\nA=IR\nB=white_light\nC=\nD=\n\n\n[bioreactor]\n# max_working_volume_ml is determined by the volume that just touches the outflow tube. I.e. if you\n# where to keep running the waste pump, what would the stable volume be.\n# see docs\nmax_working_volume_ml=14\ninitial_volume_ml=14\ninitial_alt_media_fraction=0.0\n\n\n[stirring.config]\ninitial_target_rpm=500\ninitial_duty...<truncated>"
}
]

Get Config For Pioreactor Unit

get merged config for a pioreactor unit

Endpoint

GET /api/config/units/{pioreactor_unit}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

{
"localhost": {
"PWM": {
"1": "stirring",
"2": "waste",
"3": "media",
"4": "bubblert",
"5": "heating"
},
"leds": {
"A": "IR",
"B": "white_light",
"C": "",
"D": ""
},
"bioreactor": {
"efflux_tube_volume_ml": "14",
"initial_volume_ml": "14",
"initial_alt_media_fraction": "0.0"
},
"stirring.config": {
"initial_target_rpm": "500",
"initial_duty_cycle": "15",
"pwm_hz": "200",
"use_rpm": "True",
"duration_between_updates_seconds": "23",
"post_delay_duration": "0.25",
"pre_delay_duration": "0.25",
"enable_dodging_od": "true",
"target_rpm_during_od_reading": "0",
"target_rpm_outside_od_reading": "500"
},
"dosing_automation.turbidostat": {
"biomass_signal": "auto"
},
"stirring.pid": {
"Kp": "0.007",
"Ki": "0.0",
"Kd": "0.0"
},
"od_config.photodiode_channel": {
"1": "REF",
"2": "90"
},
"od_reading.config": {
"samples_per_second": "0.2",
"turn_off_leds_during_reading": "1",
"pd_reference_ema": "0.4",
"ir_led_intensity": "80",
"duration_between_led_off_and_od_reading": "0.1",
"smoothing_penalizer": "6.0",
"use_dark_offsets": "1"
},
"storage": {
"database": "/Users/camerondavidson-pilon/code/pioreactor/.pioreactor/storage/pioreactor.sqlite",
"temporary_cache": "/Users/camerondavidson-pilon/code/pioreactor/.pioreactor/storage/local_intermittent_pioreactor_metadata.sqlite",
"persistent_cache": "/Users/camerondavidson-pilon/code/pioreactor/.pioreactor/storage/local_persistent_pioreactor_metadata.sqlite",
"number_of_backup_replicates_to_workers": "0"
},
"logging": {
"log_file": "./pioreactor.log",
"ui_log_file": "./pioreactor.log",
"ui_log_level": "DEBUG",
"console_log_level": "DEBUG"
},
"cluster.topology": {
"leader_hostname": "localhost",
"leader_address": "localhost"
},
"ui.overview.settings": {
"filtered_od_lookback_minutes": "240",
"raw_od_lookback_minutes": "240",
"log_display_count": "65",
"time_display_mode": "hours"
},
"ui": {
"port": "4999",
"proto": "http"
},
"ui.overview.charts": {
"implied_growth_rate": "1",
"implied_daily_growth_rate": "0",
"fraction_of_volume_that_is_alternative_media": "1",
"normalized_optical_density": "1",
"raw_optical_density": "1",
"temperature": "1",
"optical_density": "1"
},
"ui.overview.cards": {
"dosings": "1",
"event_logs": "1",
"profiles": "1"
},
"dosing_automation.pid_morbidostat": {
"Kp": "5",
"Ki": "0",
"Kd": "0"
},
"temperature_automation.thermostat": {
"Kp": ".01",
"Ki": ".01",
"Kd": ".01"
},
"mqtt": {
"username": "pioreactor",
"password": "raspberry",
"broker_address": "localhost",
"broker_ws_port": "9001",
"broker_port": "1883",
"ws_protocol": "ws",
"use_tls": "0"
},
"dosing_automation.config": {
"pause_between_subdoses_seconds": "0.5",
"waste_removal_multiplier": "2.0",
"max_volume_to_warn": "17.0",
"max_volume_to_stop": "18.0",
"max_subdose": "1.0",
"experimental_pump_malfunction_tolerance": "0.2",
"experimental_detect_pump_malfunction": "False"
},
"growth_rate_calculating.config": {
"ekf_outlier_std_threshold": "3.0",
"samples_for_od_statistics": "10"
}
}
}

Get Specific Config For Pioreactor Unit

Get Specific Config For Pioreactor Unit endpoint.

Endpoint

GET /api/config/units/{pioreactor_unit}/specific

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Response body is plain text.

Update Specific Config For Pioreactor Unit

Update Specific Config For Pioreactor Unit endpoint.

Endpoint

PATCH /api/config/units/{pioreactor_unit}/specific

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Request Body

NameTypeRequiredDescription
codestringYescode.
{
"code": "[section]\nkey=value\n"
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Specific Config History For Pioreactor Unit

Get Specific Config History For Pioreactor Unit endpoint.

Endpoint

GET /api/config/units/{pioreactor_unit}/specific/history

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

[
{
"filename": "unit_config.ini::localhost",
"timestamp": "2026-04-08T00:58:21.686Z",
"data": "[PWM]\n# map the externals to the PWM\n# hardware PWM are available on channels 1 & 3.\n1=stirring\n2=waste\n3=media\n4=bubblert\n5=heating"
},
{
"filename": "unit_config.ini::localhost",
"timestamp": "2026-04-08T00:18:45.007Z",
"data": "[PWM]\n# map the externals to the PWM\n# hardware PWM are available on channels 1 & 3.\n1=stirring\n2=waste\n3=media\n4=bubbler\n5=heating"
},
{
"filename": "config_localhost.ini",
"timestamp": "2025-12-03T02:50:38.730Z",
"data": "[bioreactor]\nmax_volume_ml=30\n"
}
]

Get Exportable Datasets

Get Exportable Datasets endpoint.

Endpoint

GET /api/datasets/exportable

Response

Success

Status: 200 OK

Example body:

[
{
"dataset_name": "pioreactor_unit_activity_data",
"description": "This dataset includes most of your experiment data, including the time series of OD metrics, temperature, stirring rates, LED updates, and dosings.",
"display_name": "Pioreactor unit activity data (recommended)",
"has_experiment": true,
"has_unit": true,
"default_order_by": "timestamp",
"table": "pioreactor_unit_activity_data",
"query": null,
"source": "app",
"timestamp_columns": [
"timestamp"
],
"always_partition_by_unit": true
},
{
"dataset_name": "logs",
"description": "This dataset includes the append-only collection of logs from all Pioreactors. A subset of these logs are displayed in the Log Table in the Experiment Overview.",
"display_name": "Pioreactor logs",
"has_experiment": true,
"has_unit": true,
"default_order_by": "timestamp",
"table": "logs",
"query": null,
"source": "app",
"timestamp_columns": [
"timestamp"
],
"always_partition_by_unit": false
},
{
"dataset_name": "od_readings",
"description": "This dataset includes a time series of readings provided by the sensors (transformed via a calibration curve, if available), the inputs for growth calculations and normalized optical density.",
"display_name": "Optical density",
"has_experiment": true,
"has_unit": true,
"default_order_by": "timestamp",
"table": "od_readings",
"query": null,
"source": "app",
"timestamp_columns": [
"timestamp"
],
"always_partition_by_unit": false
}
]

Preview Exportable Dataset

Preview Exportable Dataset endpoint.

Endpoint

GET /api/datasets/exportable/{target_dataset}/preview

Request

Path Parameters

NameTypeRequiredDescription
target_datasetstringYesExportable dataset name.

Query Parameters

NameTypeRequiredDescription
n_rowsintegerNoMaximum number of preview rows. Defaults to 5.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Export Exportable Datasets

Export Exportable Datasets endpoint.

Endpoint

POST /api/datasets/exportable/export

Request

Request Body

NameTypeRequiredDescription
datasetsarrayYesdatasets.
experimentsarrayYesexperiments.
partition_by_experimentbooleanYespartition by experiment.
partition_by_unitbooleanYespartition by unit.
end_timestringNoend time.
start_timestringNostart time.
{
"datasets": [
"od_readings"
],
"experiments": [
"testing_experiment"
],
"partition_by_experiment": true,
"partition_by_unit": true,
"end_time": "2026-01-01T12:00:00Z",
"start_time": "2026-01-01T00:00:00Z"
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Experiment Profiles

Get Experiment Profiles endpoint.

Endpoint

GET /api/experiment_profiles

Response

Success

Status: 200 OK

Example body:

[
{
"experimentProfile": {
"experiment_profile_name": "Debug2",
"metadata": {
"author": "d",
"description": "d"
},
"plugins": [],
"common": {
"jobs": {}
},
"pioreactors": {
"localhost": {
"jobs": {
"circulate_alt_media": "<truncated>"
},
"label": null
}
},
"inputs": {}
},
"file": "from_forum.yaml",
"fullpath": "/Users/camerondavidson-pilon/code/pioreactor/.pioreactor/experiment_profiles/from_forum.yaml"
},
{
"experimentProfile": {
"experiment_profile_name": "invalid_demo",
"metadata": {
"author": null,
"description": null
},
"plugins": [],
"common": {
"jobs": {
"stirring": {
"actions": "<truncated>",
"description": "<truncated>"
}
}
},
"pioreactors": {},
"inputs": {}
},
"file": "efef.yaml",
"fullpath": "/Users/camerondavidson-pilon/code/pioreactor/.pioreactor/experiment_profiles/efef.yaml"
},
{
"experimentProfile": {
"experiment_profile_name": "fefesf",
"metadata": {
"author": null,
"description": null
},
"plugins": [],
"common": {
"jobs": {}
},
"pioreactors": {
"localhost": {
"jobs": {
"led_intensity": "<truncated>"
},
"label": null
}
},
"inputs": {}
},
"file": "sfeesf.yaml",
"fullpath": "/Users/camerondavidson-pilon/code/pioreactor/.pioreactor/experiment_profiles/sfeesf.yaml"
}
]

Create Experiment Profile

Create Experiment Profile endpoint.

Endpoint

POST /api/experiment_profiles

Request

Request Body

NameTypeRequiredDescription
bodystringYesbody.
filenamestringYesfilename.
{
"body": "Profile YAML or text content.",
"filename": "profile.yaml"
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Delete Experiment Profile

Delete Experiment Profile endpoint.

Endpoint

DELETE /api/experiment_profiles/{filename}

Request

Path Parameters

NameTypeRequiredDescription
filenamestringYesFilename.

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Experiment Profile

Get Experiment Profile endpoint.

Endpoint

GET /api/experiment_profiles/{filename}

Request

Path Parameters

NameTypeRequiredDescription
filenamestringYesFilename.

Response

Success

Status: 200 OK

Response body is plain text.

Update Experiment Profile

Update Experiment Profile endpoint.

Endpoint

PATCH /api/experiment_profiles/{filename}

Request

Path Parameters

NameTypeRequiredDescription
filenamestringYesFilename.

Request Body

NameTypeRequiredDescription
bodystringYesbody.
{
"body": "Profile YAML or text content."
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Experiments

Get Experiments endpoint.

Endpoint

GET /api/experiments

Response

Success

Status: 200 OK

Example body:

[
{
"experiment": "efaeffefe",
"created_at": "2026-04-13T15:47:38.212Z",
"description": "",
"delta_hours": 297.0,
"worker_count": 1,
"tags": [
"4324-2344",
"glp1"
]
},
{
"experiment": "efaef4e4",
"created_at": "2026-03-07T00:30:31.257Z",
"description": "eefefaefaefefefeefefefafafefef",
"delta_hours": 1201.0,
"worker_count": 0,
"tags": [
"pencil",
"notebook"
]
},
{
"experiment": "efaef4",
"created_at": "2026-02-06T01:19:11.315Z",
"description": "aefaef",
"delta_hours": 1896.0,
"worker_count": 0,
"tags": [
"pencil",
"notebook",
"4324-2344"
]
}
]

Create Experiment

Create Experiment endpoint.

Endpoint

POST /api/experiments

Request

Request Body

NameTypeRequiredDescription
experimentstringYesexperiment.
descriptionstringNodescription.
mediaUsedstringNomediaUsed.
organismUsedstringNoorganismUsed.
tagsarrayNotags.
{
"experiment": "testing_experiment",
"description": "Experiment notes.",
"mediaUsed": "LB",
"organismUsed": "example_organismUsed",
"tags": [
"screening"
]
}

Response

Success

Status: 201 Created

Example body:

{
"experiment": "testing_experiment",
"created_at": "2026-01-01T00:00:00Z",
"description": "Experiment notes.",
"delta_hours": 0,
"worker_count": 1,
"tags": [
"screening"
]
}

Delete Experiment

Delete Experiment endpoint.

Endpoint

DELETE /api/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Experiment

Get Experiment endpoint.

Endpoint

GET /api/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

{
"experiment": "efaeffefe",
"created_at": "2026-04-13T15:47:38.212Z",
"description": "",
"delta_hours": 297.0,
"worker_count": 1,
"tags": [
"4324-2344",
"glp1"
]
}

Update Experiment

Update Experiment endpoint.

Endpoint

PATCH /api/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
descriptionstringYesdescription.
tagsarrayYestags.
{
"description": "Experiment notes.",
"tags": [
"screening"
]
}

Response

Success

Status: 200 OK

Example body:

{
"experiment": "testing_experiment",
"created_at": "2026-01-01T00:00:00Z",
"description": "Experiment notes.",
"delta_hours": 0,
"worker_count": 1,
"tags": [
"screening"
]
}

Get Recent Experiment Profile Runs

Get Recent Experiment Profile Runs endpoint.

Endpoint

GET /api/experiments/{experiment}/experiment_profiles/recent

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

[]

Get Running Profiles

Get Running Profiles endpoint.

Endpoint

GET /api/experiments/{experiment}/experiment_profiles/running

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

[]

Get List Of Historical Workers For Experiment

Get List Of Historical Workers For Experiment endpoint.

Endpoint

GET /api/experiments/{experiment}/historical_worker_assignments

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

[
{
"pioreactor_unit": "localhost",
"experiment": "efaeffefe",
"is_currently_assigned_to_experiment": 1
},
{
"pioreactor_unit": "missing",
"experiment": "efaeffefe",
"is_currently_assigned_to_experiment": 0
},
{
"pioreactor_unit": "pio01",
"experiment": "efaeffefe",
"is_currently_assigned_to_experiment": 0
}
]

Get Exp Logs

Shows event logs from all units, uses pagination.

Endpoint

GET /api/experiments/{experiment}/logs

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.
skipstringNoskip.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Get Media Rates

Shows amount of added media per unit. Note that it only consider values from a dosing automation (i.e. not manual dosing, which includes continously dose)

Endpoint

GET /api/experiments/{experiment}/media_rates

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

{
"all": {
"altMediaRate": 0.0,
"mediaRate": 0.0
}
}

Get Recent Logs

Shows recent event logs from all units

Endpoint

GET /api/experiments/{experiment}/recent_logs

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Get Fallback Time Series

Get Fallback Time Series endpoint.

Endpoint

GET /api/experiments/{experiment}/time_series/{data_source}/{column}

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.
data_sourcestringYesTime-series data source name.
columnstringYesDataset column name.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Growth Rates

Gets growth rates for all units

Endpoint

GET /api/experiments/{experiment}/time_series/growth_rates

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Readings

Gets raw od for all units

Endpoint

GET /api/experiments/{experiment}/time_series/od_readings

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Readings Filtered

Gets normalized od for all units

Endpoint

GET /api/experiments/{experiment}/time_series/od_readings_filtered

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Readings Fused

Get Od Readings Fused endpoint.

Endpoint

GET /api/experiments/{experiment}/time_series/od_readings_fused

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Raw Readings

Gets raw od for all units

Endpoint

GET /api/experiments/{experiment}/time_series/raw_od_readings

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Temperature Readings

Gets temperature readings for all units

Endpoint

GET /api/experiments/{experiment}/time_series/temperature_readings

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Unit Labels

Get Unit Labels endpoint.

Endpoint

GET /api/experiments/{experiment}/unit_labels

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

{}

Upsert Unit Labels

Update or insert a new unit label for the current experiment.

Endpoint

PATCH /api/experiments/{experiment}/unit_labels

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
labelstringYeslabel.
unitstringYesunit.
{
"label": "Control",
"unit": "example_unit"
}

Response

Success

Status: 201 Created

Example body:

{
"status": "success"
}

Upsert Unit Labels

Update or insert a new unit label for the current experiment.

Endpoint

PUT /api/experiments/{experiment}/unit_labels

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
labelstringYeslabel.
unitstringYesunit.
{
"label": "Control",
"unit": "example_unit"
}

Response

Success

Status: 201 Created

Example body:

{
"status": "success"
}

Remove Workers From Experiment

Remove Workers From Experiment endpoint.

Endpoint

DELETE /api/experiments/{experiment}/workers

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get List Of Workers For Experiment

Get List Of Workers For Experiment endpoint.

Endpoint

GET /api/experiments/{experiment}/workers

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Response

Success

Status: 200 OK

Example body:

[
{
"pioreactor_unit": "localhost",
"is_active": 1,
"model_name": "pioreactor_40ml",
"model_version": "1.5"
}
]

Add Worker To Experiment

Add Worker To Experiment endpoint.

Endpoint

PUT /api/experiments/{experiment}/workers

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
pioreactor_unitstringYespioreactor unit.
{
"pioreactor_unit": "pio02"
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Remove Worker From Experiment

Remove Worker From Experiment endpoint.

Endpoint

DELETE /api/experiments/{experiment}/workers/{pioreactor_unit}

Request

Path Parameters

NameTypeRequiredDescription
experimentstringYesExperiment identifier.
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Active Experiments

Get list of experiments with at least one active worker assigned

Endpoint

GET /api/experiments/active

Response

Success

Status: 200 OK

Example body:

[
{
"experiment": "efaeffefe",
"created_at": "2026-04-13T15:47:38.212Z",
"description": "",
"delta_hours": 297.0,
"worker_count": 1,
"tags": [
"4324-2344",
"glp1"
]
}
]

Get Experiments Worker Assignments

Get Experiments Worker Assignments endpoint.

Endpoint

GET /api/experiments/assignment_count

Response

Success

Status: 200 OK

Example body:

[
{
"experiment": "efaeffefe",
"worker_count": 1
}
]

Get Latest Experiment

Get Latest Experiment endpoint.

Endpoint

GET /api/experiments/latest

Response

Success

Status: 200 OK

Example body:

{
"experiment": "efaeffefe",
"created_at": "2026-04-13T15:47:38.212Z",
"description": "",
"delta_hours": 297.0,
"worker_count": 1,
"tags": [
"4324-2344",
"glp1"
]
}

Get Historical Media Used

Get Historical Media Used endpoint.

Endpoint

GET /api/historical_media

Response

Success

Status: 200 OK

Example body:

[
{
"key": "DM-Glc %0.1"
},
{
"key": "MOPS 0.03% glc, 0.3% glycerol"
},
{
"key": "MOPS 0.2% glc"
}
]

Get Historical Organisms Used

Get Historical Organisms Used endpoint.

Endpoint

GET /api/historical_organisms

Response

Success

Status: 200 OK

Example body:

[
{
"key": "MG1655/NCM3270/W3110/REL606"
},
{
"key": "REL606"
},
{
"key": "REL606 \u2206pykF"
}
]

Get Job Descriptors

Get Job Descriptors endpoint.

Endpoint

GET /api/jobs/descriptors

Response

Success

Status: 200 OK

Example body:

[
{
"display_name": "Stirring",
"job_name": "stirring",
"display": true,
"published_settings": [
{
"key": "target_rpm",
"type": "numeric",
"display": true,
"description": "Modify the target RPM of stirring. This will effect the optical density reading. Too low and the stirring may completely stop. Too high and the resulting vortex may interfere with the optics.",
"default": null,
"unit": "RPM",
"label": "Target stir RPM",
"editable": true
}
],
"source": "app",
"description": "Start the stirring on the Pioreactor. Stirring is needed for mixing and proper OD measurements.",
"subtext": null,
"is_testing": false
},
{
"display_name": "Optical density",
"job_name": "od_reading",
"display": true,
"published_settings": [],
"source": "app",
"description": "Collect optical density measurements of the culture over time.",
"subtext": null,
"is_testing": false
},
{
"display_name": "Growth rate",
"job_name": "growth_rate_calculating",
"display": true,
"published_settings": [],
"source": "app",
"description": "Transform optical density measurements into culture growth rate measurements. Start this after innoculation. Begins by sampling for a few minutes to gather a baseline.",
"subtext": null,
"is_testing": false
}
]

Get Local Access Point

Get Local Access Point endpoint.

Endpoint

GET /api/local_access_point

Response

Success

Status: 200 OK

Example body:

{
"active": false
}

Get Logs

Shows event logs from all units, uses pagination.

Endpoint

GET /api/logs

Request

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.
skipstringNoskip.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Get Models

Return the list of supported Pioreactor models (name, version, display_name).

Endpoint

GET /api/models

Response

Success

Status: 200 OK

Example body:

{
"models": [
{
"model_name": "pioreactor_40ml",
"model_version": "1.5",
"display_name": "Pioreactor 40ml, v1.5",
"reactor_capacity_ml": 40.0,
"reactor_diameter_mm": 27.0,
"reactor_max_fill_volume_ml": 38.0,
"max_temp_to_reduce_heating": 78.0,
"max_temp_to_disable_heating": 80.0,
"max_temp_to_shutdown": 85.0,
"is_legacy": false,
"is_contrib": false
},
{
"model_name": "pioreactor_40ml",
"model_version": "1.0",
"display_name": "Pioreactor 40ml, v1.0",
"reactor_capacity_ml": 40.0,
"reactor_diameter_mm": 27.0,
"reactor_max_fill_volume_ml": 38.0,
"max_temp_to_reduce_heating": 78.0,
"max_temp_to_disable_heating": 80.0,
"max_temp_to_shutdown": 85.0,
"is_legacy": true,
"is_contrib": false
},
{
"model_name": "pioreactor_20ml",
"model_version": "1.1",
"display_name": "Pioreactor 20ml, v1.1",
"reactor_capacity_ml": 20.0,
"reactor_diameter_mm": 27.0,
"reactor_max_fill_volume_ml": 18.0,
"max_temp_to_reduce_heating": 78.0,
"max_temp_to_disable_heating": 80.0,
"max_temp_to_shutdown": 85.0,
"is_legacy": true,
"is_contrib": false
}
]
}

Update App From Release Archive

Update App From Release Archive endpoint.

Endpoint

POST /api/system/update_from_archive

Request

Request Body

NameTypeRequiredDescription
release_archive_locationstringYesrelease archive location.
unitsarrayYesunits.
{
"release_archive_location": "/tmp/release.zip",
"units": [
"pio01"
]
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Update App

Update App endpoint.

Endpoint

POST /api/system/update_next_version

Request

Request Body

NameTypeRequiredDescription
unitsarrayNounits.
{
"units": [
"pio01"
]
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Upload System File

Upload System File endpoint.

Endpoint

POST /api/system/upload

Response

Success

Status: 201 Created

Example body:

{
"message": "File successfully uploaded",
"save_path": "/tmp/file.zip"
}

Set System Utc Clock

Set System Utc Clock endpoint.

Endpoint

POST /api/system/utc_clock

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get List Of Units

Get List Of Units endpoint.

Endpoint

GET /api/units

Response

Success

Status: 200 OK

Example body:

[
{
"pioreactor_unit": "localhost"
},
{
"pioreactor_unit": "unit01"
}
]

Get Capabilities

Get Capabilities endpoint.

Endpoint

GET /api/units/{pioreactor_unit}/capabilities

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "d32e292b-ff2d-4086-82ea-f73fb94d6431",
"result_url_path": "/unit_api/task_results/d32e292b-ff2d-4086-82ea-f73fb94d6431"
}

Publish New Log

Publish New Log endpoint.

Endpoint

POST /api/units/{pioreactor_unit}/experiments/{experiment}/logs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
levelstringYeslevel.
messagestringYesmessage.
sourcestringYessource.
taskstringYestask.
timestampstringYestimestamp.
source_stringNosource .
{
"level": "INFO",
"message": "Log message.",
"source": "api",
"task": "stirring",
"timestamp": "2026-01-01T00:00:00Z",
"source_": "api"
}

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Import Dot Pioreactor Archive

Import Dot Pioreactor Archive endpoint.

Endpoint

POST /api/units/{pioreactor_unit}/import_zipped_dot_pioreactor

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 201 Created

Response body is binary file data.

Run Job On Unit In Experiment

Runs specified job on unit.

Endpoint

PATCH /api/units/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
argsarrayNoargs.
config_overridesarrayNoconfig overrides.
envobjectNoenv.
optionsobjectNooptions.
{
"options": {
"target_rpm": "200"
},
"env": {
"JOB_SOURCE": "api"
},
"args": [
"some-flag"
],
"config_overrides": [
[
"stirring.config",
"pwm_hz",
"100"
]
]
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Run Job On Unit In Experiment

Runs specified job on unit.

Endpoint

POST /api/units/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
argsarrayNoargs.
config_overridesarrayNoconfig overrides.
envobjectNoenv.
optionsobjectNooptions.
{
"options": {
"target_rpm": "200"
},
"env": {
"JOB_SOURCE": "api"
},
"args": [
"some-flag"
],
"config_overrides": [
[
"stirring.config",
"pwm_hz",
"100"
]
]
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Jobs Running

Get Jobs Running endpoint.

Endpoint

GET /api/units/{pioreactor_unit}/jobs/running

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "fcadaa88-c287-4f8f-a5b3-86a69e5f91d6",
"result_url_path": "/unit_api/task_results/fcadaa88-c287-4f8f-a5b3-86a69e5f91d6"
}

Stop All Jobs On Unit For Experiment

Kills all jobs for worker or unit assigned to experiment

Endpoint

PATCH /api/units/{pioreactor_unit}/jobs/stop/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Stop All Jobs On Unit For Experiment

Kills all jobs for worker or unit assigned to experiment

Endpoint

POST /api/units/{pioreactor_unit}/jobs/stop/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Stop Specific Job On Unit

Kills specified job on unit

Endpoint

PATCH /api/units/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Stop Specific Job On Unit

Kills specified job on unit

Endpoint

POST /api/units/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Update Job On Unit

Update specified job on unit. Use $broadcast for everyone.

Endpoint

PATCH /api/units/{pioreactor_unit}/jobs/update/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
settingsobjectYessettings.
{
"settings": {
"target_rpm": "200"
}
}

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Get Logs For Unit

Shows event logs from all units, uses pagination.

Endpoint

GET /api/units/{pioreactor_unit}/logs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.
skipstringNoskip.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Install Plugin Across Cluster

Install Plugin Across Cluster endpoint.

Endpoint

PATCH /api/units/{pioreactor_unit}/plugins/install

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Install Plugin Across Cluster

Install Plugin Across Cluster endpoint.

Endpoint

POST /api/units/{pioreactor_unit}/plugins/install

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Plugins On Machine

Get Plugins On Machine endpoint.

Endpoint

GET /api/units/{pioreactor_unit}/plugins/installed

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "d3dc87b6-6a0a-4a45-a9a1-d472e6c0c9a9",
"result_url_path": "/unit_api/task_results/d3dc87b6-6a0a-4a45-a9a1-d472e6c0c9a9"
}

Uninstall Plugin Across Cluster

Uninstall Plugin Across Cluster endpoint.

Endpoint

PATCH /api/units/{pioreactor_unit}/plugins/uninstall

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Uninstall Plugin Across Cluster

Uninstall Plugin Across Cluster endpoint.

Endpoint

POST /api/units/{pioreactor_unit}/plugins/uninstall

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Reboot Unit

Reboots unit

Endpoint

POST /api/units/{pioreactor_unit}/system/reboot

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 201 Created

No success response body.

Shutdown Unit

Shutdown unit

Endpoint

POST /api/units/{pioreactor_unit}/system/shutdown

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 201 Created

No success response body.

Get Unit Utc Clock

Get Unit Utc Clock endpoint.

Endpoint

GET /api/units/{pioreactor_unit}/system/utc_clock

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "da0dc23d-00c3-439d-877a-d0ba10e642b2",
"result_url_path": "/unit_api/task_results/da0dc23d-00c3-439d-877a-d0ba10e642b2"
}

Get System Logs For Unit

Shows system logs from specific unit uses pagination.

Endpoint

GET /api/units/{pioreactor_unit}/system_logs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.
skipstringNoskip.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Get App Versions

Get App Versions endpoint.

Endpoint

GET /api/units/{pioreactor_unit}/versions/app

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "7305efc4-ae79-45b0-b278-d0f559332c92",
"result_url_path": "/unit_api/task_results/7305efc4-ae79-45b0-b278-d0f559332c92"
}

Get Zipped Dot Pioreactor

Download a ZIP of ~/.pioreactor from one or all workers.

Endpoint

GET /api/units/{pioreactor_unit}/zipped_dot_pioreactor

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Response body is binary file data.

Get List Of Workers

Get List Of Workers endpoint.

Endpoint

GET /api/workers

Response

Success

Status: 200 OK

Example body:

[
{
"pioreactor_unit": "localhost",
"added_at": "2025-10-03T14:12:44.444Z",
"is_active": 1,
"model_name": "pioreactor_40ml",
"model_version": "1.5"
},
{
"pioreactor_unit": "unit01",
"added_at": "2026-04-23T00:31:23.936Z",
"is_active": 1,
"model_name": "pioreactor_40ml",
"model_version": "1.5"
}
]

Add Worker

Add Worker endpoint.

Endpoint

PUT /api/workers

Request

Request Body

NameTypeRequiredDescription
pioreactor_unitstringYespioreactor unit.
model_namestringNomodel name.
model_versionstringNomodel version.
{
"pioreactor_unit": "pio02",
"model_name": "pioreactor_40ml",
"model_version": "1.5"
}

Response

Success

Status: 201 Created

Example body:

{
"status": "success"
}

Delete Worker

Delete Worker endpoint.

Endpoint

DELETE /api/workers/{pioreactor_unit}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Get Worker

Get Worker endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

{
"pioreactor_unit": "localhost",
"added_at": "2025-10-03T14:12:44.444Z",
"is_active": 1,
"model_name": "pioreactor_40ml",
"model_version": "1.5"
}

Get All Active Calibrations

Get All Active Calibrations endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/active_calibrations

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "7270e89b-0fda-46b2-af6f-97d4a6b5ce32",
"result_url_path": "/unit_api/task_results/7270e89b-0fda-46b2-af6f-97d4a6b5ce32"
}

Remove Active Status Calibration

Remove Active Status Calibration endpoint.

Endpoint

DELETE /api/workers/{pioreactor_unit}/active_calibrations/{device}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Set Active Calibration

Set Active Calibration endpoint.

Endpoint

PATCH /api/workers/{pioreactor_unit}/active_calibrations/{device}/{calibration_name}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.
calibration_namestringYesCalibration name.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get All Active Estimators

Get All Active Estimators endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/active_estimators

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "cad9a1a8-c46d-4f86-b29e-b597c6a6dc80",
"result_url_path": "/unit_api/task_results/cad9a1a8-c46d-4f86-b29e-b597c6a6dc80"
}

Remove Active Status Estimator

Remove Active Status Estimator endpoint.

Endpoint

DELETE /api/workers/{pioreactor_unit}/active_estimators/{device}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Set Active Estimator

Set Active Estimator endpoint.

Endpoint

PATCH /api/workers/{pioreactor_unit}/active_estimators/{device}/{estimator_name}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.
estimator_namestringYesEstimator name.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Automation Descriptors For Worker

Get Automation Descriptors For Worker endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/automations/descriptors/{automation_type}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
automation_typestringYesAutomation type, for example dosing, temperature, or led.

Response

Success

Status: 200 OK

Example body:

[
{
"display_name": "Only record temperature",
"automation_name": "only_record_temperature",
"description": "Apply no heating, only record the temperature.",
"source": null,
"fields": []
},
{
"display_name": "Thermostat",
"automation_name": "thermostat",
"description": "Vary the amount of applied heating to keep the culture near a target temperature, using a control-loop.",
"source": null,
"fields": [
{
"key": "target_temperature",
"default": 30,
"label": "Target temperature",
"disabled": false,
"unit": "\u2103",
"type": "numeric",
"options": null
}
]
}
]

Update Bioreactor On Unit

Update Bioreactor On Unit endpoint.

Endpoint

PATCH /api/workers/{pioreactor_unit}/bioreactor/update/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
valuesobjectYesvalues.
{
"values": {
"current_volume_ml": 12.5
}
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Blink Worker endpoint.

Endpoint

POST /api/workers/{pioreactor_unit}/blink

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Get Calibration Protocols

Get Calibration Protocols endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/calibration_protocols

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "a5cac5e3-60aa-428a-b6fc-cde64f140e9a",
"result_url_path": "/unit_api/task_results/a5cac5e3-60aa-428a-b6fc-cde64f140e9a"
}

Get All Calibrations

Get All Calibrations endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/calibrations

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "b33bc95e-3abf-42e5-866d-d4569107d649",
"result_url_path": "/unit_api/task_results/b33bc95e-3abf-42e5-866d-d4569107d649"
}

Get Calibrations

Get Calibrations endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/calibrations/{device}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "098b85e4-e7b1-4d8f-89a3-d3be905f9ad0",
"result_url_path": "/unit_api/task_results/098b85e4-e7b1-4d8f-89a3-d3be905f9ad0"
}

Create Calibration

Create Calibration endpoint.

Endpoint

POST /api/workers/{pioreactor_unit}/calibrations/{device}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.

Request Body

NameTypeRequiredDescription
calibration_dataobjectYescalibration data.
set_as_activebooleanYesset as active.
{
"calibration_data": {
"calibration_name": "example_calibration"
},
"set_as_active": true
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Delete Calibration

Delete Calibration endpoint.

Endpoint

DELETE /api/workers/{pioreactor_unit}/calibrations/{device}/{calibration_name}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.
calibration_namestringYesCalibration name.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Calibration

Get Calibration endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/calibrations/{device}/{calibration_name}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.
calibration_namestringYesCalibration name.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "5029d03a-5419-48f5-89fc-3e03b2f8e8b6",
"result_url_path": "/unit_api/task_results/5029d03a-5419-48f5-89fc-3e03b2f8e8b6"
}

Start Calibration Session

Start Calibration Session endpoint.

Endpoint

POST /api/workers/{pioreactor_unit}/calibrations/sessions

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 201 Created

No success response body.

Get Calibration Session

Get Calibration Session endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/calibrations/sessions/{session_id}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
session_idstringYesCalibration session identifier.

Response

Success

Status: 200 OK

No success response body.

Abort Calibration Session

Abort Calibration Session endpoint.

Endpoint

POST /api/workers/{pioreactor_unit}/calibrations/sessions/{session_id}/abort

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
session_idstringYesCalibration session identifier.

Response

Success

Status: 201 Created

No success response body.

Advance Calibration Session

Advance Calibration Session endpoint.

Endpoint

POST /api/workers/{pioreactor_unit}/calibrations/sessions/{session_id}/inputs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
session_idstringYesCalibration session identifier.

Response

Success

Status: 201 Created

No success response body.

Get Capabilities

Get Capabilities endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/capabilities

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "85e0664d-6b2b-4590-a338-5487ccd97da8",
"result_url_path": "/unit_api/task_results/85e0664d-6b2b-4590-a338-5487ccd97da8"
}

Get All Estimators

Get All Estimators endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/estimators

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "700978c5-7730-49e7-8e70-520caaf6f0fe",
"result_url_path": "/unit_api/task_results/700978c5-7730-49e7-8e70-520caaf6f0fe"
}

Get Estimators By Device

Get Estimators By Device endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/estimators/{device}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "532485d5-6130-485c-8b5e-2bedf3e8db08",
"result_url_path": "/unit_api/task_results/532485d5-6130-485c-8b5e-2bedf3e8db08"
}

Delete Estimator

Delete Estimator endpoint.

Endpoint

DELETE /api/workers/{pioreactor_unit}/estimators/{device}/{estimator_name}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.
estimator_namestringYesEstimator name.

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Estimator

Get Estimator endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/estimators/{device}/{estimator_name}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
devicestringYesTarget device name.
estimator_namestringYesEstimator name.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "47af3277-2692-4f05-b3cb-469ca6f23ffe",
"result_url_path": "/unit_api/task_results/47af3277-2692-4f05-b3cb-469ca6f23ffe"
}

Get Experiment Assignment For Worker

Get Experiment Assignment For Worker endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiment

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

{
"pioreactor_unit": "localhost",
"is_active": 1,
"experiment": "efaeffefe",
"model_name": "pioreactor_40ml",
"model_version": "1.5"
}

Get Logs For Unit And Experiment

Shows event logs from specific unit and experiment, uses pagination.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/logs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.
skipstringNoskip.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Publish New Log

Publish New Log endpoint.

Endpoint

POST /api/workers/{pioreactor_unit}/experiments/{experiment}/logs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
levelstringYeslevel.
messagestringYesmessage.
sourcestringYessource.
taskstringYestask.
timestampstringYestimestamp.
source_stringNosource .
{
"level": "INFO",
"message": "Log message.",
"source": "api",
"task": "stirring",
"timestamp": "2026-01-01T00:00:00Z",
"source_": "api"
}

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Get Recent Logs For Unit And Experiment

Shows event logs for a specific unit within an experiment. This is for the single-page Pioreactor ui

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/recent_logs

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
min_levelstringNomin level.

Response

Success

Status: 200 OK

Example body:

[
{
"timestamp": "2026-01-01T00:00:00Z",
"level": "INFO",
"message": "Log message.",
"task": "stirring",
"source": "app",
"pioreactor_unit": "pio01",
"experiment": "testing_experiment"
}
]

Get Fallback Time Series Per Unit

Get Fallback Time Series Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/{data_source}/{column}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.
data_sourcestringYesTime-series data source name.
columnstringYesDataset column name.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Growth Rates Per Unit

Get Growth Rates Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/growth_rates

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Readings Per Unit

Get Od Readings Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/od_readings

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Readings Filtered Per Unit

Get Od Readings Filtered Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/od_readings_filtered

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Readings Fused Per Unit

Get Od Readings Fused Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/od_readings_fused

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Od Raw Readings Per Unit

Get Od Raw Readings Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/raw_od_readings

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Get Temperature Readings Per Unit

Get Temperature Readings Per Unit endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/experiments/{experiment}/time_series/temperature_readings

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Query Parameters

NameTypeRequiredDescription
lookbacknumberNoLookback window in hours. Defaults to 4.0.
target_pointsintegerNoApproximate maximum points per series. Defaults to 720 and must be greater than 0.

Response

Success

Status: 200 OK

Body shape: series is a list of series labels. data is a parallel list of point arrays, so data[i] contains the points for series[i]. Each point has x as an ISO-8601 UTC timestamp string and y as a number.

Example body:

{
"series": [
"pio01",
"pio02"
],
"data": [
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.01234
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.0125
}
],
[
{
"x": "2026-01-01T00:00:00.000Z",
"y": 0.00987
},
{
"x": "2026-01-01T00:01:00.000Z",
"y": 0.01001
}
]
]
}

Change Worker Status

Change Worker Status endpoint.

Endpoint

PUT /api/workers/{pioreactor_unit}/is_active

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Request Body

NameTypeRequiredDescription
is_activebooleanNois active.
{
"is_active": true
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Job Descriptors For Worker

Get Job Descriptors For Worker endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/jobs/descriptors

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

[
{
"display_name": "Stirring",
"job_name": "stirring",
"display": true,
"published_settings": [
{
"key": "target_rpm",
"type": "numeric",
"display": true,
"description": "Modify the target RPM of stirring. This will effect the optical density reading. Too low and the stirring may completely stop. Too high and the resulting vortex may interfere with the optics.",
"default": null,
"unit": "RPM",
"label": "Target stir RPM",
"editable": true
}
],
"source": "app",
"description": "Start the stirring on the Pioreactor. Stirring is needed for mixing and proper OD measurements.",
"subtext": null,
"is_testing": false
},
{
"display_name": "Optical density",
"job_name": "od_reading",
"display": true,
"published_settings": [],
"source": "app",
"description": "Collect optical density measurements of the culture over time.",
"subtext": null,
"is_testing": false
},
{
"display_name": "Growth rate",
"job_name": "growth_rate_calculating",
"display": true,
"published_settings": [],
"source": "app",
"description": "Transform optical density measurements into culture growth rate measurements. Start this after innoculation. Begins by sampling for a few minutes to gather a baseline.",
"subtext": null,
"is_testing": false
}
]

Run Job On Unit In Experiment

Runs specified job on unit.

Endpoint

PATCH /api/workers/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
argsarrayNoargs.
config_overridesarrayNoconfig overrides.
envobjectNoenv.
optionsobjectNooptions.
{
"options": {
"target_rpm": "200"
},
"env": {
"JOB_SOURCE": "api"
},
"args": [
"some-flag"
],
"config_overrides": [
[
"stirring.config",
"pwm_hz",
"100"
]
]
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Run Job On Unit In Experiment

Runs specified job on unit.

Endpoint

POST /api/workers/{pioreactor_unit}/jobs/run/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
argsarrayNoargs.
config_overridesarrayNoconfig overrides.
envobjectNoenv.
optionsobjectNooptions.
{
"options": {
"target_rpm": "200"
},
"env": {
"JOB_SOURCE": "api"
},
"args": [
"some-flag"
],
"config_overrides": [
[
"stirring.config",
"pwm_hz",
"100"
]
]
}

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Jobs Running

Get Jobs Running endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/jobs/running

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "094009e4-64cf-482e-965a-0f2024b7a1ed",
"result_url_path": "/unit_api/task_results/094009e4-64cf-482e-965a-0f2024b7a1ed"
}

Get Job Settings For Worker

Get Job Settings For Worker endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/jobs/settings/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "09ced173-624b-4c62-b7ac-56eb4835ae6d",
"result_url_path": "/unit_api/task_results/09ced173-624b-4c62-b7ac-56eb4835ae6d"
}

Get Job Setting For Worker

Get Job Setting For Worker endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/jobs/settings/job_name/{job_name}/setting/{setting}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
settingstringYesJob setting name.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"unit": "localhost",
"task_id": "1d7d71c8-eddb-41ef-ad52-b1a4d5dd99d2",
"result_url_path": "/unit_api/task_results/1d7d71c8-eddb-41ef-ad52-b1a4d5dd99d2"
}

Stop All Jobs On Unit For Experiment

Kills all jobs for worker or unit assigned to experiment

Endpoint

PATCH /api/workers/{pioreactor_unit}/jobs/stop/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Stop All Jobs On Unit For Experiment

Kills all jobs for worker or unit assigned to experiment

Endpoint

POST /api/workers/{pioreactor_unit}/jobs/stop/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Stop Specific Job On Unit

Kills specified job on unit

Endpoint

PATCH /api/workers/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Stop Specific Job On Unit

Kills specified job on unit

Endpoint

POST /api/workers/{pioreactor_unit}/jobs/stop/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Update Job On Unit

Update specified job on unit. Use $broadcast for everyone.

Endpoint

PATCH /api/workers/{pioreactor_unit}/jobs/update/job_name/{job_name}/experiments/{experiment}

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.
job_namestringYesJob name.
experimentstringYesExperiment identifier.

Request Body

NameTypeRequiredDescription
settingsobjectYessettings.
{
"settings": {
"target_rpm": "200"
}
}

Response

Success

Status: 202 Accepted

Example body:

{
"status": "success"
}

Get Worker Model And Metadata

Get Worker Model And Metadata endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/model

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Example body:

{
"pioreactor_unit": "localhost",
"model_name": "pioreactor_40ml",
"model_version": "1.5",
"display_name": "Pioreactor 40ml, v1.5",
"reactor_capacity_ml": 40.0,
"reactor_diameter_mm": 27.0,
"reactor_max_fill_volume_ml": 38.0,
"max_temp_to_reduce_heating": 78.0,
"max_temp_to_disable_heating": 80.0,
"max_temp_to_shutdown": 85.0,
"is_legacy": false,
"is_contrib": false
}

Change Worker Model

Change Worker Model endpoint.

Endpoint

PUT /api/workers/{pioreactor_unit}/model

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Request Body

NameTypeRequiredDescription
model_namestringYesmodel name.
model_versionstringYesmodel version.
{
"model_name": "pioreactor_40ml",
"model_version": "1.5"
}

Response

Success

Status: 200 OK

Example body:

{
"status": "success"
}

Get Zipped Calibrations

Get Zipped Calibrations endpoint.

Endpoint

GET /api/workers/{pioreactor_unit}/zipped_calibrations

Request

Path Parameters

NameTypeRequiredDescription
pioreactor_unitstringYesUnit name or $broadcast where supported.

Response

Success

Status: 200 OK

Response body is binary file data.

Remove All Workers From All Experiments

Remove All Workers From All Experiments endpoint.

Endpoint

DELETE /api/workers/assignments

Response

Success

Status: 202 Accepted

Example body:

{
"task_id": "abcd1234",
"result_url_path": "/unit_api/task_results/abcd1234"
}

Get Workers And Experiment Assignments

Get Workers And Experiment Assignments endpoint.

Endpoint

GET /api/workers/assignments

Response

Success

Status: 200 OK

Example body:

[
{
"pioreactor_unit": "localhost",
"experiment": "efaeffefe",
"is_active": 1
},
{
"pioreactor_unit": "unit01",
"experiment": null,
"is_active": 1
}
]

Discover Available Workers

Discover available pioreactor workers on the network not already registered.

Endpoint

GET /api/workers/discover

Response

Success

Status: 200 OK

Example body:

[]

Setup Worker Pioreactor

Setup Worker Pioreactor endpoint.

Endpoint

POST /api/workers/setup

Request

Request Body

NameTypeRequiredDescription
modelstringYesmodel.
namestringYesname.
versionstringYesversion.
{
"model": "example_model",
"name": "testing_experiment",
"version": "example_version"
}

Response

Success

Status: 200 OK

Example body:

{
"msg": "Worker pio02 added successfully."
}