# Calendars

> List the calendars and task lists from the connected sources of the user. Use the ids to sync events.

Source: https://reassign.dev/reference/calendars/

Use this endpoint to list the calendars and task lists that the user connected to Reassign. This endpoint is read only.

The machine-readable spec of all public endpoints: [openapi.json](https://reassign.dev/openapi.json).

## The calendar model

A calendar is one calendar or one task list under a connected source, for example a Google account.

- The list holds only calendars from sources that are connected now.
- Task lists (`kind: "tasks"`) are in the same list as the calendars.
- Only a calendar with `writable: true` is a valid sync target.
- The list also holds calendars that are not writable. Use them to show where a read-only event comes from.
- The response has no default flag on each calendar. To find the default calendar, compare `id` with `defaultCalendarId`.
- The list has no copy style. `GET /schedule` gives the default copy style of each writable event calendar as `integrations.sources[].calendars[].copyStyle`. The API cannot change it. Refer to [Scheduling](https://reassign.dev/reference/scheduling.md).

| Field                  | Meaning                                                                                                                                                                      |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `defaultCalendarId`    | The id of the default home calendar of the account. The value is `null` when no default is set, or when the default is not writable or not connected.                        |
| `calendars[].id`       | The unique identifier (UUID) of the calendar.                                                                                                                                |
| `calendars[].name`     | The name from the provider. When the provider gives no name, the value is `Calendar`.                                                                                        |
| `calendars[].provider` | The provider of the source: `google`, `google_tasks`, `linear`, `microsoft`, `microsoft_todo`, `ticktick`, or `todoist`.                                                     |
| `calendars[].kind`     | `calendar` for a calendar, or `tasks` for a task list.                                                                                                                       |
| `calendars[].account`  | The account label of the source. When the source has no label, the value is an empty string.                                                                                 |
| `calendars[].color`    | The color that the user set, as a lowercase `#rrggbb` hex color. If the user set no color, the value is the provider color. The value is `null` when neither color is known. |
| `calendars[].writable` | `true` when the provider lets Reassign write to this calendar.                                                                                                               |

- `defaultCalendarId` (_string | null, required_)
- `calendars` (_object\[], required_)
  - `id` (_string, required_)
  - `name` (_string, required_)
  - `provider` (_"google" | "google\_tasks" | "linear" | "microsoft" | "microsoft\_todo" | "ticktick" | "todoist", required_)
  - `kind` (_"calendar" | "tasks", required_)
  - `account` (_string, required_)
  - `color` (_string | null, required_)
  - `writable` (_boolean, required_)

### Use a calendar id in an event write

An event write (`POST /api/v1/events`) has two calendar fields. Refer to [Events](https://reassign.dev/reference/events.md).

| Field               | Value                                                           | Result                                                                                                                                                                                                                                                                                                                      |
| ------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `calendarId`        | The `id` of a writable, connected calendar                      | Reassign syncs the event to this home calendar.                                                                                                                                                                                                                                                                             |
| `calendarId`        | `null`                                                          | The event stays on the dial only. The account default does not adopt it later. On `update`, Reassign also deletes all the copies in `mirrorCalendarIds`. On `create`, a one-off event can still have copies. A series cannot. Refer to [Rules of the fields](https://reassign.dev/reference/events.md#rules-of-the-fields). |
| `calendarId`        | Omitted                                                         | On `create`, the event goes to the default calendar of the account (`defaultCalendarId`), if one is set. Otherwise it stays on the dial only. On `update`, the home calendar does not change.                                                                                                                               |
| `mirrorCalendarIds` | A list of calendar `id`s                                        | Reassign writes a one-way copy of the event to each calendar.                                                                                                                                                                                                                                                               |
| `mirrorStyles`      | A map from a copy calendar `id` to `full`, `private`, or `busy` | Sets how much each copy shows. Refer to [Copy styles](https://reassign.dev/reference/events.md#copy-styles).                                                                                                                                                                                                                |

- A task list can be the home calendar. A task list cannot be a copy target in `mirrorCalendarIds`.
- `mirrorCalendarIds` must not hold the same `id` two times, and must not hold the home calendar.
- An unknown `id` returns the code `not_found`. A calendar that is not writable returns the code `read_only`. A calendar of a disconnected source is not in the list, and it also returns `read_only`.
- On `update`, Reassign checks only the ids that the op adds. An id that is already on the event can stay, also when its calendar is now read-only or disconnected. You can always remove an id.
- On `update`, `calendarId: null` needs the bare series id and no `scope`. It can carry `start`, `end`, `name`, `notes`, `areaId`, `activityTypeId`, `projectId`, `priority`, and `kind`. With `mirrorCalendarIds`, `mirrorStyles`, `recurrence`, `recurrenceEnd`, `sourceUrl`, or `focusIntervals`, it is a `validation` error. Refer to [Events](https://reassign.dev/reference/events.md).

---

## List the calendars

**GET** `/api/v1/calendars`

Get all the calendars of the connected sources, in the order of the calendar picker. The calendars come first, then the task lists.

- You do not need a connected integration to call this endpoint. With no connected source, the `calendars` list is empty.
- This endpoint takes no parameters. An unknown query parameter returns `422` with the code `validation`.
- The token must have the `events:read` or the `events:write` scope.
- The account needs a trial or Pro plan.

### Response fields

- `defaultCalendarId` (_string | null, required_)
- `calendars` (_object\[], required_)
  - `id` (_string, required_)
  - `name` (_string, required_)
  - `provider` (_"google" | "google\_tasks" | "linear" | "microsoft" | "microsoft\_todo" | "ticktick" | "todoist", required_)
  - `kind` (_"calendar" | "tasks", required_)
  - `account` (_string, required_)
  - `color` (_string | null, required_)
  - `writable` (_boolean, required_)

### Responses

| Status | Codes                 | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200`  | —                     | Success.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `401`  | `unauthorized`        | No Bearer token and no session cookie, or the token is invalid, expired, or revoked. The response carries a `WWW-Authenticate` challenge that points at the protected-resource metadata.                                                                                                                                                                                                                                                                                               |
| `403`  | `permission`, `scope` | A token without `events:read` or `events:write` gets `scope` "This token is not authorized to read events (requires events:read or events:write scope)." An account without Reassign Pro access gets `permission` "Reassign needs an active subscription." The 7-day free trial includes Reassign Pro. A cookie session from another site gets `permission` "Cross-origin request."                                                                                                    |
| `422`  | `validation`          | The request has a query parameter; this operation takes none.                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `429`  | `rate_limited`        | Too many requests. The edge firewall limits each IP to 2000 requests per minute across `/api/v1`; that 429 comes from the edge and can have a body that is not this JSON and no `Retry-After` header. When an edge 429 has no `Retry-After`, retry after 60 seconds. The app also limits each Bearer credential to 600 requests per minute, and some routes limit each user. These limits return this body. This app 429 always has `Retry-After`: retry after that number of seconds. |
| `503`  | `internal`            | A fault on our side. The request is safe to retry.                                                                                                                                                                                                                                                                                                                                                                                                                                     |

**Request** — **GET** `/api/v1/calendars`

**cURL**

```bash
curl "https://reassign.app/api/v1/calendars" \
  -H "Authorization: Bearer rsk_live_YOUR_TOKEN"
```

**JavaScript**

```js
const res = await fetch("https://reassign.app/api/v1/calendars", {
  headers: {
    Authorization: "Bearer rsk_live_YOUR_TOKEN",
  },
});
const data = await res.json();
```

**Response**

```json
{
  "defaultCalendarId": "8a1f0c2e-3b4d-4e5f-9a0b-1c2d3e4f5061",
  "calendars": [
    {
      "id": "8a1f0c2e-3b4d-4e5f-9a0b-1c2d3e4f5061",
      "name": "Work",
      "provider": "google",
      "kind": "calendar",
      "account": "user@example.com",
      "color": "#4285f4",
      "writable": true
    },
    {
      "id": "a1b2c3d4-5e6f-4071-8293-a4b5c6d7e8f9",
      "name": "Holidays",
      "provider": "google",
      "kind": "calendar",
      "account": "user@example.com",
      "color": "#0b8043",
      "writable": false
    }
  ]
}
```
