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:
| Field | What it means |
|---|---|
occurrence_start | Which 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 |
scope | How 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:
| Level | What arrives |
|---|---|
busy | That 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 |
read | Everything about the appointment |
write | The same, and you may change it |
manage | The 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.