Calendar API
Calendars and Calendar Groups
Create calendars, organize them into groups, and manage sharing
PrimeCal splits calendar management between /api/calendars and
/api/calendar-groups. This page keeps both route families together so the
full calendar-management workflow is documented in one place.
JWT or user API keyOwned and shared calendarsGroup aliases under /calendars/groupsShare permissions
Source
- Calendar controller:
backend-nestjs/src/calendars/calendars.controller.ts - Calendar groups controller:
backend-nestjs/src/calendars/calendar-groups.controller.ts - Share service:
backend-nestjs/src/calendars/calendar-share.service.ts - DTOs:
backend-nestjs/src/dto/calendar.dto.ts,backend-nestjs/src/dto/calendar-group.dto.ts,backend-nestjs/src/calendars/dto/calendar-sharing.dto.ts,backend-nestjs/src/user-groups/dto/user-group.dto.ts - Entity enums:
backend-nestjs/src/entities/calendar.entity.ts
Authentication and Permissions
- All endpoints on this page require authentication.
- Ownership or share permissions are enforced in the service layer.
- Share operations use
read,write, andadminpermission levels. - Calendar access is resolved through
CalendarShare: ownership, direct user shares (principalType=user), and people-group shares (principalType=group). If more than one path grants access, the highest permission wins:admin>write>read. - Calendar deletion is a soft delete.
- Group deletion does not delete calendars inside the group.
Endpoint Reference
Calendars
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
POST | /api/calendars | Create a calendar. | Body: name,description,color,icon,visibility,groupId,ownerGroupId,groupPermission,rank | JWT or user API key | calendars/calendars.controller.ts |
GET | /api/calendars | List owned and shared calendars. | None | JWT or user API key | calendars/calendars.controller.ts |
GET | /api/calendars/:id | Get one calendar. | Path: id | JWT or user API key | calendars/calendars.controller.ts |
PATCH | /api/calendars/:id | Update a calendar. | Path: id, body: partial calendar fields | JWT or user API key | calendars/calendars.controller.ts |
DELETE | /api/calendars/:id | Soft-delete a calendar. | Path: id | JWT or user API key | calendars/calendars.controller.ts |
POST | /api/calendars/:id/share | Share a calendar with users. | Path: id, body: userIds,permission | JWT or user API key | calendars/calendars.controller.ts |
DELETE | /api/calendars/:id/share | Unshare a calendar from users. | Path: id, body: userIds | JWT or user API key | calendars/calendars.controller.ts |
POST | /api/calendars/:id/share-groups | Share a calendar with people groups. | Path: id, body: groupIds,permission | JWT or user API key | calendars/calendars.controller.ts |
DELETE | /api/calendars/:id/share-groups | Unshare a calendar from people groups. | Path: id, body: groupIds | JWT or user API key | calendars/calendars.controller.ts |
GET | /api/calendars/:id/shared-users | List users the calendar is shared with. | Path: id | JWT or user API key | calendars/calendars.controller.ts |
GET | /api/calendars/groups | Alias for listing calendar groups. | None | JWT or user API key | calendars/calendars.controller.ts |
POST | /api/calendars/groups | Alias for creating a calendar group. | Body: name,isVisible | JWT or user API key | calendars/calendars.controller.ts |
Calendar Groups
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
POST | /api/calendar-groups | Create a group. | Body: name,isVisible | JWT or user API key | calendars/calendar-groups.controller.ts |
GET | /api/calendar-groups | List groups with accessible calendars. | None | JWT or user API key | calendars/calendar-groups.controller.ts |
PATCH | /api/calendar-groups/:id | Rename a group or toggle visibility. | Path: id, body: name,isVisible | JWT or user API key | calendars/calendar-groups.controller.ts |
DELETE | /api/calendar-groups/:id | Delete a group without deleting its calendars. | Path: id | JWT or user API key | calendars/calendar-groups.controller.ts |
POST | /api/calendar-groups/:id/calendars | Assign calendars to a group. | Path: id, body: calendarIds | JWT or user API key | calendars/calendar-groups.controller.ts |
POST | /api/calendar-groups/:id/calendars/unassign | Remove calendars from a group. | Path: id, body: calendarIds | JWT or user API key | calendars/calendar-groups.controller.ts |
POST | /api/calendar-groups/:id/share | Share all calendars in a group. | Path: id, body: userIds,permission | JWT or user API key | calendars/calendar-groups.controller.ts |
DELETE | /api/calendar-groups/:id/share | Unshare all calendars in a group from users. | Path: id, body: userIds | JWT or user API key | calendars/calendar-groups.controller.ts |
People-Group Calendar Assignment
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
POST | /api/user-groups/:groupId/calendars | Attach one or more existing calendars to a people group. | Path: groupId, body: calendarIds,calendarId,permission | JWT or user API key | calendars/user-group-calendars.controller.ts |
POST | /api/user-groups/:groupId/calendars/create | Create a calendar primarily attached to a people group. | Path: groupId, body: calendar fields plus optional groupPermission | JWT or user API key | calendars/user-group-calendars.controller.ts |
DELETE | /api/user-groups/:groupId/calendars | Detach one or more calendars from a people group. | Path: groupId, body: calendarIds or legacy calendarId | JWT or user API key | calendars/user-group-calendars.controller.ts |
DELETE | /api/user-groups/:groupId/calendars/:calendarId | Detach a calendar from a people group without deleting it. | Path: groupId,calendarId | JWT or user API key | calendars/user-group-calendars.controller.ts |
Request Shapes
Calendar DTOs
CreateCalendarDto and UpdateCalendarDto in backend-nestjs/src/dto/calendar.dto.ts
name: required on create, stringdescription: optional stringcolor: optional string, defaults at the entity level to#3b82f6icon: optional stringvisibility: optional enumprivate|shared|publicgroupId: optional number ornullownerGroupId: optional people-group ID ornull; when present, the service also creates a group principal share.groupPermission: optional enumread|write|admin, used withownerGroupIdduring create.rank: optional number, defaults at the entity level to0
Entity notes from backend-nestjs/src/entities/calendar.entity.ts
namelength: 200descriptionlength: 500colorlength: 7iconlength: 10
Sharing DTOs
ShareCalendarDto.userIds: required number arrayShareCalendarDto.permission: required enumread|write|adminUnshareCalendarUsersDto.userIds: required unique integer array, max 100 items, minimum1ShareCalendarGroupsDto.groupIds: required unique integer array, max 100 items, minimum1ShareCalendarGroupsDto.permission: required enumread|write|adminUnshareCalendarGroupsDto.groupIds: required unique integer array, max 100 items, minimum1
Entity notes from CalendarShare
principalType:user|groupprincipalId: user ID or people-group ID based onprincipalTypeuserId: retained for direct user-share compatibility and legacy joins- Unique key:
(calendarId, principalType, principalId)
Group DTOs
CreateCalendarGroupDto and UpdateCalendarGroupDto in backend-nestjs/src/dto/calendar-group.dto.ts
name: required on create, minimum 2 charsisVisible: optional booleanAssignCalendarsToGroupDto.calendarIds: required number arrayShareCalendarGroupDto.userIds: required number arrayShareCalendarGroupDto.permission: required enumread|write|admin
Example Calls
Create a calendar
curl -X POST "$PRIMECAL_API/api/calendars" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Family",
"description": "Shared household planning",
"color": "#14b8a6",
"visibility": "private",
"rank": 10
}'
Create a group and assign calendars
curl -X POST "$PRIMECAL_API/api/calendar-groups" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Late Family",
"isVisible": true
}'
curl -X POST "$PRIMECAL_API/api/calendar-groups/3/calendars" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"calendarIds": [5, 7]
}'
Share a calendar
curl -X POST "$PRIMECAL_API/api/calendars/5/share" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"userIds": [42],
"permission": "write"
}'
Share a calendar with a people group
curl -X POST "$PRIMECAL_API/api/calendars/5/share-groups" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"groupIds": [9],
"permission": "write"
}'
Response and Behavior Notes
- Calendar responses can include group metadata and shared-user summaries.
GET /api/calendarsis the main bootstrap route for the calendar workspace.- Group-shared calendars are returned by
GET /api/calendarsfor accepted group members and behave like regular calendars in color, icon, rank, and visibility handling. /api/calendars/groupsexists as a compatibility alias; the canonical group controller lives at/api/calendar-groups.rankaffects ordering and priority behavior in calendar-oriented views.isTasksCalendarandisReservationCalendarexist at the entity level but are not directly managed through the create/update DTOs documented here.
Best Practices
- Use
GET /api/calendarsandGET /api/calendar-groupstogether when building the left-hand calendar tree. - Prefer User Group API people groups when several calendars or repeated collaborators must stay aligned under the same permission model.
- Treat
DELETE /api/calendars/:idas a soft delete and refresh local state after mutation. - Use
User APIGET /api/users?search=...to power people pickers for share dialogs. - Keep
visibilityand share permissions conceptually separate in clients: visibility is the calendar's exposure model, while sharing grants concrete access to users.