---
title: "Update a planned measurement"
method: PATCH
path: "/projects/{project_id}/planned_measurements/{planned_measurement_id}"
tags: ["Planned Measurements"]
---

# Update a planned measurement

`PATCH /projects/{project_id}/planned_measurements/{planned_measurement_id}`

Patch a planned measurement.

## Path parameters

- `project_id` string, required
- `planned_measurement_id` string, required

## Request body

- UpdatePlannedMeasurement — Request model for patching a planned measurement. ``set_temperature_c`` and ``thermal_chamber_id`` must end up either both set or both unset, but this model cannot check that alone: a body sending only one of them has nothing to compare against, and the other may already be stored. The service validates the *merged* result against the stored row, and the database CHECK backstops it — the same split used for the thermal chamber's min/max envelope.
  - `name` string, nullable
  - `status` 'requested' | 'scheduled' | 'in_progress' | 'completed' | 'cancelled' — Lifecycle state for a planned measurement.
  - `cell_specification_id` string, nullable
  - `cell_instance_id` string, nullable
  - `channel_id` string, nullable
  - `set_temperature_c` number, nullable
  - `thermal_chamber_id` string, nullable
  - `protocol_id` string, nullable
  - `program_id` string, nullable
  - `test_setup` object, nullable
  - `planned_start_time` string, date-time, nullable
  - `planned_end_time` string, date-time, nullable
  - `estimated_duration_seconds` integer, nullable
  - `setup_duration_seconds` integer, nullable
  - `teardown_duration_seconds` integer, nullable
  - `started_measurement_id` string, nullable
  - `notes` string, nullable

## Response `200`

Successful Response

- PlannedMeasurement — A planned measurement row returned by the API.
  - `name` string, required
  - `cell_specification_id` string, nullable — Cell specification the requester wants tested (set at request time).
  - `cell_instance_id` string, nullable — Cell instance this future measurement will run on.
  - `channel_id` string, nullable — Channel reserved for this measurement, once scheduled.
  - `set_temperature_c` number, nullable — Temperature this test must run at, in degrees Celsius, held fixed for the whole test. None means ambient: the test runs outside a thermal chamber.
  - `thermal_chamber_id` string, nullable — Chamber this test's channel sits in for the reservation. Recorded per reservation rather than per channel, because channels move between chambers.
  - `protocol_id` string, nullable — Named protocol (experiment_template) this measurement will run. Required on create; a planned measurement must name a protocol.
  - `program_id` string, nullable — Optional catalog program (Formation, Cycling, …) for this test request.
  - `test_setup` object, nullable — Planned physical setup.
  - `planned_start_time` string, date-time, nullable — When setup/run is planned to start.
  - `planned_end_time` string, date-time, nullable — When this planned measurement is expected to release the channel.
  - `estimated_duration_seconds` integer, nullable — Expected run duration before scheduled times exist.
  - `setup_duration_seconds` integer — Operator setup duration before the test starts.
  - `teardown_duration_seconds` integer — Operator teardown duration after the test finishes.
  - `notes` string, nullable — Free-text planning notes.
  - `id` string, required
  - `organization_id` string, required
  - `project_id` string, required
  - `status` 'requested' | 'scheduled' | 'in_progress' | 'completed' | 'cancelled', required — Lifecycle state for a planned measurement.
  - `requested_by` string, required
  - `scheduled_by` string, nullable
  - `scheduled_at` string, date-time, nullable
  - `started_measurement_id` string, nullable
  - `cancelled_at` string, date-time, nullable
  - `completed_at` string, date-time, nullable
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `requested_by_email` string, nullable
  - `scheduled_by_email` string, nullable
  - `channel_name` string, nullable
  - `cycler_id` string, nullable
  - `cycler_name` string, nullable
  - `program_name` string, nullable
  - `estimated_duration_status` 'estimating' | 'ready' | 'failed' — Lifecycle of a duration estimate computed by a background simulation. Used by both estimates: a planned test's total duration (``planned_measurements.estimated_duration_*``) and a running test's remaining duration (``cell_measurements.estimated_end_time_*``). One enum because the lifecycle is identical -- only what is being estimated differs. ``estimating`` while the job is in flight, ``ready`` once a value came from it, ``failed`` with the reason in the accompanying note. ``None`` means no estimate was ever requested.
  - `estimated_duration_job_id` string, nullable
  - `estimated_duration_simulation_id` string, nullable
  - `simulated_duration_seconds` integer, nullable
  - `estimated_duration_is_exact` boolean, nullable
  - `estimated_duration_margin_pct` number, nullable
  - `actual_duration_seconds` integer, nullable
  - `estimated_duration_note` string, nullable
  - `estimated_duration_calculated_at` string, date-time, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/ionworks/apis/fastapi.md) · [All operations](https://skmtc.dev/ionworks/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/ionworks/fastapi/revisions/7337a3cbdaf2/schema)
