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

# Update an Existing Appointment — PATCH /appointments/{id}

> Partially update an existing appointment's time, status, or notes. Optionally notify the patient via WhatsApp when changes are saved.

The Update Appointment endpoint allows you to modify an existing appointment using a partial update (PATCH semantics). You can reschedule by changing `starts_at` and `ends_at`, advance the lifecycle status to `confirmed`, `completed`, or `no_show`, or edit internal notes — all in a single request. Every field in the request body is optional; only the fields you include are changed. If you want the patient to receive a WhatsApp notification about the change, include `"notify_patient": true` in the request body.

## Request

**PATCH** `https://api.bydoctor.com.br/v1/appointments/{id}`

**Content-Type:** `application/json`

<ParamField path="id" type="string" required>
  The UUID of the appointment to update.
</ParamField>

<ParamField body="starts_at" type="string">
  New appointment start time as an ISO 8601 UTC timestamp. Must be provided together with `ends_at` when rescheduling.
</ParamField>

<ParamField body="ends_at" type="string">
  New appointment end time as an ISO 8601 UTC timestamp. Must be strictly after the new `starts_at`.
</ParamField>

<ParamField body="status" type="string">
  Transition the appointment to a new lifecycle status. Accepted values: `confirmed`, `completed`, `no_show`. See the warning below regarding `cancelled`.
</ParamField>

<ParamField body="notes" type="string">
  Replacement text for the notes field. Pass an empty string `""` to clear existing notes.
</ParamField>

<ParamField body="notify_patient" type="boolean" default={false}>
  When `true`, ByDoctor sends a WhatsApp update notification to the patient's registered phone number after a successful update. Defaults to `false` so that routine administrative edits do not generate unwanted messages. This field is write-only and is not returned in responses.
</ParamField>

## Response Fields

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

<ResponseField name="clinic_id" type="string">
  The ID of the clinic that owns this appointment.
</ResponseField>

<ResponseField name="patient_id" type="string">
  The ID of the patient linked to this appointment.
</ResponseField>

<ResponseField name="professional_id" type="string">
  The ID of the professional assigned to this appointment.
</ResponseField>

<ResponseField name="starts_at" type="string">
  Current appointment start time in ISO 8601 UTC format (updated if rescheduled).
</ResponseField>

<ResponseField name="ends_at" type="string">
  Current appointment end time in ISO 8601 UTC format (updated if rescheduled).
</ResponseField>

<ResponseField name="type" type="string">
  Appointment type: `presencial` or `teleconsulta`. Cannot be changed after creation.
</ResponseField>

<ResponseField name="status" type="string">
  The appointment's current lifecycle status after the update.
</ResponseField>

<ResponseField name="notes" type="string">
  The current notes after the update. `null` if none are set.
</ResponseField>

<ResponseField name="payment_status" type="string">
  Current payment status: `pending`, `paid`, or `overdue`.
</ResponseField>

<ResponseField name="teleconsult_url" type="string">
  Video room URL. Present only when `type` is `teleconsulta`. `null` otherwise.
</ResponseField>

<ResponseField name="created_at" type="string">
  Timestamp when the appointment was originally created (ISO 8601 UTC).
</ResponseField>

<ResponseField name="updated_at" type="string">
  Timestamp of this update (ISO 8601 UTC).
</ResponseField>

<Warning>
  Setting `status` to `cancelled` via this endpoint is **not permitted** and will return a `400 Bad Request` error. To cancel an appointment, use the [Cancel Appointment](/api-reference/appointments/cancel) endpoint (`DELETE /appointments/{id}`) instead. This separation ensures cancellations are audited correctly and that the optional WhatsApp cancellation notice is handled by the dedicated workflow.
</Warning>

## Example Request — Reschedule an Appointment

```bash theme={null}
curl --request PATCH \
  --url "https://api.bydoctor.com.br/v1/appointments/c3d4e5f6-a7b8-9012-cdef-123456789012" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{
    "starts_at": "2025-07-22T10:00:00Z",
    "ends_at": "2025-07-22T10:30:00Z",
    "notes": "Rescheduled at patient request.",
    "notify_patient": true
  }'
```

## Example Response (200 OK)

```json theme={null}
{
  "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "clinic_id": "clinic_01HX1234ABCD",
  "patient_id": "pat_01HX5678EFGH",
  "professional_id": "pro_01HX9012IJKL",
  "starts_at": "2025-07-22T10:00:00Z",
  "ends_at": "2025-07-22T10:30:00Z",
  "type": "teleconsulta",
  "status": "confirmed",
  "notes": "Rescheduled at patient request.",
  "payment_status": "pending",
  "teleconsult_url": "https://meet.bydoctor.com.br/room/c3d4e5f6",
  "created_at": "2025-07-01T10:15:30Z",
  "updated_at": "2025-07-10T09:30:00Z"
}
```

## Error Responses

**400 Bad Request** — Invalid field value, including an attempt to set `status` to `cancelled`.

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "Setting status to 'cancelled' via PATCH is not allowed. Use DELETE /appointments/{id} to cancel an appointment.",
    "field": "status"
  }
}
```

**401 Unauthorized** — Your API key is missing or invalid.

```json theme={null}
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key. Provide a valid Bearer token in the Authorization header."
  }
}
```

**404 Not Found** — No appointment with the given ID exists in your clinic.

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "No appointment found with id 'c3d4e5f6-a7b8-9012-cdef-123456789012'."
  }
}
```

**409 Conflict** — The new time slot overlaps with another appointment for the same professional.

```json theme={null}
{
  "error": {
    "code": "time_slot_conflict",
    "message": "Professional 'pro_01HX9012IJKL' already has an appointment between 2025-07-22T10:00:00Z and 2025-07-22T10:30:00Z.",
    "conflicting_appointment_id": "d4e5f6a7-b8c9-0123-def0-234567890123"
  }
}
```

**422 Unprocessable Entity** — The request body is structurally valid but logically inconsistent (for example, `ends_at` is before or equal to `starts_at`).

```json theme={null}
{
  "error": {
    "code": "unprocessable_entity",
    "message": "'ends_at' must be strictly after 'starts_at'."
  }
}
```
