> ## Documentation Index
> Fetch the complete documentation index at: https://teardowns.aero/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Update a teardown

> Partial update only the fields you send are applied.

PATCH a teardown your organization owns. Sparse only the keys on
your request body are written. Omitted keys are left alone.

Use this for:

* Correcting a typo in `msn` or `tail_number`
* Re-classifying with a different vocab name
* Setting / changing / clearing the `audience`
* Updating dates, location, traceability, description

To change the **status** (lifecycle state), use the
[transition endpoint](/api-reference/teardowns/transition) instead.
PATCH does not accept `status` lifecycle changes go through the
state machine.

## Headers

<ParamField header="Authorization" type="string" required>
  `Bearer tdao_live_…`
</ParamField>

<ParamField header="X-Organization-Id" type="string" required>
  Your organization's UUID.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `application/json`
</ParamField>

## Path parameters

<ParamField path="teardown_id" type="string (UUID)" required />

## Body

Every field is optional. Sending an empty body returns the teardown
unchanged.

<ParamField body="aircraft_type / engine_model" type="string">
  Re-classify by name. Same case-insensitive lookup as create.
  An unknown value returns `400 unknown_vocabulary` with the allowed
  list in the body. APU and landing-gear vocab fields are not patchable
  through the public surface.
</ParamField>

<ParamField body="tail_number" type="string" />

<ParamField body="msn" type="string" />

<ParamField body="traceability" type="string" />

<ParamField body="start_date" type="string (date)">
  Maps to `teardowns.teardown_start_date`.
</ParamField>

<ParamField body="end_date" type="string (date)" />

<ParamField body="incident_related" type="string">
  `Yes` or `No`.
</ParamField>

<ParamField body="description" type="string" />

<ParamField body="location" type="string" />

<ParamField body="country" type="string">
  ISO country code.
</ParamField>

<ParamField body="audience" type="array | null">
  Set who can see the teardown's documents. Pass an array of company
  types (`Airline` / `Lessor` / `OEM` / `MRO` / `Distributor` /
  `Others`), or pass `null` to clear the restriction back to
  "anyone with platform access".

  This is the JSON-array form. The document-upload endpoint accepts
  the same concept as a comma-separated string. See
  [audience](/concepts/audience).
</ParamField>

<ParamField body="images" type="array of URLs">
  Direct overwrite. Usually you want the upload / delete-by-url
  endpoints instead.
</ParamField>

<ParamField body="documents" type="array of URLs">
  Direct overwrite. Usually you want the upload / delete-by-url
  endpoints instead.
</ParamField>

<Warning>
  `location_city`, `sub_status`, `non_incident_statement`, `apu_model`,
  and `landing_gear_type` are NOT patchable on the public surface
  sending any of them returns `422` (strict mode). If you need to update
  one of those fields, use the web app.
</Warning>

<Warning>
  **`status` is not patchable here.** Use the [transition
  endpoint](/api-reference/teardowns/transition) so lifecycle moves run
  through the state machine. Sending `status` returns a 422 (strict mode
  catches unknown body keys).

  Same goes for `teardown_status_label` it's a derived label, not
  something you set directly.
</Warning>

## Response

`200 OK`. The full updated teardown in the same shape as the GET / POST
responses (partner field names).

<RequestExample>
  ```bash curl theme={null}
  curl -X PATCH "$base_url/public/v1/teardowns/$teardown_id" \
    -H "Authorization: Bearer $api_key" \
    -H "X-Organization-Id: $org_id" \
    -H "Content-Type: application/json" \
    -d '{
      "description": "Updated via API",
      "tail_number": "VT-XYZ",
      "country": "IN",
      "audience": ["Airline", "MRO"]
    }'
  ```

  ```python python theme={null}
  import requests
  resp = requests.patch(
      f"{base_url}/public/v1/teardowns/{teardown_id}",
      headers={
          "Authorization": f"Bearer {api_key}",
          "X-Organization-Id": org_id,
      },
      json={
          "description": "Updated via API",
          "tail_number": "VT-XYZ",
          "country": "IN",
          "audience": ["Airline", "MRO"],
      },
  )
  resp.raise_for_status()
  ```

  ```bash clear audience theme={null}
  # Pass null to clear back to "anyone with platform access"
  curl -X PATCH "$base_url/public/v1/teardowns/$teardown_id" \
    -H "Authorization: Bearer $api_key" \
    -H "X-Organization-Id: $org_id" \
    -H "Content-Type: application/json" \
    -d '{"audience": null}'
  ```
</RequestExample>

<ResponseExample>
  ```jsonc 200 OK theme={null}
  {
    "teardown_id": "3c707051-021d-4d04-a8e7-4eb254e80858",
    ...
    "tail_number": "VT-XYZ",
    "country": "IN",
    "description": "Updated via API",
    "audience": ["Airline", "MRO"],
    "audience_set_at": "2026-05-27T08:00:00Z",
    "updated_at": "2026-05-27T08:00:00Z"
  }
  ```

  ```jsonc 400 Unknown vocabulary theme={null}
  {
    "detail": {
      "error_code": "unknown_vocabulary",
      "field": "aircraft_type",
      "value": "A320-poo",
      "valid_values": ["A320-200", "A321-200", ...],
      "message": "Unknown aircraft_type: 'A320-poo'. See valid_values."
    }
  }
  ```

  ```jsonc 404 Not Found theme={null}
  {
    "detail": "Teardown not found"
  }
  ```
</ResponseExample>

## Audit trail

PATCH writes:

* `teardown.updated` the generic update audit, with `previous_state`
  containing the old values for `msn`, `registration`, `description`,
  and `new_state` containing the sparse body you sent.
* `teardown.audience.set` or `teardown.audience.changed` if the
  audience field changed. Two separate action codes so support can
  filter "first time it was restricted" vs "subsequent change".

Both rows carry the standard API-key metadata
(`via_api`, `api_key_id`, `api_key_prefix`, `actor_email`).

## See also

* [Transition](/api-reference/teardowns/transition) for changing
  lifecycle state.
* [Audience](/concepts/audience) for the visibility model.
* [Vocabularies](/concepts/vocabularies) for the name-based lookup
  behaviour shared with create.
