Calendar Events
Manage calendar event groups and events. Supports bulk event creation, shared access, and integration with messages.
All endpoints require authentication via the X-API-Key header. See Authentication.
Shared access model
Calendar events and event groups use ownership-based visibility:
- Records with
shared: trueare visible to all users in the organization. - Records with
shared: falseare only visible to the owner.
Deletes cascade by disassociation, not deletion — related records have their reference set to null.
Create an event group
POST /calendar/events/groups
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Group name. |
icon | object | Yes | { type: "image" | "icon" | "emoji", value: string, color: string }. |
shared | boolean | Yes | Whether the group is visible to all org users. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Validation error | Missing or invalid fields. |
List event groups
GET /calendar/events/groups
Returns groups visible to the current user (shared or owned). Each group includes an eventsCount of associated calendar events.
Query parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
search | string | — | Case-insensitive text search on group name. |
Example request
Response
Get an event group
GET /calendar/events/groups/:id
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Event group ID. |
Example request
Response
Standard success envelope with the event group in data.
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid ID | Invalid ObjectId format. |
| 404 | Event group not found | No group with that ID. |
Update an event group
PATCH /calendar/events/groups/:id
All fields are optional. Note: icon.type only allows image or icon when updating (not emoji).
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Event group ID. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | No | |
icon | object | No | { type: "image" | "icon", value: string, color: string }. Note: emoji type not allowed in updates. |
shared | boolean | No |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Validation error | Invalid ObjectId or invalid fields. |
| 404 | Event group not found | No group with that ID. |
Delete an event group
DELETE /calendar/events/groups/:id
Cascade: All calendar events in this group have their eventGroupId set to null. The events themselves are not deleted.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Event group ID. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid ID | Invalid ObjectId format. |
| 404 | Event group not found | No group with that ID. |
Create a calendar event
POST /calendar/events
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Event name. |
date | number | Yes | Unix timestamp in milliseconds. |
color | string | Yes | Display color. |
type | string | Yes | Event type. |
shared | boolean | Yes | Whether the event is visible to all org users. |
description | string | No | |
eventGroupId | string | No | Event group to associate with. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Validation error | Missing or invalid fields. |
Bulk create calendar events
POST /calendar/events/create/bulk
Create multiple calendar events at once. The response does not include the created event IDs.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
events | array | Yes | Array of event objects. Each has the same structure as single create: name, date, color, type, shared (all required), optional description and eventGroupId. |
Example request
Response
Note: data is null — created event IDs are not returned.
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Validation error | events is not an array, or any event fails validation. All-or-nothing — if one event fails, none are created. |
List calendar events
GET /calendar/events
Returns events visible to the current user (shared or owned), sorted by date ascending. Each event includes populated messages and eventGroup.
Query parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
eventGroupId | string | — | Filter by event group. |
startDate | number | — | Unix timestamp (ms). Inclusive lower bound on date. |
endDate | number | — | Unix timestamp (ms). Inclusive upper bound on date. |
search | string | — | Case-insensitive text search on event name. |
Example request
Response
Get a calendar event
GET /calendar/events/:id
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Calendar event ID. |
Example request
Response
Standard success envelope with the calendar event in data.
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid ID | Invalid ObjectId format. |
| 404 | Calendar event not found | No event with that ID. |
Update a calendar event
PATCH /calendar/events/:id
All fields are optional. Set eventGroupId to null to disassociate from a group.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Calendar event ID. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | No | |
date | number | No | Unix timestamp in milliseconds. |
color | string | No | |
type | string | No | |
shared | boolean | No | |
description | string | No | |
eventGroupId | string | null | No | Set to null to disassociate. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Validation error | Invalid ObjectId or invalid fields. |
| 404 | Calendar event not found | No event with that ID. |
Delete a calendar event
DELETE /calendar/events/:id
Cascade: All messages linked to this event have their calendarEventId set to null. The messages themselves are not deleted.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Calendar event ID. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid ID | Invalid ObjectId format. |
| 404 | Calendar event not found | No event with that ID. |
Response envelope
All endpoints use the standard envelope:
Error responses:
data is null for a general failure, such as a database error or an upstream timeout. When the request is rejected because of a specific field, data carries the field(s) at fault instead:
Each issue carries a path (the dotted path into the request body) and a message. A label is added when the path is not self-describing, which today means custom fields only, for example "path": "fields.68b0a1f39c2e4d0012ab77e5", "label": "Class Year". issues is an array, but treat it as holding at most one entry: validation stops at the first failure.