Skip to main content
Use the Mailbox API to keep private calendars and non-sending events for an authorised mailbox. Calendar events do not include participants, recurrence, alerts, invitations, or scheduling messages.
Authorise every request with a Mailbox credential. Use calendar.read for reads. Use calendar.write for creates, updates, and deletes.If your connected-app token has several granted mailboxes, list them with GET /mailbox/mailboxes. Pass the selected mailbox’s returned id as mailbox_id on every request below. Omit mailbox_id for manual mailbox credentials and assigned agent tokens.
1

Create or select a calendar

List calendars before creating another one. Keep the returned cursor unchanged when you request the next page.
Create a private calendar with a local time zone. Retain one Idempotency-Key for the logical create and reuse it after a lost response. Do not send the same body with a new key while the outcome is uncertain.
2

Create an event with a stable UID

Save a caller-held uid before dispatch. Send a local start without an offset, its time_zone, and an ISO 8601 duration.
If the response is uncertain, look up the exact UID with GET /mailbox/calendar-events?uid=.... UID search is eventually consistent, so an empty immediate result does not authorise another create. Keep reconciling the original UID and idempotency key.
3

Change the latest event version

Read the event immediately before an update or delete and retain its ETag. Send that exact value in If-Match. If the mutation returns 409 conflict, read the event again and review the current version before another mutation.
Include If-Match when you delete an event. Deleting an event does not send a cancellation email. Confirm the event before you delete it. To delete a calendar, first remove its events, then read the calendar and send its exact ETag in If-Match. A non-empty calendar returns 409 conflict.
4

Synchronise event state

Call GET /mailbox/calendar-events/changes without since_state to establish a baseline. Then list the current events and call changes again with the baseline state to include edits that happened during the list.For each changes response, read every created or updated ID, remove every destroyed ID, then store its new_state. Continue while has_more is true, always passing the last applied new_state. Changes are coalesced, not a complete activity history. When sync_required is true or a saved state has expired, establish a new baseline and repeat the full list workflow.

Client operation names

Next steps

Mailbox selection and permissions

Synchronise mailbox data