Skip to the documentation
API

Calendar

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

Operations

Events and invitations, as the Calendar page of the app shows them: list a window, read an event or the one a thread carries, put events on the calendar and change them, call off a meeting, and answer an invitation. A change that invites, updates or cancels attendees, and every answer, goes out by email, so it also needs emails:send.

GET/calendar/events

List occurrences in a window

Scopescalendar:readReads

from and to are REQUIRED. Occurrences are expanded from recurrence rules, so a calendar has no meaningful unbounded listing. A default window would turn an infinite series into a question with no answer. At most a year apart.

Lists your own events: the ones you made and the ones an address of yours organises or attends. For the workspace owner and their keys, an address counts as theirs unless it was given to a teammate. Set includeTeam to true to add the rest of the workspace, apart from events somebody marked private. A member and a narrowed key always get their own view, whatever includeTeam says.

Requires the calendar:read scope.

Query parameters

fromstringRequired

Start of the window.

Formatdate-time
tostringRequired

End of the window, after from and at most 366 days later.

Formatdate-time
timezonestringRequired

IANA zone. Decides what an all-day event means.

includeTeamboolean

Adds the events of the rest of the workspace, apart from the ones marked private. Only the workspace owner and their keys see more with it.

Defaultfalse
qstring

Words to look for in the title, the place and the organiser. Only events that hold every word come back, so search a long window, at most a year, to find an event by name.

Up to 200 characters
limitinteger

Rows per page, 1 to 100.

At least 1At most 100Default25
cursorstring

The previous page's nextCursor, passed back as it came. It is opaque: it holds where the last row sat in this list's order, so a row deleted or edited between pages never breaks the walk, and the next page starts at the first row that sorts after it. A value this list did not hand out is a 400 invalid_cursor.

Returns

A page of occurrences, sorted by start and then by event id, with hasMore and nextCursor. Send the same from, to, timezone and q with every cursor. Nothing in the window is dropped: a series repeats at most once a day, so it gives at most one occurrence per day of the window, and every one is reachable through the pages. The cursor holds the start and event id of the last row, so an event deleted or moved between pages never breaks the walk.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.listEvents()nextmail.calendar.listAllEvents()nextmail.calendar.iterateEvents()
Python
calendar.list_events()calendar.list_all_events()calendar.iterate_events()
Ruby
calendar.list_eventscalendar.list_all_eventscalendar.iterate_events
PHP
calendar->listEventscalendar->listAllEventscalendar->iterateEvents
Go
Calendar.ListEventsCalendar.ListAllEventsCalendar.IterateEvents
Java
calendar().listEventscalendar().listAllEventscalendar().iterateEvents
C#
Calendar.ListEventsAsyncCalendar.ListAllEventsAsyncCalendar.IterateEventsAsync
CLI
openemail calendar list-events
MCP
listCalendarEvents

POST/calendar/events

Create an event

Scopescalendar:writeSends mail

Puts an event on the calendar, as New event on the Calendar page of the app does. start and end are ISO 8601 with a zone, and timezone is the IANA zone the event belongs to, UTC unless you say. recurrence takes an RRULE such as FREQ=WEEKLY;BYDAY=MO, and reminders the minutes before the start.

With attendees, an invitation goes to each of them from the address in from, which has to be one the key or app may send as, so the call also needs emails:send. sendInvites: false keeps the change to your own calendar.

Requires the calendar:write scope.

Request body

summarystringRequired

The title, 1 to 255 characters.

1 to 255 characters
descriptionstring

Notes about the event, up to 8,000 characters.

Up to 8000 characters
locationstring

Where it is: a room, an address or a link.

Up to 255 characters
urlstring

A link that belongs to the event.

Up to 2000 charactersFormaturi
meetingUrlstring

A link to the video call, such as a Zoom, Meet or Teams address. It goes into the invitation, so guests see a Join button in their calendar too. Send an empty string to take it off.

Up to 2000 characters
startstringRequired

When it starts, a Date or ISO 8601 with a zone.

Formatdate-time
endstringRequired

When it ends, after start and at most two years later.

Formatdate-time
allDayboolean

Whether it fills whole days. start and end then mark the days.

timezonestring

The IANA zone the event belongs to, UTC unless you say.

1 to 64 characters
recurrencestring

An RRULE such as FREQ=WEEKLY;BYDAY=MO when it repeats.

Up to 512 characters
attendeesobject[]

Up to 200 people to invite, each { email, name?, optional? }.

Up to 200 items
emailstringRequired
Up to 320 charactersFormatemail
namestring
Up to 128 characters
optionalboolean
remindersobject[]

Up to five reminders, each { minutesBefore, action? }.

Up to 5 items
minutesBeforeintegerRequired
At least 0At most 40320
actionstring
One of"DISPLAY""EMAIL""AUDIO"
transparencystring

OPAQUE shows you busy and TRANSPARENT free.

One of"OPAQUE""TRANSPARENT"
visibilitystring

PUBLIC, PRIVATE or CONFIDENTIAL.

One of"PUBLIC""PRIVATE""CONFIDENTIAL"
sendInvitesboolean

False keeps the change to your own calendar, and sends nothing.

fromstring

The address the invitations come from. It has to be one the key may send as.

Up to 320 characters

Returns

The event, with its attendees.

Errors

403

from_address_forbidden: the key or app may not send as from. insufficient_scope when invitations would go out and emails:send is missing.

The errors every operation can return400401404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.createEvent()
Python
calendar.create_event()
Ruby
calendar.create_event
PHP
calendar->createEvent
Go
Calendar.CreateEvent
Java
calendar().createEvent
C#
Calendar.CreateEventAsync
CLI
openemail calendar create-event
MCP
createCalendarEvent

GET/calendar/events/{id}

Retrieve an event

Scopescalendar:readReads

The event with its attendees and their responses. rawIcs is omitted. Everything understood in it is already structured here, and /ics serves the document.

Requires the calendar:read scope.

Path parameters

idstringRequired

Event id, the eventId of an occurrence, such as cal_ followed by 24 hex characters.

Returns

The event.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.getEvent()
Python
calendar.get_event()
Ruby
calendar.get_event
PHP
calendar->getEvent
Go
Calendar.GetEvent
Java
calendar().getEvent
C#
Calendar.GetEventAsync
CLI
openemail calendar get-event
MCP
getCalendarEvent

PATCH/calendar/events/{id}

Change an event

Scopescalendar:writeSends mail

Changes an event you organise. A field left out keeps its value, and attendees replaces the whole list. Everyone invited gets the updated invitation.

For a repeating event, scope says which dates change, as the app asks when you edit one date: occurrence changes only the date that starts at occurrenceStart, following that date and every one after it (they become a new series, and the old one ends the day before), and series all of them, with a new start or end moving every date by the same amount.

With attendees, an invitation goes to each of them from the address in from, which has to be one the key or app may send as, so the call also needs emails:send. sendInvites: false keeps the change to your own calendar.

Requires the calendar:write scope.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Request body

summarystring

The title, 1 to 255 characters.

1 to 255 characters
descriptionstring

Notes about the event, up to 8,000 characters.

Up to 8000 characters
locationstring

Where it is: a room, an address or a link.

Up to 255 characters
urlstring

A link that belongs to the event.

Up to 2000 charactersFormaturi
meetingUrlstring

A link to the video call, such as a Zoom, Meet or Teams address. It goes into the invitation, so guests see a Join button in their calendar too. Send an empty string to take it off.

Up to 2000 characters
startstring

When it starts, a Date or ISO 8601 with a zone.

Formatdate-time
endstring

When it ends, after start and at most two years later.

Formatdate-time
allDayboolean

Whether it fills whole days. start and end then mark the days.

timezonestring

The IANA zone the event belongs to, UTC unless you say.

1 to 64 characters
recurrencestring

An RRULE such as FREQ=WEEKLY;BYDAY=MO when it repeats.

Up to 512 characters
attendeesobject[]

Up to 200 people to invite, each { email, name?, optional? }. It replaces the whole list.

Up to 200 items
emailstringRequired
Up to 320 charactersFormatemail
namestring
Up to 128 characters
optionalboolean
remindersobject[]

Up to five reminders, each { minutesBefore, action? }.

Up to 5 items
minutesBeforeintegerRequired
At least 0At most 40320
actionstring
One of"DISPLAY""EMAIL""AUDIO"
transparencystring

OPAQUE shows you busy and TRANSPARENT free.

One of"OPAQUE""TRANSPARENT"
visibilitystring

PUBLIC, PRIVATE or CONFIDENTIAL.

One of"PUBLIC""PRIVATE""CONFIDENTIAL"
sendInvitesboolean

False keeps the change to your own calendar, and sends nothing.

fromstring

The address the invitations come from. It has to be one the key may send as.

Up to 320 characters
scopestring

Which dates the change reaches when the event repeats: occurrence for the one date in occurrenceStart, following for that date and every one after it, or series for all of them. Left out, the change reaches the event or date the id names.

One of"occurrence""following""series"
occurrenceStartstring

The start of the date you mean, as it appears in the list of events. Needed with occurrence and following.

Formatdate-time

Returns

The event as it stands now.

Errors

403

not_organizer: the event was organised by somebody else, so you can only answer it. from_address_forbidden: the key or app may not send as from.

409

event_cancelled: the meeting was called off.

The errors every operation can return400401404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.updateEvent()
Python
calendar.update_event()
Ruby
calendar.update_event
PHP
calendar->updateEvent
Go
Calendar.UpdateEvent
Java
calendar().updateEvent
C#
Calendar.UpdateEventAsync
CLI
openemail calendar update-event
MCP
updateCalendarEvent

DELETE/calendar/events/{id}

Remove an event

Scopescalendar:writeDeletes

Removes an event from the calendar for good, as Remove does in the app. Nobody else is told: to call off a meeting with others in it, use POST /calendar/events/{id}/cancel. For a repeating event, scope and occurrenceStart remove one date or that date and every one after it.

Requires the calendar:write scope.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Query parameters

scopestring

Which dates the change reaches when the event repeats: occurrence for the one date in occurrenceStart, following for that date and every one after it, or series for all of them. Left out, the change reaches the event or date the id names.

One of"occurrence""following""series"
occurrenceStartstring

The start of the date you mean, as it appears in the list of events. Needed with occurrence and following.

Formatdate-time

Returns

The event is gone.

Errors

403

not_organizer: the event was organised by somebody else.

The errors every operation can return400401404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.deleteEvent()
Python
calendar.delete_event()
Ruby
calendar.delete_event
PHP
calendar->deleteEvent
Go
Calendar.DeleteEvent
Java
calendar().deleteEvent
C#
Calendar.DeleteEventAsync
CLI
openemail calendar delete-event
MCP
deleteCalendarEvent

GET/calendar/events/{id}/ics

The event as an .ics document

Scopescalendar:readReads

Served as text/calendar with NO METHOD parameter. A METHOD makes a document actionable (a client seeing method=REQUEST draws accept/decline and can reply to the organiser), and this endpoint has no authority to invite anybody on the workspace behalf. It states what the event currently is.

Requires the calendar:read scope.

Path parameters

idstringRequired

Event id, the eventId of an occurrence.

Returns

200stringtext/calendar

An iCalendar document.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.getEventIcs()
Python
calendar.get_event_ics()
Ruby
calendar.get_event_ics
PHP
calendar->getEventIcs
Go
Calendar.GetEventIcs
Java
calendar().getEventIcs
C#
Calendar.GetEventIcsAsync
CLI
openemail calendar get-event-ics

POST/calendar/events/{id}/cancel

Cancel a meeting

Scopescalendar:writeSends mail

Calls off a meeting you organise, as Cancel meeting does in the app. It stays on the calendar with status CANCELLED, and everyone invited is told it is off, from the address in from, so a meeting with attendees also needs emails:send. For a repeating meeting, scope and occurrenceStart call off one date, or that date and every one after it, and guests get the matching update. The body is optional.

Requires the calendar:write scope.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Request body

fromstring

The address the cancellation comes from. It has to be one the key may send as.

Up to 320 characters
notifyGuestsboolean
scopestring

Which dates the change reaches when the event repeats: occurrence for the one date in occurrenceStart, following for that date and every one after it, or series for all of them. Left out, the change reaches the event or date the id names.

One of"occurrence""following""series"
occurrenceStartstring

The start of the date you mean, as it appears in the list of events. Needed with occurrence and following.

Formatdate-time

Returns

The event, cancelled.

Errors

403

not_organizer: the event was organised by somebody else. from_address_forbidden: the key or app may not send as from.

The errors every operation can return400401404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.cancelEvent()
Python
calendar.cancel_event()
Ruby
calendar.cancel_event
PHP
calendar->cancelEvent
Go
Calendar.CancelEvent
Java
calendar().cancelEvent
C#
Calendar.CancelEventAsync
CLI
openemail calendar cancel-event
MCP
cancelCalendarEvent

POST/calendar/events/{id}/respond

Answer an invitation

Scopescalendar:writeemails:sendSends mail

Accepts, declines or tentatively accepts an invitation, as the buttons of an invitation in the app do. The answer goes to the organiser by email from the invited address the key or app may send as, or from respondingAs when the invitation went to more than one of yours. Send proposedStart and proposedEnd together to propose a new time with your answer, as Propose a new time does in the app: the organiser gets a counter-proposal and decides.

Requires the calendar:write and emails:send scopes.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Request body

responsestringRequired

ACCEPTED, DECLINED or TENTATIVE.

One of"ACCEPTED""DECLINED""TENTATIVE"
respondingAsstring

Which of your invited addresses answers, when there is more than one.

Up to 320 characters
proposedStartstring

A new start to propose with your answer, sent together with proposedEnd.

Formatdate-time
proposedEndstring

The end of the proposed time.

Formatdate-time
notifyGuestsboolean

Returns

The event, with your answer.

Errors

403

not_invited: the event did not invite respondingAs, or any address the key or app may send as.

409

event_cancelled: the meeting was called off. reply_not_sent: the answer could not be sent to the organiser, so nothing changed.

The errors every operation can return400401404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.respondToEvent()
Python
calendar.respond_to_event()
Ruby
calendar.respond_to_event
PHP
calendar->respondToEvent
Go
Calendar.RespondToEvent
Java
calendar().respondToEvent
C#
Calendar.RespondToEventAsync
CLI
openemail calendar respond-to-event
MCP
respondToCalendarEvent

POST/calendar/events/{id}/decline-proposal

Decline a proposed time

Scopescalendar:writeemails:sendSends mail

Keeps the original time of a meeting you organise after a guest proposed another one, as Decline in the proposal on the event does in the app. The guest is told by email from from, or from the organising address. To take the proposed time instead, change the event with PATCH /calendar/events/{id}.

Requires the calendar:write and emails:send scopes.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Request body

attendeestringRequired

The guest whose proposal you decline, by email address.

Up to 320 charactersFormatemail
fromstring

The address the answer is sent from, when it is not the organising address.

Up to 320 characters

Returns

The event, with the proposal cleared.

Errors

403

not_organizer: the event was organised by somebody else. event_read_only: the event comes from a calendar you subscribe to.

404

proposal_not_found: that guest has not proposed a new time. event_not_found: no such event.

The errors every operation can return400401422429500Error catalog

Also available in

TypeScript
nextmail.calendar.declineProposal()
Python
calendar.decline_proposal()
Ruby
calendar.decline_proposal
PHP
calendar->declineProposal
Go
Calendar.DeclineProposal
Java
calendar().declineProposal
C#
Calendar.DeclineProposalAsync
CLI
openemail calendar decline-proposal
MCP
declineCalendarProposal

POST/calendar/events/{id}/hide

Hide an event from your calendar

Scopescalendar:writeChanges data

Takes an event off your own calendar and leaves it where it is for everyone else, as Hide from my calendar does in the app. Use it for an invitation that reached you through a shared address, or one you may not remove. It stops its reminders for you too. POST /calendar/events/{id}/unhide brings it back.

Requires the calendar:write scope.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Returns

The event, hidden for you.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.hideEvent()
Python
calendar.hide_event()
Ruby
calendar.hide_event
PHP
calendar->hideEvent
Go
Calendar.HideEvent
Java
calendar().hideEvent
C#
Calendar.HideEventAsync
CLI
openemail calendar hide-event
MCP
hideCalendarEvent

POST/calendar/events/{id}/unhide

Show a hidden event again

Scopescalendar:writeChanges data

Puts an event you hid back on your calendar, as Show on my calendar does on the invitation in the app.

Requires the calendar:write scope.

Path parameters

idstringRequired

The event id from GET /calendar/events.

Returns

The event, on your calendar again.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.unhideEvent()
Python
calendar.unhide_event()
Ruby
calendar.unhide_event
PHP
calendar->unhideEvent
Go
Calendar.UnhideEvent
Java
calendar().unhideEvent
C#
Calendar.UnhideEventAsync
CLI
openemail calendar unhide-event
MCP
hideCalendarEvent

GET/calendar/free-busy

Free and busy times

Scopescalendar:readReads

When the people you name are busy, as Find a time in the event editor of the app shows it. Each address of the workspace shows the busy times of the person who holds it, from their events, the invitations they have not declined, their subscribed calendars and their bookings, without any detail. Add durationMinutes to get suggestions: the first times everyone known is free. A key or app limited to some addresses is refused, since the answer reads whole calendars.

Requires the calendar:read scope.

Query parameters

fromstringRequired

The start of the window.

Formatdate-time
tostringRequired

A free and busy window may span at most 31 days.

Formatdate-time
emailsstringRequired

The addresses to look up, at most 20. An address of the workspace shows when the person who holds it is busy; any other address comes back with known false. Separate them with commas.

timezonestring

IANA zone the suggested times keep to working hours in.

Default"UTC"
durationMinutesinteger

The length of the meeting in minutes. With it, suggestions lists the first times everyone known is free, on weekdays between 09:00 and 17:00 in timezone.

At least 5At most 480

Returns

When each person is busy, and the suggested times.

Errors

422

capability_unsupported: the key or app is limited to some addresses. invalid_parameter: the window, an address or the duration is not valid.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.calendar.freeBusy()
Python
calendar.free_busy()
Ruby
calendar.free_busy
PHP
calendar->freeBusy
Go
Calendar.FreeBusy
Java
calendar().freeBusy
C#
Calendar.FreeBusyAsync
CLI
openemail calendar free-busy
MCP
findMeetingTime

GET/calendar/feeds

List calendar links

Scopescalendar:readReads

The secret links that publish your calendar to other calendar apps, as Share in the calendar settings of the app lists them. Anyone with a link can read what it shows, so treat url and webcalUrl like passwords.

Requires the calendar:read scope.

Returns

Your calendar links.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.listFeeds()
Python
calendar.list_feeds()
Ruby
calendar.list_feeds
PHP
calendar->listFeeds
Go
Calendar.ListFeeds
Java
calendar().listFeeds
C#
Calendar.ListFeedsAsync
CLI
openemail calendar list-feeds
MCP
listCalendarFeeds

POST/calendar/feeds

Create a calendar link

Scopescalendar:writeChanges data

Makes a secret link that publishes your calendar as an iCalendar feed, for Google Calendar (From URL), Outlook (Subscribe from web) or Apple Calendar (New subscription). full shows every detail, busy only the times you are busy. The calendar app checks the link again on its own schedule, usually every few hours.

Requires the calendar:write scope.

Request body

namestringRequired

The name calendar apps show for the calendar, up to 100 characters.

1 to 100 characters
modestringRequired

full for every detail, busy for busy times only.

One of"full""busy"

Returns

The new link.

Errors

409

calendar_feed_limit: you already keep the most links one person may.

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.createFeed()
Python
calendar.create_feed()
Ruby
calendar.create_feed
PHP
calendar->createFeed
Go
Calendar.CreateFeed
Java
calendar().createFeed
C#
Calendar.CreateFeedAsync
CLI
openemail calendar create-feed
MCP
createCalendarFeed

DELETE/calendar/feeds/{id}

Delete a calendar link

Scopescalendar:writeDeletes

Turns a calendar link off for good. Calendar apps that subscribed to it stop getting updates.

Requires the calendar:write scope.

Path parameters

idstringRequired

The calendar link id.

Returns

The link is gone.

Errors

404

calendar_feed_not_found: no link of yours has that id.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.calendar.deleteFeed()
Python
calendar.delete_feed()
Ruby
calendar.delete_feed
PHP
calendar->deleteFeed
Go
Calendar.DeleteFeed
Java
calendar().deleteFeed
C#
Calendar.DeleteFeedAsync
CLI
openemail calendar delete-feed
MCP
deleteCalendarFeed

POST/calendar/feeds/{id}/reset

Reset a calendar link

Scopescalendar:writeChanges data

Replaces the secret in a calendar link, so the old address stops working everywhere it was shared. Paste the new address into the calendar apps you still want to update.

Requires the calendar:write scope.

Path parameters

idstringRequired

The calendar link id.

Returns

The link with its new address.

Errors

404

calendar_feed_not_found: no link of yours has that id.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.calendar.resetFeed()
Python
calendar.reset_feed()
Ruby
calendar.reset_feed
PHP
calendar->resetFeed
Go
Calendar.ResetFeed
Java
calendar().resetFeed
C#
Calendar.ResetFeedAsync
CLI
openemail calendar reset-feed
MCP
resetCalendarFeed

GET/calendar/subscriptions

List calendar subscriptions

Scopescalendar:readReads

The other calendars you subscribe to by link, such as a Google or Outlook calendar address, a team rota or public holidays, as Other calendars in the app lists them. Their events show on your calendar, read-only.

Requires the calendar:read scope.

Returns

Your subscriptions.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.listSubscriptions()
Python
calendar.list_subscriptions()
Ruby
calendar.list_subscriptions
PHP
calendar->listSubscriptions
Go
Calendar.ListSubscriptions
Java
calendar().listSubscriptions
C#
Calendar.ListSubscriptionsAsync
CLI
openemail calendar list-subscriptions
MCP
listCalendarSubscriptions

POST/calendar/subscriptions

Subscribe to a calendar

Scopescalendar:writeChanges data

Adds a calendar by its iCalendar link: an https, http or webcal address, such as the secret address of a Google calendar or a published Outlook calendar. It is read at once, then again about every half hour. name defaults to the name the calendar gives itself.

Requires the calendar:write scope.

Request body

urlstringRequired

The calendar link, https, http or webcal.

1 to 2048 characters
namestring

The name to show, up to 100 characters.

1 to 100 characters
colorstring

The colour of its events, from CALENDAR_COLORS.

One of"blue""sky""teal""green""lime""yellow""orange""red""pink""purple""gray"

Returns

The subscription, with its first events read.

Errors

409

calendar_subscription_exists: you already subscribe to that address. calendar_subscription_limit: you already subscribe to the most calendars one person may.

422

calendar_subscription_url_invalid: not a public https, http or webcal link. calendar_subscription_unreadable: nothing at the address read as a calendar.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.calendar.createSubscription()
Python
calendar.create_subscription()
Ruby
calendar.create_subscription
PHP
calendar->createSubscription
Go
Calendar.CreateSubscription
Java
calendar().createSubscription
C#
Calendar.CreateSubscriptionAsync
CLI
openemail calendar create-subscription
MCP
subscribeToCalendar

PATCH/calendar/subscriptions/{id}

Change a calendar subscription

Scopescalendar:writeChanges data

Renames a subscription or gives it another colour.

Requires the calendar:write scope.

Path parameters

idstringRequired

The subscription id.

Request body

namestring

The new name, up to 100 characters.

1 to 100 characters
colorstring

The new colour, from CALENDAR_COLORS.

One of"blue""sky""teal""green""lime""yellow""orange""red""pink""purple""gray"

Returns

The subscription as it stands now.

Errors

404

calendar_subscription_not_found: no subscription of yours has that id.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.calendar.updateSubscription()
Python
calendar.update_subscription()
Ruby
calendar.update_subscription
PHP
calendar->updateSubscription
Go
Calendar.UpdateSubscription
Java
calendar().updateSubscription
C#
Calendar.UpdateSubscriptionAsync
CLI
openemail calendar update-subscription
MCP
updateCalendarSubscription

DELETE/calendar/subscriptions/{id}

Unsubscribe from a calendar

Scopescalendar:writeDeletes

Removes a subscription and every event it brought onto your calendar.

Requires the calendar:write scope.

Path parameters

idstringRequired

The subscription id.

Returns

The subscription is gone.

Errors

404

calendar_subscription_not_found: no subscription of yours has that id.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.calendar.deleteSubscription()
Python
calendar.delete_subscription()
Ruby
calendar.delete_subscription
PHP
calendar->deleteSubscription
Go
Calendar.DeleteSubscription
Java
calendar().deleteSubscription
C#
Calendar.DeleteSubscriptionAsync
CLI
openemail calendar delete-subscription
MCP
unsubscribeFromCalendar

POST/calendar/subscriptions/{id}/refresh

Refresh a calendar subscription

Scopescalendar:writeChanges data

Reads a subscribed calendar again now instead of waiting for the next half-hourly read, and restarts one that stopped after repeated failures.

Requires the calendar:write scope.

Path parameters

idstringRequired

The subscription id.

Returns

The subscription after the read.

Errors

404

calendar_subscription_not_found: no subscription of yours has that id.

429

calendar_subscription_refresh_too_soon: it was read moments ago.

rate_limited: the key or app made more than 600 requests in 60 seconds. Wait for the seconds in Retry-After.

The errors every operation can return400401403422500Error catalog

Also available in

TypeScript
nextmail.calendar.refreshSubscription()
Python
calendar.refresh_subscription()
Ruby
calendar.refresh_subscription
PHP
calendar->refreshSubscription
Go
Calendar.RefreshSubscription
Java
calendar().refreshSubscription
C#
Calendar.RefreshSubscriptionAsync
CLI
openemail calendar refresh-subscription
MCP
refreshCalendarSubscription

GET/threads/{id}/event

The event a thread carries

Scopescalendar:readReads

The calendar event that came with an invitation in the thread, as the invitation card of the reading pane shows it. A thread with no event, or one the key or app does not reach, is a 404. Answer it with POST /calendar/events/{id}/respond.

Requires the calendar:read scope.

Path parameters

idstringRequired

The thread id.

Returns

The event.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.threads.getEvent()
Python
threads.get_event()
Ruby
threads.get_event
PHP
threads->getEvent
Go
Threads.GetEvent
Java
threads().getEvent
C#
Threads.GetEventAsync
CLI
openemail threads get-event
MCP
getCalendarEvent

GET/calendar/imports

List calendar imports

Scopescalendar:readReads

The calendar files and calendars brought in, newest first, each with what it added and what it left out. Paging is keyset: pass nextCursor back as cursor while hasMore is true.

Requires the calendar:read scope.

Query parameters

limitinteger

Rows per page, 1 to 100.

At least 1At most 100Default25
cursorstring

The previous page's nextCursor, passed back as it came. It is opaque: it holds where the last row sat in this list's order, so a row deleted or edited between pages never breaks the walk, and the next page starts at the first row that sorts after it. A value this list did not hand out is a 400 invalid_cursor.

Returns

One page of calendar imports.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.listImports()nextmail.calendar.listAllImports()nextmail.calendar.iterateImports()
Python
calendar.list_imports()calendar.list_all_imports()calendar.iterate_imports()
Ruby
calendar.list_importscalendar.list_all_importscalendar.iterate_imports
PHP
calendar->listImportscalendar->listAllImportscalendar->iterateImports
Go
Calendar.ListImportsCalendar.ListAllImportsCalendar.IterateImports
Java
calendar().listImportscalendar().listAllImportscalendar().iterateImports
C#
Calendar.ListImportsAsyncCalendar.ListAllImportsAsyncCalendar.IterateImportsAsync
CLI
openemail calendar list-imports
MCP
listCalendarImports

POST/calendar/imports

Import a calendar file

Scopescalendar:writeChanges data

Takes an iCalendar (.ics) file as the request body and queues it. Its events become events of your own that you can edit, and nobody on them is sent anything, now or when you change them later, unless you ask for that on the change. Poll GET /calendar/imports/{id} until status is completed.

The file may be 10 MB and hold 25,000 events. Several calendars in one file are merged, and the report keeps their names. An event whose UID is already in the workspace is skipped and counted, never overwritten, so sending the same file twice adds nothing.

Requires the calendar:write scope.

Query parameters

filenamestring

The name to show for the file in the list of imports.

Up to 255 characters

Request body

Content typetext/calendar, application/octet-stream

binary

Returns

The import, with status queued.

Errors

400

not_a_calendar_file: the body is not an iCalendar file. item_import_empty: the body is empty. too_many_events: the file holds more than 25,000 events.

413

item_import_too_large: the file is over 10 MB.

The errors every operation can return401403404422429500Error catalog

Also available in

TypeScript
nextmail.calendar.importIcs()
Python
calendar.import_ics()
Ruby
calendar.import_ics
PHP
calendar->importIcs
Go
Calendar.ImportIcs
Java
calendar().importIcs
C#
Calendar.ImportIcsAsync
CLI
openemail calendar import-ics

GET/calendar/imports/{id}

Get a calendar import

Scopescalendar:readReads

One calendar import with its counts and its report: the calendars it read, how many events it left out and why, and up to 20 of the events it left out.

Requires the calendar:read scope.

Path parameters

idstringRequired

Calendar import id, iimp_ followed by 24 hex characters.

Returns

The import.

Errors

404

item_import_not_found: no such import.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.calendar.getImport()
Python
calendar.get_import()
Ruby
calendar.get_import
PHP
calendar->getImport
Go
Calendar.GetImport
Java
calendar().getImport
C#
Calendar.GetImportAsync
CLI
openemail calendar get-import
MCP
getCalendarImport

POST/calendar/imports/{id}/undo

Remove what a calendar import added

Scopescalendar:writeDeletes

Deletes every event the import added, changed since or not, and marks the import undone. Nobody is told. Events that were skipped because they were already here are not touched.

Requires the calendar:write scope.

Path parameters

idstringRequired

Calendar import id, iimp_ followed by 24 hex characters.

Returns

The import, with status undone.

Errors

404

item_import_not_found: no such import.

409

item_import_not_undoable: it is still running or was already removed.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.calendar.undoImport()
Python
calendar.undo_import()
Ruby
calendar.undo_import
PHP
calendar->undoImport
Go
Calendar.UndoImport
Java
calendar().undoImport
C#
Calendar.UndoImportAsync
CLI
openemail calendar undo-import
MCP
undoCalendarImport

Objects

CalendarEventobject

objectstringRequired
One of"calendar_event"
idstringRequired
uidstringRequired

The iCalendar UID every copy of the event shares.

sequenceinteger
At least 0
summarystring
Can be null
descriptionstring
Can be null
locationstring
Can be null
urlstring
Can be null
meetingUrlstring

The link to the video call, which the apps show as a Join button.

Can be null
startstringRequired
Formatdate-time
endstringRequired
Formatdate-time
allDayboolean
timezonestring
Can be null
recurrencestring

The RRULE, when it repeats.

Can be null
exdatesstring[]

Occurrences left out: an instant, or a date for an all-day event.

rdatesstring[]

Extra occurrences outside the rule: an instant, or a date for an all-day event.

recurrenceIdstring

For one changed occurrence of a repeating event, the start it replaces.

Can be nullFormatdate-time
subscriptionIdstring

The calendar subscription it comes from, or null for your own calendar.

Can be null
statusstringRequired

CONFIRMED, TENTATIVE or CANCELLED.

transparencystring
visibilitystring
organizerobject
Can be null
emailstring
namestring
Can be null
isOrganizerboolean

Whether you organise it, and so may change it.

hiddenboolean

Whether you hid it from your own calendar with POST /calendar/events/{id}/hide. Only GET /calendar/events/{id} says.

sourcestring
messageIdstring
Can be null
threadIdstring
Can be null
alarmsobject[]
minutesBeforeinteger
actionstring
attendeesobject[]Required
objectstring
One of"calendar_attendee"
emailstring
namestring
Can be null
partstatstring

NEEDS-ACTION, ACCEPTED, DECLINED or TENTATIVE.

rolestring
rsvpboolean
cutypestring
Can be null
respondedAtstring
Can be nullFormatdate-time
proposedStartstring

The start this guest proposed instead, until the organiser answers.

Can be nullFormatdate-time
proposedEndstring
Can be nullFormatdate-time
createdAtstring
Formatdate-time
updatedAtstring
Formatdate-time

CalendarEventHiddenobject

objectstringRequired
One of"calendar_event"
idstringRequired
uidstringRequired

The iCalendar UID. Hiding reaches every date of it.

hiddenbooleanRequired

CalendarFeedobject

objectstringRequired
One of"calendar_feed"
idstringRequired
namestringRequired

The name calendar apps show for the calendar.

modestringRequired

full shows every detail, busy only when you are busy.

One of"full""busy"
urlstringRequired

The https address to paste into a calendar app.

webcalUrlstringRequired

The same address as a webcal link, which opens a calendar app.

readCountintegerRequired

Roughly how often calendar apps have read it.

At least 0
lastReadAtstringRequired
Can be nullFormatdate-time
createdAtstringRequired
Formatdate-time

CalendarFreeBusyobject

objectstringRequired
One of"calendar_free_busy"
fromstringRequired
Formatdate-time
tostringRequired
Formatdate-time
timezonestringRequired
peopleobject[]Required
emailstringRequired
knownbooleanRequired

Whether the address belongs to the workspace, so its times are known.

busyobject[]Required
startstringRequired
Formatdate-time
endstringRequired
Formatdate-time
suggestionsobject[]Required

Times everyone known is free, when durationMinutes was sent.

startstringRequired
Formatdate-time
endstringRequired
Formatdate-time

CalendarImportobject

objectstringRequired
One of"calendar_import"
idstringRequired

iimp_ followed by 24 hex characters.

kindstringRequired
One of"calendar"
sourcestringRequired

file is an upload. The others came with a mailbox import: takeout from a Google Takeout archive, caldav and carddav from the old provider, microsoft from an Outlook sign-in.

One of"file""takeout""caldav""carddav""microsoft"
statusstringRequired

undone means what it brought in was removed again.

One of"uploading""queued""running""completed""failed""cancelled""undone"
fileNamestringRequired
Can be null
fileBytesintegerRequired
At least 0
parentImportIdstringRequired

The mailbox import it came with, when there was one.

Can be null
countsobjectRequired
totalintegerRequired

Items found so far.

At least 0
importedintegerRequired

Items added.

At least 0
mergedintegerRequired

Contacts left as they were because the address book already holds them. Always 0 on a calendar import, where an event that is already here is counted under skipped.

At least 0
skippedintegerRequired

Items left out for a reason given in report.

At least 0
failedintegerRequired
At least 0
reportobjectRequired
collectionsobject[]Required

The calendars or address books the items came from, by their original name.

namestringRequired
itemsintegerRequired
At least 0
skippedRecord<string, integer>Required

How many items were left out, by reason.

samplesobject[]Required

Up to 20 of the items left out.

namestringRequired
reasonstringRequired
One of"uid-taken""no-start""duplicate""limit""invalid""empty"
lastErrorstringRequired
Can be null
undoablebooleanRequired

Whether the undo call would remove anything.

createdAtstringRequired
Formatdate-time
startedAtstringRequired
Can be nullFormatdate-time
finishedAtstringRequired
Can be nullFormatdate-time
undoneAtstringRequired
Can be nullFormatdate-time

CalendarImportListobject

objectstring
One of"list"
hasMoreboolean

True when another page follows. Pass nextCursor back as cursor to read it.

nextCursorstring

An opaque cursor for the next page, or null on the last page. Pass it back unchanged.

Can be null

CalendarOccurrenceobject

objectstringRequired
One of"calendar_occurrence"
eventIdstringRequired
uidstringRequired

The iCalendar UID every copy of the event shares.

startstringRequired
Formatdate-time
endstringRequired
Formatdate-time
allDaybooleanRequired
summarystringRequired
Can be null
locationstringRequired
Can be null
meetingUrlstring

The link to the video call, when it has one.

Can be null
statusstringRequired

CONFIRMED, TENTATIVE or CANCELLED.

transparencystringRequired
isOrganizerbooleanRequired

Whether you organise it, and so may change it.

organizerEmailstringRequired
Can be null
recurringbooleanRequired

Whether this is one occurrence of a repeating event.

myPartstatstringRequired

Your answer to the invitation, when you were invited.

Can be null
attendeeCountintegerRequired
At least 0
subscriptionIdstring

The calendar subscription it comes from, or null for your own calendar.

Can be null

CalendarOccurrenceListobject

objectstring
One of"list"
hasMoreboolean

True when another page follows. Pass nextCursor back as cursor to read it.

nextCursorstring

An opaque cursor for the next page, or null on the last page. Pass it back unchanged.

Can be null

CalendarSubscriptionobject

objectstringRequired
One of"calendar_subscription"
idstringRequired
namestringRequired
urlstringRequired

The https address it is read from.

colorstringRequired
One of"blue""sky""teal""green""lime""yellow""orange""red""pink""purple""gray"
statusstringRequired

active, failing while reads fail and are retried, or stopped after ten failures in a row until you refresh it.

One of"active""failing""stopped"
lastErrorstringRequired

Why the last read failed, if it did.

Can be nullOne of"unreachable""too-large""not-a-calendar""too-many-events"
eventCountintegerRequired
At least 0
lastSyncedAtstringRequired
Can be nullFormatdate-time
lastFetchedAtstringRequired
Can be nullFormatdate-time
createdAtstringRequired
Formatdate-time

DeletedCalendarEventobject

objectstringRequired
One of"calendar_event"
idstringRequired
deletedbooleanRequired
One oftrue

DeletedCalendarFeedobject

objectstringRequired
One of"calendar_feed"
idstringRequired
deletedbooleanRequired
One oftrue

DeletedCalendarSubscriptionobject

objectstringRequired
One of"calendar_subscription"
idstringRequired
deletedbooleanRequired
One oftrue