Skip to main content

Bookings

Advanced Booking entries (hub_bookings) with a strict status state-machine. Scopes: bookings.entries.read / bookings.entries.write / bookings.entries.delete.

Endpoints

GET /api/workspace/v1/bookings
GET /api/workspace/v1/bookings/{id}
POST /api/workspace/v1/bookings
PATCH /api/workspace/v1/bookings/{id}
POST /api/workspace/v1/bookings/{id}/status
DELETE /api/workspace/v1/bookings/{id}
POST /api/workspace/v1/bookings/{id}/restore
POST /api/workspace/v1/bookings/bulk-delete

Status values

requestedInitial state — customer requested a slot, awaiting confirmation
confirmedSlot fixed and confirmed
in_progressBooking is currently taking place
completedService delivered
invoicedInvoice sent — waiting on payment
paidTerminal — fully paid
cancelledTerminal — cancelled by customer or business
rescheduledTerminal — moved to a fresh booking
rejectedTerminal — request declined
no_showCustomer did not show up

Status transitions

The state-machine is enforced server-side. Invalid transitions return HTTP 422 with INVALID_STATE.

FromAllowed → To
requestedconfirmed, cancelled, rejected
confirmedin_progress, completed, cancelled, rescheduled, no_show
in_progresscompleted, cancelled, no_show
completedinvoiced, cancelled
invoicedpaid, cancelled
no_showinvoiced, completed
paid / cancelled / rescheduled / rejected(terminal — no transitions)

Create a booking

curl "https://app.staffifyai.com/api/workspace/v1/bookings" \
  -X POST \
  -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": 12,
    "customer_id": 501,
    "confirmed_slot_at": "2026-09-25T09:00:00Z",
    "duration_minutes": 60,
    "source": "manual"
  }'

Change status

POST /bookings/{id}/status with a body of { "status": "confirmed" }. For cancellations you can include cancellation_reason and cancelled_by.

curl -X POST "https://app.staffifyai.com/api/workspace/v1/bookings/912/status" \
  -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "confirmed" }'

Delete / restore

Soft-delete moves a booking to a 30-day recycle bin. Requires the separate bookings.entries.delete scope.

Webhooks

  • booking.created
  • booking.updated
  • booking.status_changed (payload includes from_status + to_status)
  • booking.deleted
  • booking.restored
  • booking.payment.paid (auto-invoice generated after Stripe Checkout success)
  • booking.payment.refunded (credit note issued, booking payment_status = refunded)
  • booking.payment.failed (Stripe Checkout expired or declined)

See also

Booking customers — the customer records that bookings reference.

Bookings - Workspace API - Staffify