Acuity Scheduling
Twin of the Acuity Scheduling API.
Twin of the Acuity Scheduling API.
| Covers | acuityscheduling.com |
| Auth | HTTP Basic, OAuth 2 |
| Webhooks | Yes |
| Operations | 39 |
Coverage
Appointments with booking, cancellation and reschedule against real
availability, appointment types, calendars and blocks, clients, intake forms,
labels, certificates, orders, products and webhooks. The API sits under
/api/v1 and the OAuth issuer under /oauth2 on the same base, both at the
vendor’s own paths.
Credentials
HTTP Basic takes the numeric user id and the API key. An OAuth bearer works on
the same routes and carries Acuity’s single api-v1 scope. Any well-formed
credential of either kind authenticates by default, so your existing user id and
API key need no change. Set auth.mode to enforced to accept only what the
world knows. See Credentials.
Vendor specific details
- The credential is checked before the router. An unknown path with no credential is a 401, not a 404, so a typo in a URL looks like an auth failure.
- Only the literal lowercase
/api/reaches the API./API/v1/megets the marketing site’s HTML, so.json()raises rather than returning an error you can read. A trailing slash 404s too. - Datetimes come back with a colon-less offset,
2026-08-04T13:00:00-0500. A strict ISO-8601 parser that insists on-05:00will not read them. - Nothing on the query string is refused for its value:
max=abc,minDate=notadateandcalendarID=abcall return 200 with the full list. There is no pagination either, so a list past its cap truncates. admin=trueskips availability, the advance window, email checks and intake field validation, and then makescalendarIDmandatory.
Webhook deliveries are form-encoded and thin: action, id, calendarID and
appointmentTypeID, nothing else, with action as the bare verb like
scheduled. Your receiver has to re-fetch the appointment.
Its own notes
Once a sandbox is running, this twin serves its own operating notes at
{control_url}/veris/manual: the credentials it accepts, the API versions it
serves, and the fault statuses you can arm against it. They are generated from
the same source as its behaviour, so they cannot drift.