API Reference
Appointments

Appointments API

Manage appointments throughout their full lifecycle — from booking to completion.

Overview

Appointments are the core of GlowScript. Each appointment connects a client to a service, provider, and time slot.

Appointment Status Flow

scheduled → confirmed → checked_in → in_progress → completed
     ↓          ↓           ↓            ↓
 cancelled   cancelled   no_show     cancelled

Data Model

Appointment Object

FieldTypeDescription
idUUIDUnique identifier
medspa_idUUIDOrganization ID
client_idUUIDClient receiving service
service_idUUIDService being performed
provider_idUUIDProvider performing service
room_idUUIDTreatment room (optional)
equipment_idUUIDEquipment required (optional)
scheduled_atDateTimeAppointment start time
duration_minutesIntegerLength of appointment
statusEnumCurrent status
notesStringClient-visible notes
internal_notesStringStaff-only notes
sourceStringBooking source (manual, online, shopify)
created_atDateTimeWhen created
updated_atDateTimeLast modified

Status Values

StatusDescription
scheduledNewly booked, awaiting confirmation
confirmedClient confirmed attendance
checked_inClient has arrived
in_progressService is being performed
completedService finished successfully
cancelledAppointment was cancelled
no_showClient didn't show up

Actions

Get Appointments

Retrieve appointments with optional filters.

import { getAppointments } from '@/lib/actions/appointments'
 
const result = await getAppointments({
  startDate: '2026-02-01',
  endDate: '2026-02-28',
  providerId: 'uuid',  // optional
  clientId: 'uuid',    // optional
  status: ['scheduled', 'confirmed'],  // optional
})
 
if (result.success) {
  console.log(result.data)
}

Parameters:

ParameterTypeRequiredDescription
startDateStringYesStart of date range (YYYY-MM-DD)
endDateStringYesEnd of date range (YYYY-MM-DD)
providerIdUUIDNoFilter by provider
clientIdUUIDNoFilter by client
statusString[]NoFilter by status(es)

Response:

{
  "success": true,
  "data": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "client": {
        "id": "...",
        "first_name": "Jane",
        "last_name": "Smith"
      },
      "service": {
        "id": "...",
        "name": "Botox Treatment",
        "duration_minutes": 30
      },
      "provider": {
        "id": "...",
        "full_name": "Dr. Johnson"
      },
      "scheduled_at": "2026-02-15T10:00:00Z",
      "duration_minutes": 30,
      "status": "confirmed"
    }
  ]
}

Get Single Appointment

Retrieve detailed information about a specific appointment.

import { getAppointment } from '@/lib/actions/appointments'
 
const result = await getAppointment('appointment-uuid')

Response includes:

  • Full client details
  • Service information
  • Provider details
  • Room and equipment (if assigned)
  • Associated consent forms
  • Treatment record (if completed)

Create Appointment

Book a new appointment.

import { createAppointment } from '@/lib/actions/appointments'
 
const result = await createAppointment({
  client_id: 'client-uuid',
  service_id: 'service-uuid',
  provider_id: 'provider-uuid',
  scheduled_at: '2026-02-15T10:00:00Z',
  duration_minutes: 60,
  room_id: 'room-uuid',        // optional
  equipment_id: 'equip-uuid',  // optional
  notes: 'First visit',        // optional
  source: 'manual'             // optional
})

Parameters:

ParameterTypeRequiredDescription
client_idUUIDYesClient ID
service_idUUIDYesService ID
provider_idUUIDYesProvider ID
scheduled_atDateTimeYesStart time (ISO 8601)
duration_minutesIntegerNoOverride service duration
room_idUUIDNoAssign treatment room
equipment_idUUIDNoAssign equipment
notesStringNoClient-visible notes
internal_notesStringNoStaff-only notes
sourceStringNoBooking source

Validations:

  • Provider must be available at requested time
  • Room must be available (if specified)
  • Equipment must be available (if specified)
  • Provider must be certified for the service

Update Appointment

Modify an existing appointment.

import { updateAppointment } from '@/lib/actions/appointments'
 
const result = await updateAppointment('appointment-uuid', {
  scheduled_at: '2026-02-15T14:00:00Z',  // reschedule
  provider_id: 'new-provider-uuid',       // change provider
  notes: 'Updated notes'
})

Update Appointment Status

Change the status of an appointment.

import { updateAppointmentStatus } from '@/lib/actions/appointments'
 
// Check in a client
const result = await updateAppointmentStatus('appointment-uuid', 'checked_in')
 
// Start the service
await updateAppointmentStatus('appointment-uuid', 'in_progress')
 
// Complete the appointment
await updateAppointmentStatus('appointment-uuid', 'completed')

Cancel Appointment

Cancel an appointment with an optional reason.

import { cancelAppointment } from '@/lib/actions/appointments'
 
const result = await cancelAppointment('appointment-uuid', 'Client requested reschedule')

Effects:

  • Sets status to cancelled
  • Records cancellation timestamp
  • Stores cancellation reason
  • Triggers cancellation webhook (if configured)

Mark No-Show

Mark a client as a no-show.

import { markNoShow } from '@/lib/actions/appointments'
 
const result = await markNoShow('appointment-uuid')

Related Actions

Check Provider Availability

Before booking, verify the provider is available.

import { checkProviderAvailability } from '@/lib/actions/scheduling'
 
const result = await checkProviderAvailability(
  'provider-uuid',
  '2026-02-15T10:00:00Z',  // start
  '2026-02-15T11:00:00Z',  // end
)
 
if (result.isAvailable) {
  // Safe to book
}

Get Available Slots

Get all available time slots for a provider on a date.

import { getAvailableSlots } from '@/lib/actions/scheduling'
 
const result = await getAvailableSlots(
  'provider-uuid',
  '2026-02-15',     // date
  60,               // duration in minutes
  15                // slot interval (optional, default 15)
)
 
// Returns array of { slot_start, slot_end }

Webhooks

Appointment events that trigger webhooks:

EventDescription
appointment.createdNew appointment booked
appointment.updatedAppointment modified
appointment.status_changedStatus transition
appointment.cancelledAppointment cancelled
appointment.completedService completed

Best Practices

  1. Always check availability before creating appointments
  2. Use transactions for complex booking flows
  3. Handle conflicts gracefully — race conditions can occur
  4. Set appropriate reminders via SMS/email integrations
  5. Track source for marketing attribution

Error Codes

CodeMessageResolution
PROVIDER_UNAVAILABLEProvider is not available at this timeChoose different time/provider
ROOM_UNAVAILABLERoom is already bookedChoose different room/time
SERVICE_NOT_FOUNDService does not existVerify service ID
CLIENT_NOT_FOUNDClient does not existVerify client ID
INVALID_STATUS_TRANSITIONCannot change status this wayFollow status flow