Dental PMS
Workflow

Schedule a Patient Appointment

This guide walks through the full workflow for booking a dental appointment — from finding the patient and selecting the right appointment type, to creating the booking and reading the confirmation response.

4 API calls
Patients + Scheduling domains
~5 minutes to complete

Booking a dental appointment is not a single API call — it's a short pipeline across two domains. The Patients domain identifies who is being booked, the Scheduling domain captures what kind of visit it is and when it happens. Each call returns a uuid that you forward into the next request as a foreign key.

A typical client implements this as four sequential steps: search for the patient, fetch the configured appointment types (often cached client-side), POST the new appointment, and finally read the returned object to surface a confirmation in the UI. The right-hand panel updates as you scroll — each stage shows the request you'd send and a sample of what comes back.

1

Find the patient

Start by looking up the patient in the system. Use the query parameter to search by first name, last name, or a partial match across both.

The response returns a paginated list. Each result includes the patient's uuid — you'll need this to book the appointment in step 3.

Tip

If the patient doesn't exist yet, create them first with POST /patients. See the Patients reference for required fields.

GET /patients
# Search patients by name (first, last, or partial match)
curl -X GET "https://api.example.com/api/v1/{org_id}/patients?query=Smith&page=1&page_size=5" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
200 OK · paginated patients
{
  "items": [
    {
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "first_name": "Jane",
      "last_name": "Smith",
      "date_of_birth": "1986-04-12",
      "primary_phone": "+1-415-555-0148",
      "email": "jane.smith@example.com",
      "preferred_provider_uuid": "d4e5f6a7-b8c9-0123-defa-234567890123"
    },
    {
      "uuid": "f0e1d2c3-b4a5-6789-0123-456789abcdef",
      "first_name": "Jonathan",
      "last_name": "Smith",
      "date_of_birth": "1972-11-30",
      "primary_phone": "+1-415-555-0223",
      "email": "j.smith@example.com",
      "preferred_provider_uuid": null
    }
  ],
  "page": 1,
  "page_size": 5,
  "total": 2
}
2

List appointment types

Fetch the practice's configured appointment types. Each type defines the default duration, display color, and whether it requires an exam.

Common types include New Patient Exam, Hygiene / Cleaning, and Emergency Visit. Copy the uuid of the appropriate type for the next step.

You can also filter by ?is_active=true to exclude archived types.

GET /appointment-types
# Filter to only active types so archived ones aren't returned
curl -X GET "https://api.example.com/api/v1/{org_id}/appointment-types?is_active=true" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
200 OK · appointment types
{
  "items": [
    {
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "code": "NPE",
      "name": "New Patient Exam",
      "duration_minutes": 60,
      "color": "#4f46e5",
      "requires_exam": true,
      "is_active": true
    },
    {
      "uuid": "c4d5e6f7-a8b9-0123-cdef-345678901234",
      "code": "HYG",
      "name": "Hygiene / Cleaning",
      "duration_minutes": 45,
      "color": "#059669",
      "requires_exam": false,
      "is_active": true
    },
    {
      "uuid": "e6f7a8b9-c0d1-2345-efab-567890123456",
      "code": "EMG",
      "name": "Emergency Visit",
      "duration_minutes": 30,
      "color": "#dc2626",
      "requires_exam": true,
      "is_active": true
    }
  ],
  "total": 3
}
3

Book the appointment

Create the appointment by posting the patient, appointment type, provider, location, and the desired time window.

Both scheduled_start and scheduled_end are required and must be in ISO 8601 format. The duration between them should match the appointment type's default duration, but can be adjusted for longer procedures.

Conflict detection

The API returns 409 Conflict if the provider or operatory is already booked for the requested time window. Check availability with GET /schedule/availability before booking if needed.

POST /appointments
curl -X POST "https://api.example.com/api/v1/{org_id}/appointments" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "appointment_type_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "location_uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
    "provider_uuid": "d4e5f6a7-b8c9-0123-defa-234567890123",
    "scheduled_start": "2025-05-20T10:00:00",
    "scheduled_end": "2025-05-20T11:00:00",
    "notes": "New patient — first visit"
  }'
4

Read the confirmation

A successful 201 Created response returns the full appointment object. The status field starts as scheduled.

Store the uuid — you'll use it to update status, attach clinical notes, or cancel the appointment later.

uuidUnique identifier for this appointment
statusLifecycle state. Starts as "scheduled", transitions to "confirmed", "arrived", "completed", or "cancelled"
scheduled_start / endThe booked time window in the practice timezone
providerExpanded provider object with name and credentials
201 Created Response
{
  "uuid": "e5f6a7b8-c9d0-1234-efab-345678901234",
  "status": "scheduled",
  "patient": {
    "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "first_name": "Jane",
    "last_name": "Smith"
  },
  "appointment_type": {
    "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "name": "New Patient Exam",
    "duration_minutes": 60,
    "color": "#4f46e5"
  },
  "scheduled_start": "2025-05-20T10:00:00",
  "scheduled_end": "2025-05-20T11:00:00",
  "location": {
    "uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
    "name": "Main Street Dental"
  },
  "provider": {
    "uuid": "d4e5f6a7-b8c9-0123-defa-234567890123",
    "first_name": "Michael",
    "last_name": "Chen",
    "title": "DDS"
  },
  "created_at": "2025-05-10T14:32:00Z"
}