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

# Update Appointment

> Modify appointment details before blood draw

Update appointment details such as the scheduled time or test location. Only appointments that have not yet had their blood draw confirmed can be modified.

<Warning>
  Appointments cannot be modified after the blood draw has been confirmed or if already cancelled.
  Attempting to update such an appointment returns `409 Conflict`.
</Warning>

## Request

### Path parameters

<ParamField path="id" type="string" required>
  Unique identifier (UUID) of the appointment to update.
</ParamField>

### Body parameters

All body parameters are optional — only include the fields you want to change.

<ParamField body="scheduled_at" type="string">
  New appointment datetime in ISO 8601 format (e.g., `2026-05-20T14:00:00Z` or
  `2026-05-20T16:00:00+02:00`). **Must include a timezone designator** — either `Z` or an explicit
  offset like `+02:00`; naive datetimes are rejected. Must be in the future.
</ParamField>

<ParamField body="location_id" type="string">
  UUID of the new test location. The location must exist and be active. Use [List
  Locations](/api/locations/list-locations) to find available location IDs.
</ParamField>

## Response

On success, the API returns `200 OK` with the updated appointment and its embedded profile.

<ResponseField name="id" type="string" required>
  Unique appointment identifier (UUID).
</ResponseField>

<ResponseField name="profile_id" type="string" required>
  UUID of the profile this appointment belongs to.
</ResponseField>

<ResponseField name="location_id" type="string">
  UUID of the test location. `null` for home kit appointments.
</ResponseField>

<ResponseField name="scheduled_at" type="string">
  Scheduled appointment datetime as a UTC instant (ISO 8601 with `Z` suffix, e.g.
  `2026-05-20T14:00:00Z`). May be `null`.
</ResponseField>

<ResponseField name="status" type="string" required>
  Current appointment status. One of `pending`, `confirmed`, `blood_drawn`, or `cancelled`.
  Lab-result completion granularity is derived from [Get Results](/api/appointments/get-results);
  finer-grained shipment progression from each entry in the inline `shipments` array (see below)
  followed to [Get Shipment](/api/shipments/get-shipment).
</ResponseField>

<ResponseField name="test_method" type="string">
  Method used for the blood draw. One of `practitioner` or `home`. May be `null`.
</ResponseField>

<ResponseField name="cancellation_reason" type="string">
  Free-text reason captured when the appointment was cancelled (e.g. no-show, late cancellation,
  'Failed. Repeat required'). `null` unless `status` is `cancelled`.
</ResponseField>

<ResponseField name="created_at" type="string" required>
  ISO 8601 timestamp of when the appointment was created.
</ResponseField>

<ResponseField name="updated_at" type="string">
  ISO 8601 timestamp of the last update. May be `null`.
</ResponseField>

<ResponseField name="profile" type="object" required>
  The patient profile associated with this appointment.

  <Expandable title="profile">
    <ResponseField name="id" type="string">
      Unique profile identifier (UUID).
    </ResponseField>

    <ResponseField name="handle" type="string">
      Profile handle or username. May be `null`.
    </ResponseField>

    <ResponseField name="first_name" type="string">
      First name. May be `null`.
    </ResponseField>

    <ResponseField name="last_name" type="string">
      Last name. May be `null`.
    </ResponseField>

    <ResponseField name="email" type="string">
      Email address. May be `null`.
    </ResponseField>

    <ResponseField name="phone" type="string">
      Phone number in E.164 format. May be `null`.
    </ResponseField>

    <ResponseField name="sex" type="integer">
      Biological sex per ISO/IEC 5218. May be `null`.
    </ResponseField>

    <ResponseField name="date_of_birth" type="string">
      Date of birth in `YYYY-MM-DD` format. May be `null`.
    </ResponseField>

    <ResponseField name="height" type="number">
      Height in centimeters. May be `null`.
    </ResponseField>

    <ResponseField name="weight" type="number">
      Weight in kilograms. May be `null`.
    </ResponseField>

    <ResponseField name="language" type="string">
      Preferred language (`en`, `de`, or `fi`).
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp of when the profile was created.
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      ISO 8601 timestamp of the last profile update. May be `null`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="panels" type="AppointmentPanel[]" required>
  Panels currently attached to this appointment. Excludes cancelled attachments. Look up panel
  details (name, biomarkers) via [List Panels](/api/panels/list-panels).

  <Expandable title="Panel attachment fields">
    <ResponseField name="panel_id" type="string">
      Panel UUID — cross-reference against [List Panels](/api/panels/list-panels).
    </ResponseField>

    <ResponseField name="added_at" type="string">
      ISO 8601 timestamp the panel was first attached to this appointment.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="individual_biomarkers" type="AppointmentIndividualBiomarker[]" required>
  À-la-carte biomarkers attached to this appointment outside any panel (see [Add Custom
  Biomarkers](/api/appointments/add-individual-biomarkers)). Cross-reference each `biomarker_id`
  against [List Biomarkers](/api/biomarkers/list-biomarkers) for display data.

  <Expandable title="Individual biomarker fields">
    <ResponseField name="biomarker_id" type="integer">
      Biomarker identifier — cross-reference against
      [List Biomarkers](/api/biomarkers/list-biomarkers).
    </ResponseField>

    <ResponseField name="added_at" type="string">
      ISO 8601 timestamp the biomarker was first attached to this appointment.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="shipments" type="AppointmentShipmentLink[]" required>
  Shipments linked to this appointment, oldest-link first. Empty array when no shipments are
  linked. Cross-reference each `id` against [Get Shipment](/api/shipments/get-shipment) for the
  full shipment payload.

  <Expandable title="Shipment link fields">
    <ResponseField name="id" type="string">
      Shipment reference identifier — cross-reference against
      [Get Shipment](/api/shipments/get-shipment).
    </ResponseField>

    <ResponseField name="added_at" type="string">
      ISO 8601 timestamp the shipment was first linked to this appointment.
    </ResponseField>
  </Expandable>
</ResponseField>

## Error responses

| Status | Description                                                                                                                 |
| ------ | --------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Validation error — e.g., `scheduled_at` is in the past or invalid UUID format.                                              |
| `403`  | Forbidden — your API key does not have access to this operation or the appointment/location is outside your access context. |
| `404`  | Appointment or location not found.                                                                                          |
| `409`  | Appointment cannot be modified (blood draw already confirmed or appointment is cancelled).                                  |
| `500`  | Internal server error.                                                                                                      |

<RequestExample>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url https://anivahealth.com/api/v1/appointments/c9f3e2a1-7d6b-4c5e-b3a2-1f0e9d8c7b6a \
    --header 'x-api-key: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "scheduled_at": "2026-05-20T14:00:00Z",
      "location_id": "d8f3e1a2-4c5b-6d7e-8f9a-0b1c2d3e4f5a"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "c9f3e2a1-7d6b-4c5e-b3a2-1f0e9d8c7b6a",
    "profile_id": "a3f1c2d4-8b7e-4f2a-9c1d-2e3f4a5b6c7d",
    "location_id": "d8f3e1a2-4c5b-6d7e-8f9a-0b1c2d3e4f5a",
    "scheduled_at": "2026-05-20T14:00:00Z",
    "status": "confirmed",
    "test_method": "practitioner",
    "cancellation_reason": null,
    "created_at": "2026-04-01T09:45:00Z",
    "updated_at": "2026-04-10T11:30:00Z",
    "profile": {
      "id": "a3f1c2d4-8b7e-4f2a-9c1d-2e3f4a5b6c7d",
      "handle": null,
      "first_name": "Maria",
      "last_name": "Schmidt",
      "email": "maria.schmidt@example.com",
      "phone": "+4930123456789",
      "sex": 2,
      "date_of_birth": "1985-03-22",
      "height": 168,
      "weight": 65,
      "language": "de",
      "created_at": "2026-04-01T09:14:32Z",
      "updated_at": null
    },
    "panels": [
      {
        "panel_id": "f1c2d4a3-7b8e-4f2a-9c1d-2e3f4a5b6c7d",
        "added_at": "2026-04-01T09:50:00Z"
      }
    ],
    "individual_biomarkers": [],
    "shipments": []
  }
  ```

  ```json 409 theme={null}
  {
    "error": "Appointment cannot be modified after blood draw has been confirmed"
  }
  ```

  ```json 404 theme={null}
  {
    "error": "Location not found or inactive"
  }
  ```
</ResponseExample>
