Appointments
Scheduled patient visits. Bound to a provider, an appointment type, and a contact.
Booking an appointment writes a row, an activity (type: MEETING), and an audit entry. Cancellation flows through the same endpoint with a PATCH.
Book an appointment
Create a new appointment slot. The container service validates conflicts against the provider's availability and overlapping bookings.
Required scopes:
contacts.writeRequest body
| Name | Type | Description |
|---|---|---|
contactIdrequired | string | Patient. |
providerIdrequired | string | Provider. |
appointmentTypeIdrequired | string | Appointment type. |
scheduledAtrequired | string | ISO 8601 datetime. |
durationMinutes | integer | Override the type's default duration. |
reason | string | Visit reason. ≤ 2000 chars. |
internalNotes | string | Staff-only notes. ≤ 8000 chars. |
telehealthUrl | string | Video room URL. |
location | string | Free-form location. ≤ 200 chars. |
Request body
{ "contactId": "cln…", "providerId": "prv…", "appointmentTypeId": "at…", "scheduledAt": "2026-05-22T19:00:00Z" }Responses
201 CreatedBooked.example { "id": "ap_3w8d2k…", "contactId": "cln1f8s7p…", "providerId": "prv_9k4w2x…", "appointmentTypeId": "at_8h2c3p…", "scheduledAt": "2026-05-22T19:00:00Z", "durationMinutes": 30, "status": "BOOKED", "location": "Suite 101", "telehealthUrl": null, "reason": "Annual physical", "createdAt": "2026-05-18T14:00:00Z" }409 ConflictProvider double-booked.422 Unprocessable EntityValidation failed.
Code samples
curl -X POST https://app.contactfollowup.com/api/appointments \
-H "Authorization: Bearer $HEARTHNOTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "contactId": "cln…", "providerId": "prv…", "appointmentTypeId": "at…", "scheduledAt": "2026-05-22T19:00:00Z" }'List appointments
Filter by provider, contact, and a time window.
Required scopes:
contacts.readQuery parameters
| Name | Type | Description |
|---|---|---|
providerId | string | Provider id. |
contactId | string | Contact id. |
from | string | ISO 8601 datetime — start of window. |
to | string | ISO 8601 datetime — end of window. |
limit | integer | Default 200. |
Responses
200 OKAppointments.example { "appointments": [{ "id": "ap_3w8d2k…", "contactId": "cln1f8s7p…", "providerId": "prv_9k4w2x…", "appointmentTypeId": "at_8h2c3p…", "scheduledAt": "2026-05-22T19:00:00Z", "durationMinutes": 30, "status": "BOOKED", "location": "Suite 101", "telehealthUrl": null, "reason": "Annual physical", "createdAt": "2026-05-18T14:00:00Z" }] }
Code samples
curl -X GET https://app.contactfollowup.com/api/appointments \
-H "Authorization: Bearer $HEARTHNOTE_TOKEN" \
-H "Content-Type: application/json"