# Report measured condition data (merge)

> `PATCH /batteries/{batteryId}/condition` · Scope: `condition` · operationId `updateCondition`

Editor and above, or an API key with the `condition` scope (source `api`, ADR-016, ADR-017). Merge
semantics: only the named fields change, `null` clears a field.
Each value has a `measured_at` (its own or the request's), which must not lie in the future or before
the manufacturing date. Fields that are not dynamic fields of the unit are refused (`unknown_field`);
so is the whole update when a value is invalid or the merged condition data fails a cross-field
check. A value older than the stored one, or equal to it, is skipped and listed. Accepted values are
stored as approved measurements and recorded as a `condition_update` lifecycle event; a published
passport is re-published as the organisation's `condition_republish` setting says (immediately in
this request, or by the daily job).

## Path parameters

- **batteryId** `string (uuid)` (required)

## Request body (`application/json`)

- **measured_at** `string (date-time)`: The measurement time of values without their own.
- **note** `string`: Becomes the description of the lifecycle event.
- **values** `ConditionValueInput[]` (required)
  - **field_key** `string` (required)
  - **measured_at** `string (date-time)`: When the value was measured; defaults to the update's `measured_at`.
  - **value** `any | null` (required): The value as JSON; null clears the field.

## Responses

### 200 (`application/json`)

What was accepted, what was skipped, and the publication.

- **accepted** `FieldValue[]` (required)
  - **checks** `ValueCheck[]` (required)
  - **evidence** `EvidenceRef[]`: Documents this revision rests on (set on approved revisions and supplier submissions).
  - **field_key** `string` (required)
  - **measured_at** `string (date-time)`: When a measured value (condition data, ADR-016) was measured.
  - **recorded_at** `string (date-time)` (required)
  - **recorded_by** `UserRef`
  - **registry_version** `string` (required)
  - **responsible** `UserRef`
  - **review_note** `string`
  - **review_status** `string` (required, one of: `captured`, `auto_checked`, `approved`, `rejected`)
  - **reviewed_at** `string (date-time)`
  - **reviewed_by** `UserRef`
  - **revision** `integer` (required)
  - **source** `string` (required, one of: `manual`, `import`, `supplier`, `api`, `system`)
  - **superseded_at** `string (date-time)`
  - **unit** `string`
  - **value** `any | null` (required): The value as JSON; null when the field was cleared.
- **event** `LifecycleEvent`
  - **api_key** `ApiKeyRef`: An organisation API key (ADR-017) that reported an event (source `api`) or staged an import (ADR-026).
  - **battery_id** `string (uuid)` (required)
  - **created_at** `string (date-time)` (required)
  - **description** `string`
  - **evidence** `EvidenceRef[]` (required)
  - **field_keys** `string[]` (required): The condition fields this event updated.
  - **id** `string (uuid)` (required)
  - **occurred_on** `string (date)` (required)
  - **partner** `ServicePartnerRef`
  - **related_battery_id** `string (uuid)`: Second life: the successor (on the predecessor's event) or the predecessor (on the successor's).
  - **related_serial_number** `string`
  - **reported_by** `UserRef`
  - **source** `string` (required, one of: `manual`, `supplier`, `api`, `system`): `manual` (a member), `supplier` (a service-partner link), `api` (an API key, M7), `system`.
  - **type** `string` (required, one of: `placed_on_market`, `put_into_service`, `inspection`, `repair`, `component_replaced`, `condition_update`, `repurposed`, `reused`, `remanufactured`, `waste`, `recycled`, `custom`): What happened to a unit. `condition_update` is recorded by condition updates, `repurposed`, `reused` and `remanufactured` by `createSecondLifeBattery`; the others are reported.
- **publication** `ConditionPublication` (required)
  - **blockers** `PublishBlocker[]`
  - **outcome** `string` (required, one of: `published`, `unchanged`, `blocked`, `scheduled`, `not_published`): `published` / `unchanged`: published immediately (or nothing changed); `blocked`: the gate refused, the passport is `update_needed`; `scheduled`: the daily job publishes it; `not_published`: the unit has no published passport.
  - **version** `PassportVersionSummary`
- **skipped** `ConditionSkip[]` (required)
  - **field_key** `string` (required)
  - **reason** `string` (required, one of: `older_measurement`, `unchanged`): `older_measurement`: the stored value was measured later; `unchanged`: same value and time.

### 400 (`application/problem+json`)

The request is malformed or failed validation (`validation_error`), or a token is invalid or expired (`invalid_token`).

### 401 (`application/problem+json`)

The API key is missing, unknown or revoked (`unauthenticated`).

### 403 (`application/problem+json`)

The API key may not perform this action (`forbidden`): it lacks the operation's scope, or the action needs more than a viewer's rights.

### 404 (`application/problem+json`)

The resource does not exist in the organisation of the API key, or the public passport is unknown (`not_found`).

### 409 (`application/problem+json`)

The request conflicts with the current state (`conflict`), e.g. a stale `If-Match` version.

### default (`application/problem+json`)

Any other problem, e.g. `internal_error`.

## Example

```bash title="cURL"
curl -X PATCH "https://passport.kabin.sh/api/v1/batteries/{batteryId}/condition" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
```
