تخطَّ إلى المستندات
Python

openemail.calendar

كل دالّة في مساحة الأسماء هذه: توقيعها ومعلماتها وما تُرجعه ومثال عليها.

الدوالّ

Calendar events found in mail, expanded into occurrences.

calendar.list_events()

List one page of event occurrences inside a time window

الصلاحياتcalendar:readيتصفح النتائج صفحةً صفحة
التوقيع
def list_events(    *,    limit: int | None = None,    cursor: str | None = None,    from_: datetime | str,    to: datetime | str,    timezone: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[CalendarOccurrenceResource]

Expands every event in the workspace into its occurrences between from_= and to= and returns one page of them, sorted by start time and then by event id. A recurring series gives one row per instance in the window, with its excluded dates left out, and every row points back to its event through eventId. The window is required because a repeating series has no end to list up to. Follow nextCursor while hasMore is True, with the same from_=, to= and timezone=, to read every occurrence, or let list_all_events and iterate_events do that walk.

to= must be after from_= and at most 366 days later. A missing bound is a 422 invalid_parameter, while a value that does not parse, a reversed or overlong window, or an unknown zone is a 400 invalid_parameter naming the field. Both bounds take a datetime or an ISO 8601 string. The SDK sends a datetime as a UTC instant, and reads a naive one as local time.

timezone= is an IANA zone and defaults to UTC on the server. It is used to expand any event stored without a zone of its own, which is what decides the day an all day event lands on.

المعلمات

limitint

Occurrences per page, a whole number from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor of the previous page, sent with the same window. It is opaque, so never build one yourself.

from_datetime | strمطلوب

Start of the window, a datetime or an ISO 8601 string, sent as the from query parameter.

todatetime | strمطلوب

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

timezonestr

IANA zone such as Europe/London, at most 64 characters. Defaults to UTC.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

Page[CalendarOccurrenceResource], a dict with items, hasMore and nextCursor. Each item has eventId, uid, start, end, allDay, summary, location, status, transparency, organizerEmail, recurring, myPartstat and attendeeCount, and occurrence['isOrganizer'] is True when you organise the event.

مثال

from datetime import datetime, timedelta, timezone from openemail import openemail start = datetime.now(timezone.utc)page = openemail.calendar.list_events(    from_=start, to=start + timedelta(days=7), timezone='Europe/London', limit=50) for occurrence in page['items']:    print(occurrence['start'], occurrence['summary'], occurrence['myPartstat'] or 'not invited') print(page['hasMore'], page['nextCursor'])

ملاحظات

  • myPartstat is the response recorded for any address this workspace holds on its own domains, or for the addresses a narrowed key covers, and None when none of them is an attendee. A workspace with no address on its own domains matches no attendee, so every row reads None.

  • A narrowed key only sees occurrences whose organiser is one of the addresses it covers or where one of them is an attendee.

  • Cancelled events are not filtered out. Check status for CANCELLED.

  • Nothing in the window is dropped. A series repeats at most once a day, so one series gives at most one row per day of the window, and every one of them is reachable through the pages.

  • The cursor holds the start time and event id of the last row, so an event deleted or moved between pages never breaks the walk. A cursor this list did not hand out is a 400 invalid_cursor.

متاح أيضًا في

API
GET /calendar/events
TypeScript
calendar.listEvents()
Ruby
calendar.list_events
CLI
openemail calendar list-events

calendar.list_all_events()

Collect every occurrence inside a time window into one list

الصلاحياتcalendar:readيتصفح النتائج صفحةً صفحة
التوقيع
def list_all_events(    *,    limit: int | None = None,    cursor: str | None = None,    from_: datetime | str,    to: datetime | str,    timezone: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[CalendarOccurrenceResource]

Walks every page of list_events for one window and returns all of its occurrences in one list, sorted by start time and then by event id. It follows nextCursor until hasMore is False, sending the same from_=, to= and timezone= with each request.

A window of up to 366 days of a busy calendar can hold thousands of occurrences, so prefer iterate_events when you can stop early.

المعلمات

limitint

Page size for each request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the start of the window.

from_datetime | strمطلوب

Start of the window, a datetime or an ISO 8601 string, sent as the from query parameter.

todatetime | strمطلوب

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

timezonestr

IANA zone such as Europe/London, at most 64 characters. Defaults to UTC.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

list[CalendarOccurrenceResource] holding every occurrence in the window, earliest first.

مثال

from openemail import openemail occurrences = openemail.calendar.list_all_events(    from_='2026-10-01T00:00:00Z', to='2026-11-01T00:00:00Z', limit=100) busy = [occurrence for occurrence in occurrences if occurrence['transparency'] == 'OPAQUE']print(len(busy), 'busy blocks in October')

ملاحظات

  • If any page fails the call raises, and the occurrences already fetched are discarded.

متاح أيضًا في

API
GET /calendar/events
TypeScript
calendar.listAllEvents()
Ruby
calendar.list_all_events

calendar.iterate_events()

Stream the occurrences inside a time window one at a time

الصلاحياتcalendar:readيتصفح النتائج صفحةً صفحة
التوقيع
def iterate_events(    *,    limit: int | None = None,    cursor: str | None = None,    from_: datetime | str,    to: datetime | str,    timezone: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[CalendarOccurrenceResource]

Returns a generator over the occurrences in one window that yields them one at a time, earliest first, and fetches the next page only when the current one is used up. Nothing is requested until the loop starts, and leaving the loop with break stops further requests, which makes it the way to find the next free slot or the next meeting without reading the whole window.

The walk ends when hasMore is False, when a page has no nextCursor, or when the server repeats a cursor.

المعلمات

limitint

Page size per request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the start of the window.

from_datetime | strمطلوب

Start of the window, a datetime or an ISO 8601 string, sent as the from query parameter.

todatetime | strمطلوب

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

timezonestr

IANA zone such as Europe/London, at most 64 characters. Defaults to UTC.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

Iterator[CalendarOccurrenceResource], a generator yielding one occurrence per step.

مثال

from datetime import datetime, timedelta, timezone from openemail import openemail start = datetime.now(timezone.utc) for occurrence in openemail.calendar.iterate_events(from_=start, to=start + timedelta(days=30)):    if occurrence['myPartstat'] is None:        continue     print('Next meeting:', occurrence['start'], occurrence['summary'])    break

ملاحظات

  • timeout= bounds each page request on its own, not the whole walk. A page that fails raises out of the for loop, after the occurrences already yielded.

متاح أيضًا في

API
GET /calendar/events
TypeScript
calendar.iterateEvents()
Ruby
calendar.iterate_events

calendar.get_event()

Read an event with its attendees

الصلاحياتcalendar:read
التوقيع
def get_event(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CalendarEventResource

Returns a stored event with its attendees and their responses. What the server understood from the iCalendar data is structured here: recurrence holds the RRULE text, exdates the excluded instances, organizer the organiser and alarms the reminders, each a dict with minutesBefore and action. The raw iCalendar source is not included, and get_event_ics serves the event as a document.

id is the event id, the eventId on an occurrence, and not the iCalendar uid. A recurring series is one event however many occurrences it has, so start and end describe its first instance. messageId and threadId link the event to mail in the mailbox when there is any.

Attendees come back in the order they were added, each with partstat, role, rsvp, cutype and respondedAt. A narrowed key gets a 404 unless one of the addresses it covers organises the event or is on the attendee list, and a key that holds a whole domain covers every address on it.

المعلمات

idstrمطلوب

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

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

CalendarEventResource with id, uid, sequence, summary, description, location, url, start, end, allDay, timezone, recurrence, exdates, status, transparency, visibility, organizer, source, messageId, threadId, alarms, attendees, createdAt and updatedAt. event['isOrganizer'] is True when you organise it, and so may change it.

مثال

from openemail import openemail event = openemail.calendar.get_event('cal_3f9a1c7e5b2d48a06c1e9f4b') print(event['summary'], event['recurrence'] or 'one off') for attendee in event['attendees']:    print(attendee['email'], attendee['partstat'])

ملاحظات

  • status, transparency and visibility carry iCalendar values, and default to CONFIRMED, OPAQUE and PUBLIC.

  • An attendee's partstat defaults to NEEDS-ACTION and role to REQ-PARTICIPANT until a response is recorded.

متاح أيضًا في

API
GET /calendar/events/{id}
TypeScript
calendar.getEvent()
Ruby
calendar.get_event
CLI
openemail calendar get-event

calendar.get_event_ics()

Download an event as an iCalendar document

الصلاحياتcalendar:read
التوقيع
def get_event_ics(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> str

Returns the event serialised as an .ics document, as a str rather than parsed JSON. The server sends it as text/calendar; charset=utf-8 with a download filename built from the event's uid, and the SDK asks for that type and returns the body as text.

The document declares METHOD:PUBLISH, and the content type carries no method parameter. That is deliberate: a REQUEST document makes a calendar client offer accept and decline and reply to the organiser, and this endpoint has no authority to invite anyone. Import it to show what the event currently is, not to send an invitation.

It holds one VEVENT with the attendees and their participation status, the recurrence rule, excluded dates and alarms. Lines end in CRLF and long lines are folded. DTSTAMP is the time of the request, so two downloads of an unchanged event differ on that line.

المعلمات

idstrمطلوب

Event id, the eventId of an occurrence.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

str, the iCalendar text from BEGIN:VCALENDAR to END:VCALENDAR.

مثال

from pathlib import Path from openemail import openemail ics = openemail.calendar.get_event_ics('cal_8d3f0a2b9c4e41f7a6b5c2d1')Path('planning.ics').write_text(ics, newline='') summary = next((line for line in ics.splitlines() if line.startswith('SUMMARY:')), None)print(summary)

ملاحظات

  • Errors still come back as JSON and raise OpenEmailApiError, so a failure never comes back as a string.

  • Timed events are written as UTC instants and all day events as DATE values, never as local times with a TZID.

  • Save it with newline='', as in Path('event.ics').write_text(ics, newline=''), so the CRLF line endings are written as they are on every platform.

  • A narrowed key gets a 404 on the same terms as get_event.

متاح أيضًا في

API
GET /calendar/events/{id}/ics
TypeScript
calendar.getEventIcs()
Ruby
calendar.get_event_ics
CLI
openemail calendar get-event-ics

calendar.create_event()

Put an event on the calendar

الصلاحياتcalendar:write
التوقيع
def create_event(    body: CalendarEventCreate,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CalendarEventResource

Creates an event, as New event on the Calendar page of the app does. start and end take a datetime or an ISO 8601 string with a zone, and timezone is the IANA zone the event belongs to, which decides what an all-day event means. The SDK sends a datetime as a UTC instant, and reads a naive one as local time.

With attendees, an invitation goes to each of them by email from from, which has to be an address the key may send as, so the call also needs emails:send. Send 'sendInvites': False to keep it to your own calendar.

المعلمات

body['summary']strمطلوب

The title, 1 to 255 characters.

body['start']datetime | strمطلوب

When it starts, a datetime or an ISO 8601 string with a zone.

body['end']datetime | strمطلوب

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

body['description']str

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

body['location']str

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

body['url']str

A link that belongs to the event.

body['allDay']bool

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

body['timezone']str

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

body['recurrence']str

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

body['attendees']list[CalendarAttendeeInput]

Up to 200 people to invite, each a dict with email and optionally name and optional, such as {'email': '[email protected]', 'name': 'Ada Lovelace'}.

body['reminders']list[CalendarReminderInput]

Up to five reminders, each a dict with minutesBefore and optionally action, one of DISPLAY, EMAIL and AUDIO, such as {'minutesBefore': 15}.

body['transparency']CalendarTransparency

OPAQUE shows you busy and TRANSPARENT free.

body['visibility']CalendarVisibility

PUBLIC, PRIVATE or CONFIDENTIAL.

body['sendInvites']bool

False keeps the event to your own calendar and sends nothing.

body['from']str

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

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

CalendarEventResource for the new event, with its attendees and their responses.

مثال

from datetime import datetime, timedelta, timezone from openemail import openemail start = datetime(2026, 10, 12, 9, 0, tzinfo=timezone.utc)event = openemail.calendar.create_event(    {        'summary': 'Planning',        'start': start,        'end': start + timedelta(minutes=30),        'attendees': [{'email': '[email protected]', 'name': 'Ada Lovelace'}],        'reminders': [{'minutesBefore': 15}],        'from': '[email protected]',    }) print(event['id'], event['start'], len(event['attendees']))

ملاحظات

  • The SDK does not retry it, because a second call makes a second event and invites everybody again.

  • A key that may not send as from is refused with 403 from_address_forbidden, and an event with attendees and no from with 422 invalid_parameter. Invitations without emails:send are a 403 insufficient_scope, which is_scope_missing on the error reports.

متاح أيضًا في

API
POST /calendar/events
TypeScript
calendar.createEvent()
Ruby
calendar.create_event
CLI
openemail calendar create-event

calendar.update_event()

Change an event

الصلاحياتcalendar:write
التوقيع
def update_event(    id: str,    patch: CalendarEventPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CalendarEventResource

Changes an event you organise. A field you leave out keeps its value, and attendees replaces the whole list. Everyone invited gets the updated invitation by email from from, so a change to an event with attendees needs emails:send too, unless sendInvites is False.

المعلمات

idstrمطلوب

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

patch['summary']str

The title, 1 to 255 characters.

patch['start']datetime | str

When it starts, a datetime or an ISO 8601 string with a zone.

patch['end']datetime | str

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

patch['description']str

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

patch['location']str

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

patch['url']str

A link that belongs to the event.

patch['allDay']bool

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

patch['timezone']str

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

patch['recurrence']str

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

patch['attendees']list[CalendarAttendeeInput]

Up to 200 people to invite, each a dict with email and optionally name and optional. It replaces the whole list.

patch['reminders']list[CalendarReminderInput]

Up to five reminders, each a dict with minutesBefore and optionally action, one of DISPLAY, EMAIL and AUDIO.

patch['transparency']CalendarTransparency

OPAQUE shows you busy and TRANSPARENT free.

patch['visibility']CalendarVisibility

PUBLIC, PRIVATE or CONFIDENTIAL.

patch['sendInvites']bool

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

patch['from']str

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

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

CalendarEventResource as it stands after the change, with sequence one higher.

مثال

from openemail import openemail event = openemail.calendar.update_event(    'cal_3f9a1c7e5b2d48a06c1e9f4b',    {'start': '2026-10-12T10:00:00Z', 'end': '2026-10-12T10:30:00Z'},) print(event['start'], event['sequence'])

ملاحظات

  • The SDK does not retry it, because a retry after a lost response sends the update to everybody again.

  • An event organised by somebody else is refused with 403 not_organizer: answer it with respond_to_event instead. An event the key does not reach is a 404.

متاح أيضًا في

API
PATCH /calendar/events/{id}
TypeScript
calendar.updateEvent()
Ruby
calendar.update_event
CLI
openemail calendar update-event

calendar.delete_event()

Remove an event from the calendar

الصلاحياتcalendar:write
التوقيع
def delete_event(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedCalendarEventResource

Removes an event for good, as Remove does in the app. Nobody else is told, so call off a meeting with others in it with cancel_event instead.

المعلمات

idstrمطلوب

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

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

DeletedCalendarEventResource, such as {'object': 'calendar_event', 'id': 'cal_3f9a1c7e5b2d48a06c1e9f4b', 'deleted': True}.

مثال

from openemail import openemail deleted = openemail.calendar.delete_event('cal_3f9a1c7e5b2d48a06c1e9f4b') print(deleted['id'], deleted['deleted'])

ملاحظات

  • An event organised by somebody else is refused with 403 not_organizer, and an event that is gone or that the key does not reach is a 404.

متاح أيضًا في

API
DELETE /calendar/events/{id}
TypeScript
calendar.deleteEvent()
Ruby
calendar.delete_event
CLI
openemail calendar delete-event

calendar.cancel_event()

Call off a meeting

الصلاحياتcalendar:write
التوقيع
def cancel_event(    id: str,    body: CalendarEventCancel | None = None,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CalendarEventResource

Cancels 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 by email from from, so a meeting with attendees also needs emails:send. body is optional and only carries from.

المعلمات

idstrمطلوب

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

body['from']str

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

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

CalendarEventResource with status CANCELLED.

مثال

from openemail import openemail event = openemail.calendar.cancel_event(    'cal_3f9a1c7e5b2d48a06c1e9f4b', {'from': '[email protected]'}) print(event['summary'], event['status'])

ملاحظات

  • The SDK does not retry it, because a retry sends the cancellation again.

  • An event organised by somebody else is refused with 403 not_organizer.

متاح أيضًا في

API
POST /calendar/events/{id}/cancel
TypeScript
calendar.cancelEvent()
Ruby
calendar.cancel_event
CLI
openemail calendar cancel-event

calendar.respond_to_event()

Answer an invitation

الصلاحياتcalendar:writeemails:send
التوقيع
def respond_to_event(    id: str,    body: CalendarEventAnswer,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CalendarEventResource

Accepts, declines or tentatively accepts an invitation, as the buttons of an invitation do in the app. The answer goes to the organiser by email from the invited address the key may send as, or from respondingAs when the invitation went to more than one of yours, so it needs emails:send as well.

المعلمات

idstrمطلوب

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

body['response']CalendarResponseمطلوب

ACCEPTED, DECLINED or TENTATIVE.

body['respondingAs']str

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

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

يُرجع

CalendarEventResource with your answer on your attendee row.

مثال

from openemail import openemail event = openemail.calendar.respond_to_event(    'cal_3f9a1c7e5b2d48a06c1e9f4b', {'response': 'ACCEPTED'}) for attendee in event['attendees']:    print(attendee['email'], attendee['partstat'])

ملاحظات

  • An event that invited none of the addresses the key may send as is refused with 403 not_invited, and a cancelled meeting with 409 event_cancelled.

  • When the organiser cannot be reached, nothing changes and the call is a 409 reply_not_sent.

متاح أيضًا في

API
POST /calendar/events/{id}/respond
TypeScript
calendar.respondToEvent()
Ruby
calendar.respond_to_event
CLI
openemail calendar respond-to-event