The calendar endpoints let an app read and change the calendars somebody has
access to. They are part of the [app API](/docs/api/apps/overview) 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.

## 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](/docs/api/calendar/calendars)
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

- [List calendars](/docs/api/calendar/calendars)
- [List appointments](/docs/api/calendar/events)
- [Create an appointment](/docs/api/calendar/create)
- [Change an appointment](/docs/api/calendar/update)
- [Delete an appointment](/docs/api/calendar/delete)
- [Answer an invitation](/docs/api/calendar/respond)
- [Find a time](/docs/api/calendar/availability)