> ## 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 Shipment

> Modify shipment details before pickup

Update shipment details such as pickup schedule, package count, or notes. If any logistics-relevant fields change (pickup date, time, package count, or weight), the existing logistics order is cancelled and a new one is created automatically. Fields you omit are preserved from the existing shipment. Updated schedule fields are validated against the [pickup schedule rules](/concepts/shipments#pickup-schedule-rules).

<Warning>
  Shipments cannot be modified after pickup. Attempting to update a shipment that has already been
  picked up returns `409 Conflict`.
</Warning>

## Request

### Path parameters

<ParamField path="id" type="string" required>
  Shipment reference ID (e.g., `P2604154821`).
</ParamField>

### Body parameters

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

<ParamField body="pickup_date" type="string">
  New pickup date in `YYYY-MM-DD` format, interpreted in the origin location's timezone.
</ParamField>

<ParamField body="pickup_time_from" type="string">
  New earliest pickup time in `HH:MM` format, interpreted as wall-clock time in the origin
  location's timezone.
</ParamField>

<ParamField body="pickup_time_till" type="string">
  New latest pickup time in `HH:MM` format, interpreted as wall-clock time in the origin location's
  timezone.
</ParamField>

<ParamField body="package_count" type="integer">
  New number of packages.
</ParamField>

<ParamField body="weight" type="number">
  New weight in kg.
</ParamField>

<ParamField body="notes" type="string">
  New notes or remarks. Maximum 128 characters.
</ParamField>

## Response

On success, the API returns `200 OK` with the updated shipment.

<ResponseField name="id" type="string" required>
  Shipment reference identifier.
</ResponseField>

<ResponseField name="status" type="string" required>
  Shipment lifecycle status. One of `pending`, `in_transit`, `delivered`, `fault`, or `cancelled`.
</ResponseField>

<ResponseField name="logistics_provider" type="string" required>
  Logistics provider. One of `go`, `dhl_parcel`, `tof`, `rotrunner` or `rapido`. Every home-kit
  parcel is `dhl_parcel`.
</ResponseField>

<ResponseField name="tracking_number" type="string">
  External tracking number from the logistics provider. May be `null`.
</ResponseField>

<ResponseField name="origin" type="object">
  Pickup address. May be `null`.

  <Expandable title="address object">
    <ResponseField name="name" type="string" required>Recipient, company, or location name.</ResponseField>
    <ResponseField name="company_name" type="string">Company / c/o line. May be `null`.</ResponseField>
    <ResponseField name="street" type="string" required>Street name, without the house number.</ResponseField>
    <ResponseField name="house_number" type="string">House number. May be `null`.</ResponseField>
    <ResponseField name="address_line_2" type="string">Building, entrance, or floor. May be `null`.</ResponseField>
    <ResponseField name="city" type="string" required>City.</ResponseField>
    <ResponseField name="state" type="string">State or province. May be `null`.</ResponseField>
    <ResponseField name="postal_code" type="string" required>Postal/ZIP code.</ResponseField>
    <ResponseField name="country_code" type="string" required>ISO 3166-1 alpha-2 country code.</ResponseField>
    <ResponseField name="phone" type="string">Contact phone number. May be `null`.</ResponseField>
    <ResponseField name="email" type="string">Contact email. May be `null`.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="destination" type="object">
  Delivery address. Same structure as `origin`. May be `null`.
</ResponseField>

<ResponseField name="pickup" type="object">
  Scheduled pickup window. May be `null`.

  <Expandable title="pickup object">
    <ResponseField name="from" type="string" required>Start of pickup window as a UTC instant (ISO 8601 with `Z` suffix).</ResponseField>
    <ResponseField name="till" type="string" required>End of pickup window as a UTC instant (ISO 8601 with `Z` suffix).</ResponseField>
    <ResponseField name="timezone" type="string" required>IANA timezone of the pickup location (e.g., `Europe/Berlin`). Use to render `from` / `till` in pickup-location wall-clock.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="notes" type="string">
  Optional notes. May be `null`.
</ResponseField>

<ResponseField name="status_updates" type="object[]" required>
  Chronological lifecycle events from the logistics provider (oldest first). Each entry has a
  `status` (free-form provider-sourced label) and `time` (ISO 8601). Empty array if no events
  observed yet.
</ResponseField>

<ResponseField name="appointments" type="ShipmentAppointmentLink[]" required>
  Appointments linked to this shipment, oldest-link first. Each entry is `{ id, added_at }`;
  cross-reference each `id` against [Get Appointment](/api/appointments/get-appointment).
</ResponseField>

<ResponseField name="created_at" type="string" required>
  Creation timestamp (ISO 8601).
</ResponseField>

<ResponseField name="updated_at" type="string">
  Last update timestamp (ISO 8601). May be `null`.
</ResponseField>

## Error responses

| Status | Description                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Validation error — e.g., invalid date or time format.                                                                      |
| `403`  | Forbidden — your API key does not have access to this operation or the shipment is outside your access context.            |
| `404`  | Shipment not found.                                                                                                        |
| `409`  | Shipment cannot be modified after pickup.                                                                                  |
| `500`  | Internal server error.                                                                                                     |
| `502`  | Logistics provider rejected the request (e.g., cancellation or re-creation failed). Includes the provider's error message. |

<RequestExample>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url https://anivahealth.com/api/v1/shipments/P2604154821 \
    --header 'x-api-key: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "pickup_date": "2026-04-16",
      "pickup_time_from": "10:00",
      "pickup_time_till": "13:00"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "P2604154821",
    "status": "pending",
    "logistics_provider": "go",
    "tracking_number": null,
    "origin": {
      "name": "Aniva Berlin Mitte",
      "street": "Unter den Linden",
      "house_number": "42",
      "postal_code": "10117",
      "city": "Berlin",
      "country_code": "DE",
      "phone": "+4930987654321",
      "email": "berlin-mitte@anivahealth.com"
    },
    "destination": {
      "name": "LabClinic GmbH",
      "street": "Laborstraße",
      "house_number": "10",
      "postal_code": "80331",
      "city": "München",
      "country_code": "DE",
      "phone": null,
      "email": null
    },
    "pickup": {
      "from": "2026-04-16T08:00:00Z",
      "till": "2026-04-16T11:00:00Z",
      "timezone": "Europe/Berlin"
    },
    "notes": null,
    "status_updates": [],
    "appointments": [],
    "created_at": "2026-04-03T14:30:00Z",
    "updated_at": "2026-04-03T15:10:00Z"
  }
  ```

  ```json 409 theme={null}
  {
    "error": "Shipment cannot be modified after pickup"
  }
  ```

  ```json 502 theme={null}
  {
    "error": "Logistics provider error: The cancellation notice period has already been exceeded. Cancellation is no longer possible via the web service. Please contact the GO! station.",
    "logistics_error_code": 4006
  }
  ```
</ResponseExample>
