Skip to content

Appointments

An appointment is a scheduled visit: a slot on the clinic calendar that ties a patient to a provider for a particular reason (wellness exam, dental, recheck, surgery, etc.). Appointments are the typical entry point for day-of workflows, and they’re the parent record that most SOAP notes are written against.

Appointment listings are heavily date-filtered in practice. Scope every list with a date window of one calendar month or less, or with an id filter; see Conventions for paging and date-window rules.

Authoritative schemas live in the live Swagger UI. The fields below are a representative subset for orientation.

FieldTypeDescription
idstringUnique identifier for the appointment.
clientIdstringThe owning client (paying customer).
appointmentPatientsarrayThe patients on the appointment. An appointment can cover more than one pet for the same client, so there is no single patientId.
providerIdstringThe veterinarian or staff member assigned.
startDatestringISO 8601 UTC scheduled start.
endDatestringISO 8601 UTC scheduled end.
appointmentTypeIdstringReference to the appointment-type taxonomy. A null type means the slot is blocked off rather than booked.
appointmentStatusIdstringReference to the current status. Defaults to upcoming.
appointmentCancellationReasonIdstringSet when the appointment was cancelled.
visitReasonstringFree-text reason for visit. Becomes the initial complaint on the SOAP.
schedulingMethodstringHow the appointment was booked.
clinicIdstringThe owning clinic.
dateCreatedstringISO 8601 UTC timestamp of creation.
dateUpdatedstringISO 8601 UTC timestamp of last update.
isDeletedbooleanSoft-delete flag. Note this is isDeleted here, not deleted.
POST /pav2/open-api-appointments

Returns a paginated collection of appointments for the clinic. The most common pattern is a date-range query for “today” or “this week”; the example below shows the exact ISO 8601 timestamps to send.

Appointments have two kinds of date filter, and they answer different questions:

  • dateFrom / dateTo match appointments whose scheduled time overlaps the range. Use these for “today’s schedule” or “next week’s bookings”.
  • dateCreatedFrom / dateCreatedTo (and dateUpdatedFrom / dateUpdatedTo) match when the appointment record was created or last changed, not when the visit happens. Use dateUpdatedFrom / dateUpdatedTo for incremental sync.

Send both ends of whichever pair you use and keep the window to one calendar month or less. Keep page * rpp at or below 10,000; if a clinic’s volume risks exceeding that, use shorter windows. Deleted appointments are included unless you send "isDeleted": false. Embedding appointmentPatients.patient is expensive: keep rpp at 50 or less when you use it.

For a clinic local to UTC, “today” (2026-05-22) is 2026-05-22T00:00:00Z through 2026-05-23T00:00:00Z. Adjust the bounds to your clinic’s local timezone as needed.

Terminal window
curl -X POST https://open-api.shepherd.vet/pav2/open-api-appointments \
-H "Content-Type: application/json" \
-H "X-Integration-Public-Key: $SHEPHERD_PUBLIC_KEY" \
-H "X-Integration-Private-Key: $SHEPHERD_PRIVATE_KEY" \
-H "X-Clinic-Id: $SHEPHERD_CLINIC_ID" \
-d '{
"page": 1,
"rpp": 100,
"sort": "startDate|asc",
"dateFrom": "2026-05-22T00:00:00Z",
"dateTo": "2026-05-23T00:00:00Z",
"embed": "appointmentPatients,client,provider"
}'
{
"item": [
{
"id": "b96d21ae-435f-4ef1-8cf7-3efbc3a3649a",
"clientId": "e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6",
"appointmentPatients": [
{ "patientId": "a1b2c3d4-e5f6-7890-abcd-ef0123456789" }
],
"providerId": "5a8d0cfc-c7c4-44a0-bdab-44f4e5f6b219",
"startDate": "2026-05-22T14:30:00Z",
"endDate": "2026-05-22T15:00:00Z",
"appointmentTypeId": "8fc9c6d1-a829-4b93-a5ea-1c83db96a1b4",
"appointmentStatusId": "9f8e7d6c-5b4a-3210-a9f8-fedcba098765",
"appointmentCancellationReasonId": null,
"visitReason": "Annual wellness exam",
"clinicId": "9890662f-52db-4a41-a5c1-b2e300d400b4",
"dateCreated": "2026-05-22T09:11:00Z",
"dateUpdated": "2026-05-22T09:11:00Z",
"isDeleted": false
}
],
"totalRecords": 27,
"page": 1,
"recordsPerPage": 100,
"sort": "startDate|asc",
"searchQuery": null,
"embed": "appointmentPatients,client,provider",
"links": []
}
POST /pav2/open-api-appointments/write

Creates a new appointment on the clinic calendar.

Required: startDate, endDate, and providerId. Everything else is optional, but the optional fields interact:

  • appointmentTypeId controls the rest. Leave it null and the call blocks off time for the provider rather than booking a visit; clientId and patientIds can only be set when a type is present.
  • patientIds is an array and requires clientId. An appointment belongs to a client and can cover several of that client’s pets, so there is no single patientId.
  • startDate and endDate must fall on 5-minute boundaries (for example 14:30:00, not 14:32:00), the end must be after the start, and the appointment can span at most 24 hours.
  • appointmentStatusId defaults to upcoming when omitted. The pending status is rejected on create.
  • visitReason becomes the initial complaint on the resulting SOAP record.
  • sendEmailNotification, sendSmsNotification, and sendFormEmailNotification all default to false. Leave them false unless the clinic wants your integration to message its clients.

The response is the created appointment, or a collection envelope if you sent embed. A create is not idempotent: every successful call books a new appointment, so never retry it automatically after a timeout or a 5xx. Search for the appointment first.

Terminal window
curl -X POST https://open-api.shepherd.vet/pav2/open-api-appointments/write \
-H "Content-Type: application/json" \
-H "X-Integration-Public-Key: $SHEPHERD_PUBLIC_KEY" \
-H "X-Integration-Private-Key: $SHEPHERD_PRIVATE_KEY" \
-H "X-Clinic-Id: $SHEPHERD_CLINIC_ID" \
-d '{
"startDate": "2026-05-22T14:30:00Z",
"endDate": "2026-05-22T15:00:00Z",
"providerId": "5a8d0cfc-c7c4-44a0-bdab-44f4e5f6b219",
"appointmentTypeId": "8fc9c6d1-a829-4b93-a5ea-1c83db96a1b4",
"clientId": "e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6",
"patientIds": ["a1b2c3d4-e5f6-7890-abcd-ef0123456789"],
"visitReason": "Annual wellness exam"
}'
PUT /pav2/open-api-appointments/{id}/update

Updates an existing appointment. This is a PUT, so it is a full replacement: send the complete appointment representation, not just the fields you changed. Any editable field omitted from the body is cleared. See Updating records for the general rule and the read-merge-write pattern that keeps it safe.

Required on update: startDate, endDate, and providerId.

The remaining editable fields are clientId, patientIds, appointmentTypeId, appointmentStatusId, visitReason, appointmentCancellationReasonId, cancellationNote, sendEmailNotification, and sendSmsNotification. The same time rules as create apply: 5-minute boundaries, end after start, 24 hours at most.

What omission does on this endpoint:

  • patientIds omitted removes every patient from the appointment. The record you read has no patientIds field; build it from appointmentPatients[].patientId and resend it even when the patients have not changed.
  • appointmentStatusId omitted resets the status to upcoming. An appointment that was checked in or completed goes back to upcoming. Resend the current status.
  • appointmentTypeId, clientId, visitReason, cancellationNote, and appointmentCancellationReasonId omitted become null.

To change one thing, read the appointment with {"ids": "<id>", "rpp": 1}, copy every editable field from it (mapping patientIds as above), apply your change, and send the whole body.

Returns 204 No Content with an empty body on success. Treat any 2xx as success and don’t try to parse a body. A 404 means the id does not resolve within the clinic named by X-Clinic-Id.

Appointment-adjacent data lives on its own endpoints, each following the same list / write conventions as the parent resource.

EndpointPurpose
/pav2/open-api-appointment-notes/writeFree-form notes attached to an appointment. Write only; there is no list endpoint for appointment notes.
/pav2/open-api-appointment-statusesStatus taxonomy (scheduled, checked-in, in-room, completed, no-show).
/pav2/open-api-appointment-typesType taxonomy (wellness, dental, surgery, recheck, etc.).
/pav2/open-api-appointment-cancellation-reasonsCancellation reason taxonomy used when an appointment is cancelled.
  • Conventions: pagination, embed, sort, and date-window rules.
  • Patients: the pet the appointment is scheduled for.
  • SOAP records: clinical notes written against an appointment.
  • Errors: HTTP status codes and the error body shapes.