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.
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.
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.
# 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"{
"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
}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.
# 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"{
"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
}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.
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"
}'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 appointmentstatusLifecycle state. Starts as "scheduled", transitions to "confirmed", "arrived", "completed", or "cancelled"scheduled_start / endThe booked time window in the practice timezoneproviderExpanded provider object with name and credentials{
"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"
}Appointments reference
Full endpoint docs for creating, updating, and cancelling appointments.
Patients reference
Search, create, and manage patient records.
Check availability
Query open time slots before booking to avoid conflicts.
Update appointment status
Transition status through "confirmed", "arrived", and "completed".
# 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"{
"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
}# 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"{
"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
}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"
}'{
"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"
}