Keep calendars in step
Push events from a booking or field-service system, and read free/busy back out.
Why anyone does this
The scheduling system that decides when something happens is rarely the calendar people actually look at. Keeping the two in step is what stops somebody being double-booked by a system that could not see the other one.
What a key needs
Grant these and nothing else. A key can never do more than the person who created it, and one that carries only what the job needs is one you can leave running.
The flow
-
Find the calendar to write to
A person has several. Pick once and store the id; do not guess by name on every run, because names change and ids do not.
GET
/v1/calendars -
Ask when everyone is free
Free/busy answers across several people at once and returns busy windows rather than event detail, so it needs no access to what those events actually are.
POST
/v1/freebusy -
Create the event
Times are UTC. The offset a calendar app shows is that app's timezone, so anything scheduling by wall-clock time needs the user's zone from elsewhere.
POST
/v1/calendars/:calendar_id/events -
Change or cancel it later
Cancelling notifies the attendees; deleting does not. Use the one that matches what actually happened.
PATCH
/v1/calendars/:calendar_id/events/:id
The shape of it
Short enough to read in one go, and close enough to run that the gaps are obvious.
# When is everybody free, and book it.
curl -s https://api.veruapis.com/v1/freebusy \
-H "Authorization: Bearer $KEY" \
-d '{"emails":["[email protected]","[email protected]"],
"start":"2026-09-08T08:00:00Z","end":"2026-09-08T17:00:00Z"}'
curl -s https://api.veruapis.com/v1/calendars/$CAL/events \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"summary":"Site visit","starts_at":"2026-09-08T09:00:00Z",
"ends_at":"2026-09-08T10:00:00Z","attendees":["[email protected]"]}'
What catches people out
Every one of these came from somebody getting it wrong.
- Send an Idempotency-Key on creates. A retried booking that creates a second event is the failure people notice.
- Recurring events arrive already expanded, one entry per occurrence, so a listing has no finite end without a window.
- Free/busy is the right call for availability. Reading everyone's events to work it out needs far more access than you need.