# Calendar events

Manage events in Bitrix24 calendars: personal, group, and company. You can create, retrieve, update, and delete events, and retrieve the field schema.

Bitrix24 API: `calendar.event.*`
Scope: `calendar`

## Operations

- [Create event](./calendar-events/create.md) — `POST /v1/calendar-events`
- [List events](./calendar-events/list.md) — `GET /v1/calendar-events`
- [Get event](./calendar-events/get.md) — `GET /v1/calendar-events/:id`
- [Update event](./calendar-events/update.md) — `PATCH /v1/calendar-events/:id`
- [Delete event](./calendar-events/delete.md) — `DELETE /v1/calendar-events/:id`
- [Search events](./calendar-events/search.md) — `POST /v1/calendar-events/search`
- [Aggregate events](./calendar-events/aggregate.md) — `POST /v1/calendar-events/aggregate`
- [Event fields](./calendar-events/fields.md) — `GET /v1/calendar-events/fields`
- [Get meeting participation status](./calendar-events/meeting-status-list.md) — `GET /v1/calendar-events/:id/meeting-status`
- [Change meeting participation status](./calendar-events/meeting-status-set.md) — `PUT /v1/calendar-events/:id/meeting-status`

## Key fields

| Field | Description |
|------|---------|
| `type` | Calendar type: `user`, `group`, `company_calendar` |
| `ownerId` | Calendar owner ID. For `type=user` — employee ID from `GET /v1/users`, for `type=group` — workgroup ID |
| `name` | Event title |
| `from` / `to` | Event start and end in ISO 8601 |
| `timezoneFrom` / `timezoneTo` | Event timezone in IANA format (`UTC`). Optional — if omitted, the event uses the timezone of the employee the API key is bound to |
| `skipTime` | All-day event — when `true`, the event covers the calendar days from `from` through `to`, inclusive |
| `sectionId` | Calendar section ID |
| `attendees` | Array of invited employee IDs, used on write (`POST`/`PATCH`). Written only when the same request includes `isMeeting: true`. On read, attendees are returned in the `attendeeList` and `attendeesCodes` fields |
| `rrule` | Recurrence schedule for a recurring event — an object that specifies the recurrence frequency and the bounds of the series |
| `crmFields` | CRM elements the event is linked to: `D_<id>` deal, `C_<id>` contact, `L_<id>` lead, `CO_<id>` company. For an event with no CRM links, the field is returned as `[]` |

Full field list — [`GET /v1/calendar-events/fields`](./calendar-events/fields.md).

## What to know before you start

1. **A calendar is identified by the `type` + `ownerId` pair.** This pair is required both for listing events and for creating them. Events are always tied to a specific calendar, not to the Bitrix24 account as a whole.
2. **Creating an event requires 5 fields:** `type`, `ownerId`, `name`, `from`, `to`. For an all-day event, pass `skipTime: true`: the event covers the calendar days from `from` through `to`, inclusive. Pass the dates of such an event with a time and the offset of the API key owner's timezone, for example `2026-12-10T12:00:00+00:00`. A date without a time can move the event to an adjacent day.
3. **`from` and `to` accept ISO 8601 in any form:** with an offset (`"2026-06-01T10:00:00+00:00"`), in UTC (`"2026-06-01T10:00:00Z"`), or without a zone (`"2026-06-01T10:00:00"`). The response returns ISO 8601 with a timezone offset.
4. **The offset in the response differs from row to row.** The instant in `from` and `to` is exact, while the offset suffix is not the same for every row in a single response — occurrences of a recurring series carry the offset in effect at the start of the series. Parse the value into an instant — `new Date(row.from)` — and convert it to the timezone you need. Hours and minutes read straight from the string can differ from the time the employee sees in the calendar.
5. **An all-day event arrives with the time `00:00:00`.** The calendar day of such an event is the date in the `from` string. Converting the value to another timezone can shift the date to a neighbouring day, so take the day from the string rather than from the resulting instant.
6. **The event timezone is set via `timezoneFrom` / `timezoneTo`.** Pass an IANA name (`UTC`, `Asia/Almaty`). If the parameters are omitted, the event is created in the timezone of the employee who owns the API key.
7. **`PATCH` is partial.** When updating a single field, Vibecode reads the current event state and automatically supplies `type`, `ownerId`, `name`, which Bitrix24 requires on every update.
8. **Attendees are written only when the same request includes `isMeeting: true`.** Without this flag in the same request, the `attendees` array is ignored and the response still reports success — `201` on create, `200` on update, with no error and no warning. This also applies to a `PATCH` on an event that is already a meeting. Attendee IDs are not checked for existence on write — any number becomes an attendee as `U<id>`, so take the IDs from [`GET /v1/users`](/docs/entities/users). To link a contact, deal, lead or company to the event, use `crmFields`, not `attendees`.
9. **Related employees are loaded with the `include` parameter.** Three relations — `owner` by `ownerId`, `host` by `meetingHost`, `attendee` by `attendeeList` — are supported by the [list](./calendar-events/list.md), [get](./calendar-events/get.md) and [search](./calendar-events/search.md) operations and require the `user` scope on the key in addition to `calendar`. For an event in a group calendar that is not a meeting, `meetingHost` holds the workgroup ID and `_included.host` is `null`. In a group calendar, the `host` employee record is returned only when `isMeeting: true`. The event creator is identified by `createdBy`.
10. **Disabling a source is handled by the application, not by the platform.** The entity API is stateless: to stop receiving calendar events, the application stops calling `GET /v1/calendar-events`. The platform stores no "source enabled" flag and does not resume loading based on the application's saved settings. `calendar-events` responses are not cached — Vibecode caches only `GET /v1/users` and `GET /v1/statuses`, see [Caching](/docs/optimization). Stale data after a source is disabled comes from the application's own state, not from the platform.

## Typical scenario

1. Find the calendar owner: [`GET /v1/users`](/docs/entities/users) for a personal calendar, or a workgroup ID for a group calendar.
2. Get upcoming events: [`GET /v1/calendar-events?type=user&ownerId=1`](./calendar-events/list.md).
3. Create a new event or update an existing one: [`POST /v1/calendar-events`](./calendar-events/create.md) / [`PATCH /v1/calendar-events/:id`](./calendar-events/update.md).

## Limits

| Limit | Value |
|-------|----------|
| Maximum records per request | 5000 (`limit ≤ 5000`) |
| Auto-pagination | enabled when `limit > 50` |
| `offset` on large result sets | `limit ≤ 500` recommended when `offset ≥ 2500` |
| Batch requests | up to 50 operations in [`POST /v1/batch`](/docs/batch) |
| Rate limit | shared across the Vibecode API — see [Limits and optimization](/docs/optimization) |

## See also

- [Entity API](/docs/entity-api)
- [Batch](/docs/batch)
- [API reference](/docs/api-reference)

- [Meeting RSVP](./calendar-events/meeting-status.md)

Upcoming events: `GET /v1/calendar-events?type=user&ownerId=N&from=...&to=...`.
