# Reschedule an appointment

Operation ID: `appointments.reschedule`

Move the identified appointment to another slot returned by `appointments.listSlots`. On a FHIR-only tenant the previous slot is released after the target slot is reserved. On a vendor-integrated tenant (Athena, OpenLoop, SteadyMD) the move is executed in the vendor — and fails there — with no FHIR fallback: pass the chosen new slot's per-vendor fields exactly as `appointments.book` does (`athena_appointment_id` on Athena; `start` on OpenLoop; `start` + `steadymd_clinician_guid` on SteadyMD).

## Public method

`reschedule`

Signature: `appointments.reschedule(appointmentId, request)`

Return type: `Promise<Appointment>`

## Authentication

Classification: **AUTHENTICATED**

Schemes: `bearerAuth`

## Prerequisites

None documented.

## HTTP

`POST /appointments/{appointment_id}/reschedule`

## Path parameters

| Name | Type | Required | Format | Allowed values | Default | Nullable | Description |
|---|---|---:|---|---|---|---:|---|
| `appointment_id` | `string` | Yes |  |  |  | No |  |

## Query parameters

None.

## Body parameters

| Name | Type | Required | Format | Allowed values | Default | Nullable | Description |
|---|---|---:|---|---|---|---:|---|
| `body` | [`RescheduleAppointmentRequest`](../models/RescheduleAppointmentRequest.md) | No |  |  |  | Yes |  |

Request model: [`RescheduleAppointmentRequest`](../models/RescheduleAppointmentRequest.md)

## Request example

```json
{
  "athena_appointment_id": "1624",
  "reason": "Patient requested a later time",
  "slot_id": "660e8400-e29b-41d4-a716-446655440001",
  "start": "2026-09-01T10:00:00Z",
  "steadymd_clinician_guid": "clin-guid-9"
}
```

## Success responses

| Status | Shape | Content type | Description |
|---|---|---|---|
| `200` | [`Appointment`](../models/Appointment.md) | application/json | Appointment rescheduled successfully |

## Success response examples

### 200

```json
{
  "appointment_id": "string",
  "athena_appointment_id": "string",
  "created_at": "string",
  "end": "string",
  "openloop_appointment_id": "string",
  "patient_id": "string",
  "provider_id": "string",
  "slot_id": "string",
  "slot_ids": [
    "string"
  ],
  "specialty_code": "string",
  "start": "string",
  "status": "scheduled",
  "steadymd_consult_guid": "string",
  "telehealth_link": "string",
  "updated_at": "string"
}
```

## Common errors

| Status | Shape | Content type | Description |
|---|---|---|---|
| `400` | [`appointments.ErrorResponse`](../models/appointments.ErrorResponse.md) | application/json | Bad request — missing slot_id, or the vendor-integrated tenant's per-vendor fields are missing |
| `401` | [`appointments.ErrorResponse`](../models/appointments.ErrorResponse.md) | application/json | Authorization required — missing or invalid Bearer JWT |
| `404` | [`appointments.ErrorResponse`](../models/appointments.ErrorResponse.md) | application/json | The appointment or target slot was not found |
| `409` | [`appointments.ErrorResponse`](../models/appointments.ErrorResponse.md) | application/json | Conflict — target slot not available, or the vendor rejected the move as a business rule |
| `500` | [`appointments.ErrorResponse`](../models/appointments.ErrorResponse.md) | application/json | Internal server error |
| `502` | [`appointments.ErrorResponse`](../models/appointments.ErrorResponse.md) | application/json | Vendor-integrated tenant: the vendor failed or did not confirm the move |

## Error examples

### 400 — The target slot was not supplied

```json
{
  "error": "slot_id is required"
}
```

### 400 — Vendor-integrated tenant without the new slot's vendor fields

```json
{
  "error": "athena_appointment_id is required when rescheduling on an Athena-integrated tenant"
}
```

### 401 — Missing or invalid access token

```json
{
  "error": "Authorization required"
}
```

### 404 — The appointment or target slot does not exist

```json
{
  "error": "Slot not found"
}
```

### 409 — The target slot is not available

```json
{
  "error": "Slot busy-slot is not available (status=busy)"
}
```

### 409 — The vendor refused the move (e.g. the chosen time is no longer open)

```json
{
  "error": "Appointment cannot be changed in OpenLoop: The appointment can not be scheduled at this time."
}
```

### 500 — Unexpected service failure (sanitized example)

```json
{
  "error": "Internal server error"
}
```

### 502 — Vendor answered 200 but did not confirm the move

```json
{
  "error": "Athena did not confirm appointment 123 as moved to 09/15/2026 09:00"
}
```

## NodeJS / TypeScript implementation

```ts
import { HCSDK } from "@healthcloudai/hc-sdk";
import type { RescheduleAppointmentRequest } from "@healthcloudai/hc-sdk";
```

```ts
const appointmentId = "<APPOINTMENT_ID>";

const request = {
  "athena_appointment_id": "1624",
  "reason": "Patient requested a later time",
  "slot_id": "660e8400-e29b-41d4-a716-446655440001",
  "start": "2026-09-01T10:00:00Z",
  "steadymd_clinician_guid": "clin-guid-9"
};

const result = await appointments.reschedule(appointmentId, request);
```

## cURL

```bash
curl -X POST \
  -H 'Authorization: Bearer <ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"athena_appointment_id":"1624","reason":"Patient requested a later time","slot_id":"660e8400-e29b-41d4-a716-446655440001","start":"2026-09-01T10:00:00Z","steadymd_clinician_guid":"clin-guid-9"}' \
  'https://dev-api-appointments.health.cloud/appointments/%3CAPPOINTMENT_ID%3E/reschedule'
```

## Notes

None.

## Prepared Test Console scenario

No canonical scenario is currently associated.

## Real response

No approved real integration response is currently published. Unapproved candidates are never rendered as examples.
