# External calendars

Imported iCal calendars, for syncing bookings with platforms like Airbnb or Booking.com

Endpoint: `https://api.bookingmood.com/v1/external_calendars`, supporting `GET`, `POST`, `DELETE`, `PATCH`. Authenticate with the header `Authorization: Bearer YOUR_API_KEY` (see [authentication](https://www.bookingmood.com/he-IL/api-reference/authentication.md)).

## The external calendar object

| Attribute | Type | Description |
| --- | --- | --- |
| `id` | `uuid` | Unique identifier. |
| `product_id` | `uuid` | Identifier of the related unit. References [`products.id`](https://www.bookingmood.com/he-IL/api-reference/products.md). |
| `created_at` | `timestamp with time zone` | Creation timestamp. Read-only: set by the database. |
| `updated_at` | `timestamp with time zone \| null` | Timestamp at which the calendar last received new events. Read-only: set by the database. |
| `active` | `boolean` | Whether the calendar is synced, i.e. it is not deactivated. Read-only: set by the database. |
| `deactivated_at` | `timestamp with time zone \| null` | Timestamp at which the import was deactivated. |
| `error` | `text \| null` | Error message if the calendar could not be synced. |
| `event_status_sync` | `EventStatusSync` | How to treat incoming events. |
| `ical_url` | `text` | URL of the iCal feed. |
| `last_synced` | `timestamp with time zone \| null` | Timestamp at which the calendar was last synced. |
| `name` | `text` | Name of the calendar. |
| `sync_requested_at` | `timestamp with time zone` | Timestamp at which a sync was last requested. |
| `time_offset` | `integer` | Time offset of the calendar in hours. |
| `tld` | `text` | Top-level domain of the iCal feed URL. |

```json
{
  "id": "00000000-0000-0000-0000-000000000000",
  "product_id": "00000000-0000-0000-0000-000000000000",
  "created_at": "2026-10-30T23:18:45.588Z",
  "updated_at": "2026-10-30T23:18:45.588Z",
  "active": false,
  "deactivated_at": "2026-10-30T23:18:45.588Z",
  "error": "",
  "event_status_sync": "import",
  "ical_url": "https://example.com",
  "last_synced": "2026-10-30T23:18:45.588Z",
  "name": "Nameless iCal import",
  "sync_requested_at": "2026-10-30T23:18:45.588Z",
  "time_offset": 0,
  "tld": ""
}
```

### Types

```typescript
type EventStatusSync = "import" | "CONFIRMED" | "TENTATIVE";
```

### Related resources

Embed related resources with the [`select` parameter](https://www.bookingmood.com/he-IL/api-reference/selecting.md), e.g. `select=*,products!product_id(*)`. Resources related through more than one column need the column as a hint, like `table!column(*)`.

| Embed | Type | Description |
| --- | --- | --- |
| `products!product_id(*)` | `object \| null` | The [product](https://www.bookingmood.com/he-IL/api-reference/products.md) referenced by `product_id`. |
| `calendar_events(*)` | `array` | The [calendar events](https://www.bookingmood.com/he-IL/api-reference/calendar_events.md) referencing this external calendar through `calendar_events.calendar_id`. |

## List external calendars

`GET /v1/external_calendars`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/he-IL/api-reference/filtering.md)). Choose columns and embed related resources with `select` (see [selecting](https://www.bookingmood.com/he-IL/api-reference/selecting.md)), and sort and paginate with `order`, `limit` and `offset` (see [sorting and pagination](https://www.bookingmood.com/he-IL/api-reference/sorting-pagination.md)).

```bash
curl -X GET "https://api.bookingmood.com/v1/external_calendars?select=*&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: A list of external calendars with the selected columns. `206` when the list is a partial range.
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.

## Create external calendars

`POST /v1/external_calendars`

Insert one external calendar or an array of external calendars. The body is a `Partial` external calendar object, so columns with a default can be left out. Read-only attributes can't be written.

```bash
curl -X POST "https://api.bookingmood.com/v1/external_calendars" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "00000000-0000-0000-0000-000000000000",
    "event_status_sync": "import",
    "ical_url": "https://example.com",
    "name": "Nameless iCal import",
    "sync_requested_at": "2026-10-30T23:18:45.588Z",
    "time_offset": 0,
    "tld": ""
  }'
```

Responses:

- `201`: The newly created external calendars with the selected columns.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.

## Delete external calendars

`DELETE /v1/external_calendars`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/he-IL/api-reference/filtering.md)). Without filters, this request deletes all external calendars you have access to. Always filter on at least one column, e.g. `id=eq.{id}`.

```bash
curl -X DELETE "https://api.bookingmood.com/v1/external_calendars?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: The deleted external calendars with the selected columns. `204` without a body when sending the header `Prefer: return=minimal`.
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.

## Update external calendars

`PATCH /v1/external_calendars`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/he-IL/api-reference/filtering.md)). Without filters, this request updates all external calendars you have access to. Always filter on at least one column, e.g. `id=eq.{id}`. The body holds the attributes to change.

```bash
curl -X PATCH "https://api.bookingmood.com/v1/external_calendars?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_status_sync": "import"
  }'
```

Responses:

- `200`: The updated external calendars with the selected columns. `204` without a body when sending the header `Prefer: return=minimal`.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.

Errors have a JSON body with a `code`, `message`, `details` and `hint`. See the [introduction](https://www.bookingmood.com/he-IL/api-reference.md) for more on errors. The full API is described by the OpenAPI spec at https://api.bookingmood.com/v1/openapi.json.
