Appointments
Simple-booking appointments are calendar entries created from AI phone calls, manual operator entry, public /book/[slug] pages, or external calendar sync. Each row has a customer, a start time + duration, an optional employee assignment, and a status.
Available on all workspaces (no module gating). Scopes: bookings.appointments.read / bookings.appointments.write.
Endpoints
/api/workspace/v1/appointments/api/workspace/v1/appointments/{id}/api/workspace/v1/appointments/api/workspace/v1/appointments/{id}/api/workspace/v1/appointments/{id}The appointment object
| Field | Type | Description |
|---|---|---|
| id | integer | Appointment id |
| appointment_number | string | Auto-generated label, e.g. APT-2026-00042 |
| employee_id | integer | Which team member the appointment is with (null for unassigned) |
| customer_name | string | Customer display name |
| customer_email | string | Customer email (used for confirmations) |
| customer_phone | string | Customer phone (NL mobile preferred) |
| appointment_time | string(ISO) | Start of the appointment in UTC |
| duration_minutes | integer | Length in minutes (default 30) |
| timezone | string | Customer timezone (IANA, e.g. "Europe/Amsterdam") |
| status | enum | scheduled | confirmed | pending | pending_payment | completed | cancelled | no_show |
| booked_via | enum | ai_call | manual | public_link | google_calendar — origin of the row |
| cancelled_at | string(ISO) | When the appointment was cancelled |
| cancellation_reason | string | Optional reason supplied at cancel time |
| payment_status | enum | unpaid | pending | paid | failed | refunded |
| notes | string | Free-form operator notes |
| created_at | string(ISO) | When the row was created |
| updated_at | string(ISO) | Last modification |
List with filters
Filter by date range (from / to), status, employee_id, or customer_email. Perfect for "today's schedule" dashboards and nightly calendar exports.
curl "https://app.staffifyai.com/api/workspace/v1/appointments?from=2026-10-10T00:00:00%2B02:00&to=2026-10-10T23:59:59%2B02:00&status=confirmed" \ -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY"
Create an appointment
When the employee's calendar group is linked to an Advanced Booking team member, the time is checked against that member's bookings and time off. An overlap returns 409 with code SLOT_CONFLICT (BOOKING_BUSY: retry after a moment).
curl "https://app.staffifyai.com/api/workspace/v1/appointments" \
-X POST \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Jan de Vries",
"customer_email": "[email protected]",
"customer_phone": "+31612345678",
"appointment_time": "2026-10-15T09:30:00+02:00",
"duration_minutes": 45,
"employee_id": 7,
"timezone": "Europe/Amsterdam",
"notes": "First consult"
}'Reschedule or change status
PATCH unifies reschedule and status changes. Change appointment_time and status in a single call.
curl "https://app.staffifyai.com/api/workspace/v1/appointments/42" \
-X PATCH \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"appointment_time": "2026-10-16T10:00:00+02:00",
"status": "confirmed"
}'Cancel (soft-cancel)
DELETE performs a soft-cancel: status is set to cancelled and cancelled_at is stamped. Row stays in the table for history. Idempotent — a second DELETE returns the already-cancelled row.
Events
appointment.createdappointment.updatedappointment.cancelled