The calendar

.md

How the calendar endpoints are shaped, and why the unit is an occurrence rather than a row.

The calendar endpoints let an app read and change the calendars somebody has access to. They are part of the app API and need a user token, never an API key: a calendar belongs to people, and which people may open it is a decision the environment already made.

Every one of them needs a calendar:* scope on the device and the view_calendar permission on the account. Without the permission you get 403 with calendar_not_permitted, whatever scopes the device holds.

Ids

Every id is a string with a prefix that says what it names: cal_ for a calendar, evt_ for an appointment and ctag_ for a label, such as evt_k7m2p9x4q8r3t6v5. Send them back exactly as you got them, in a URL, a query and a body alike.

A number in their place never finds the row it used to name. In a URL it answers 404, and in calendars[] it is ignored like any calendar you cannot see. In a JSON body calendar_id and tag_ids[] take a string, so a number there is refused with validation_failed.

The unit is an occurrence

A weekly meeting is one row and many appearances. The list returns appearances, so a meeting every Monday for a year comes back as fifty two objects that share an id and differ in starts_at.

That is why every write has to say two more things than you might expect:

FieldWhat it means
occurrence_startWhich appearance you mean, as the moment it originally started. Not the moment it starts now: an appearance somebody already moved is still named by where the rule put it. Leave it out on an appointment that happens once
scopeHow much of the series the write is about: this, following or all. Defaults to this, which is the one that cannot surprise anybody

this on a repeating appointment creates a row of its own standing in for that one appearance. following splits the series in two. all moves the whole thing, keeping the changes anybody made to single appearances where they still make sense.

What you can see

Four levels, from an environment somebody already configured:

LevelWhat arrives
busyThat the hour is taken. title reads "Busy" and every other field is empty or null. Not a rendering choice: the words never leave the server
readEverything about the appointment
writeThe same, and you may change it
manageThe same, and it is yours to rename, share or delete

The level is on every calendar in the calendar list and can_write is on every appointment.

Timezones

Everything on the wire is an instant in ISO 8601, in UTC. What an appointment means is carried by its timezone, which matters for repeating ones: a weekly meeting at nine stays at nine when the clocks change, so its instants shift by an hour twice a year and its timezone does not.

Pages