Skip to main content

Schedule API and webhooks

What this page is — the external API for reading and writing Schedule data, and the events you can subscribe to.

What it is for — integrating: syncing appointments into another system, creating events from one, or reacting when a booking arrives.

The problem it solves — the in-product screens are for people. This is the interface for software.

Base path: /api/v1/ext/schedule · Authentication: an API key, scoped


1. Scopes​

An API key is granted scopes. A call needs the scope its endpoint requires.

ScopeGrants
schedule:calendar:readList the project's calendars
schedule:config:readRead event templates, bookable resources and availability
schedule:event:readRead events and their invitees
schedule:event:writeCreate and update events, and manage invitees — sends real invitations
schedule:event:deleteDelete events
schedule:booking:readRead bookings made through a public booking page
There is no calendar-write scope

Calendars are created in the product, not through the API. schedule:calendar:write does not exist — if you cannot find it, that is why.


2. Endpoints​

MethodPathScope
GET/calendarsschedule:calendar:read
GET/calendars/{id}/eventsschedule:event:read
GET/calendars/{id}/resourcesschedule:config:read
GET/calendars/{id}/availabilityschedule:config:read
GET/event-templatesschedule:config:read
GET/bookingsschedule:booking:read
GET/bookings/{id}schedule:booking:read
POST/eventsschedule:event:write
GET/events/{id}schedule:event:read
PATCH/events/{id}schedule:event:write
DELETE/events/{id}schedule:event:delete
GET/events/{id}/inviteesschedule:event:read
POST/events/{id}/inviteesschedule:event:write
DELETE/events/{id}/invitees/{inviteeId}schedule:event:write
Writing through the API sends real invitations

POST /events and POST /events/{id}/invitees trigger the same notifications the product does. A test run against a live calendar emails real people. Use a calendar with no connection configured while you are developing — see event notifications.

POST requests are idempotent: repeating one with the same idempotency key will not create a second event.


3. Event metadata is per calendar​

An event's fields come from its calendar's template, so the payload for POST /events is not the same for every calendar. Read GET /event-templates to discover what a given calendar expects before writing to it, and send those fields as an object, not as a string containing JSON.

See calendar templates.


4. Webhooks​

Eight events are published.

EventFires when
calendar.createdA calendar is created
calendar.updatedA calendar's settings change
calendar.status_changedA calendar is activated or deactivated
event.createdAn event is created
event.updatedAn event is changed
event.deletedAn event is deleted
event.invitees_addedParticipants are added to an event
booking.createdA member of the public books through a booking page

booking.created is the one most integrations want: it is the only event a person outside your organisation can trigger, and it fires as the booking is written — see what a booking creates.


5. Don't confuse this with…​

The public booking endpointsThe booking page's own endpoints are unauthenticated and rate-limited for visitors. They are not part of this API and are not for integrations
In-app permissionsAPI keys use scopes. The permissions in permissions do not apply to API calls

6. Troubleshooting​

SymptomCause
403 on a callThe key lacks that endpoint's scope
Cannot create a calendarBy design — §1
Custom fields do not appear on the eventThey were sent as a JSON string rather than an object — §3
Real people received test invitations§2. Develop against a calendar with no connection