Skip to content

List events

GET
/events
curl --request GET \
--url 'https://calendar.work.optidata.cloud/api/events?datetime_start=2026-08-01%2000%3A00%3A00&datetime_end=2026-08-31%2023%3A59%3A59&organizer=any&name=Sprint&event_id=4167&event_uid=de373eee-9440-4420-a53b-1be5ccd4eb18&include_description=false&include_participants_summary=false&limit=1000' \
--header 'Authorization: Bearer <token>'

Events visible to the authenticated user, across every calendar they can see. Narrow the result with the query parameters below; a call with no filters returns everything up to limit, which is rarely what you want.

For a month view, pass datetime_start and datetime_end. A recurring event inside the window is returned once, with one entry in instances per occurrence that falls inside it.

Search results carry a summary of each event; the full description is omitted unless you ask for include_description=true, which costs an extra round trip on the server.

Search results also carry no attendees (attendees is always empty on a list). For an event card that shows who takes part, pass include_participants_summary=true: each occurrence then carries a participantsSummary with the number of participants and the first three of them (name and avatar). It is read in the same extra round trip as include_description, so asking for both costs one round trip.

To split the events by who organizes them, pass organizer: is_organizer keeps only the occurrences you organize and is_not_organizer only the ones you do not. The filter is checked per occurrence, so it needs both datetime_start and datetime_end: a recurring event comes back with only its matching occurrences in instances, and an event left without any is dropped from the response. In a calendar shared with you, the event’s organizer is compared with you, not with the calendar owner, so an event a delegate creates on the owner’s behalf counts as organized by the owner, not by you. limit applies to the events left after the filter.

With an active filter, only the first max(limit, 1000) events of the range are checked, so a dense calendar can return fewer matching events than exist, or none, even when more match past that cap. Narrow the range for dense calendars.

Every query parameter is validated: an unknown organizer value, a missing date range with an active organizer filter, an invalid limit, a malformed event_id, an unrecognized value of include_description or include_participants_summary, an invalid date or an end before the start returns 422. Any query parameter not listed below is ignored.

datetime_start
string

Only return occurrences that end at or after this moment. Must contain a calendar date (ISO 8601 or Y-m-d H:i:s); text without one, such as today, returns 422. Required when organizer is is_organizer or is_not_organizer.

datetime_end
string

Only return occurrences that start at or before this moment. Must contain a calendar date (ISO 8601 or Y-m-d H:i:s); text without one, such as today, returns 422. Must be at or after datetime_start when both are sent. Required when organizer is is_organizer or is_not_organizer.

organizer
string
default: any
Allowed values: any is_organizer is_not_organizer

Filter the occurrences by your role as organizer:

  • any (default): no filter;
  • is_organizer: only the occurrences you organize;
  • is_not_organizer: only the occurrences you do not organize.

Values are case-sensitive; any other value, an empty value or an array returns 422. is_organizer and is_not_organizer require datetime_start and datetime_end.

name
string

Match events whose title starts with this text. The text is matched literally: quotes, parentheses and words such as OR are part of the title searched, not search operators.

calendar_ids[]
Array<integer>

Restrict the search to these calendars. Repeat the parameter once per calendar (calendar_ids[]=10&calendar_ids[]=454). Omit it to search every calendar the caller can see. Each id must be an integer, and the parameter must be sent as a list (with the brackets); otherwise the call returns 422.

event_id
string
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}:)?[0-9]+$/

Return only the event with this id: digits (4167) or, for an event of a calendar shared with you, the owner’s account id, a colon and the digits (0b9a1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d:4167). An empty value (event_id=) is the same as omitting the parameter; any other value, or an array, returns 422.

event_uid
string

Return only the event with this iCalendar UID — the identifier that stays stable when an event is copied between calendars.

include_description
boolean

Fill in each event’s full description. Off by default. Accepts true, false, 1, 0, yes, no, on and off, in any letter case. An empty value (include_description=) is the same as omitting the parameter (off); any other value, or an array, returns 422.

include_participants_summary
boolean

Add a participantsSummary to each occurrence in instances: the number of participants and the first three of them, for an event card. Off by default; without it the response is unchanged and carries no participantsSummary. See ParticipantsSummary for how the participants are counted and ordered.

The participants are read from the event details, in the same extra round trip on the server as include_description (one round trip when both are on).

Accepts true, false, 1, 0, yes, no, on and off, in any letter case. An empty value (include_participants_summary=) is the same as omitting the parameter (off); any other value, or an array, returns 422.

limit
integer
default: 1000 >= 1

Maximum number of events to return. Must be a positive integer; 0, a negative or a non-integer value returns 422. With an active organizer filter, it applies to the events left after the filter.

Matching events.

Media typeapplication/json
object
events
required
Array<object>

An event and its occurrences. The event itself carries the identifiers; everything about the schedule lives in instances.

object
id
string | null
uid

ICalendar UID. Unlike id, it survives the event being copied between calendars.

string | null
calendarId
required

Calendar the event lives in.

string
originalCalendarId
string | null
invId

Invitation id. Part of the concurrency triple you send back on an update.

string | null
ms

Modification sequence. Send it back unchanged on an update.

integer | null
rev

Revision. Send it back unchanged on an update.

integer | null
nextAlarm
One of:

The next reminder due for the event.

object
nextAlarmAt

When the reminder fires.

string | null
alarmInstStart

Start of the occurrence it belongs to.

string | null
invId
integer | null
instances
required
Array<object>

One occurrence of an event. A one-off event has exactly one; a recurring event has one per occurrence inside the window you asked for.

object
id
string | null
invId

Invitation id. Send it back when updating or rescheduling.

string | null
status
required

CONF confirmed, TENT tentative, CANC cancelled, NEED awaiting an answer.

string
Allowed values: CONF TENT CANC NEED
recurrenceId

Start of this occurrence, for a recurring event.

string | null
name

Title of the event.

string | null
location
string | null
start
required
string
end
required
string
isOrganizer
required

true when the caller owns the event.

boolean
isRecurring
required
boolean
isException
required

true when this occurrence was detached from its series.

boolean
isAllDay
required
boolean
videoConferenceUrl
string | null
description

Filled in on a single-event read; on a list, only when include_description was requested.

string | null
organizer
One of:

Who owns the event.

object
email
string | null
name
string | null
type
One of:

user is somebody with an Optiwork account in the tenant, group a user group, and guest an address outside it.

string
Allowed values: user guest group
avatarUrl
string | null
sentBy

Set when somebody sent the invitation for the organizer.

string | null
recurrenceRule
One of:

The repetition rule as stored. Mirrors the rule you send, in camelCase.

object
frequency
string
Allowed values: DAILY WEEKLY MONTHLY YEARLY
until
string | null
count
integer | null
interval
integer | null
byDay
Array<string> | null
byMonthDay
Array<integer> | null
byMonth
Array<integer> | null
bySetPos
Array<integer> | null
userParticipationStatus
One of:

How an attendee answered. NEEDS-ACTION means they have not answered yet.

string
Allowed values: NEEDS-ACTION ACCEPTED DECLINED TENTATIVE
originalTimezone

Time zone the event was created in, when it differs.

string | null
recurrenceBaseStart
string | null
recurrenceBaseEnd
string | null
attendees
required
Array<object>

Somebody invited to the event.

object
email
string | null
name
string | null
type
One of:

user is somebody with an Optiwork account in the tenant, group a user group, and guest an address outside it.

string
Allowed values: user guest group
avatarUrl
string | null
participationStatus
One of:

How an attendee answered. NEEDS-ACTION means they have not answered yet.

string
Allowed values: NEEDS-ACTION ACCEPTED DECLINED TENTATIVE
optiworkIdentifier
string | null
alarms
required
Array<object>

A reminder, expressed as an offset from the event. isNegative: true means the reminder fires before the moment named by related; the unit fields that do not apply are 0 or null.

object
description
string | null
related

Whether the offset is measured from the start or the end.

string | null
Allowed values: START END
isNegative
boolean
weeks
integer | null
days
integer | null
hours
integer | null
minutes
integer | null
seconds
integer | null
locale
string | null
participantsSummary

Who takes part in one occurrence, summarized for an event card. Present only on a list (GET /events) called with include_participants_summary=true; absent otherwise.

The participants are listed as the event details show them: the organizer first, when the occurrence has one, then the attendees in invitation order. The organizer is not looked up among the attendees, so an organizer who is also listed as an attendee counts twice. An exception occurrence is summarized from its own participants.

Even with the flag on, an occurrence can lack participantsSummary when its participants could not be read, for instance when the event was deleted while the list was being built. Read a missing participantsSummary as unknown, not as zero participants.

object
participantsCount
required

Number of participants of the occurrence: the organizer, when there is one, plus every attendee. 0 when it has none.

integer
participants
required

The first three participants, in the order above. Empty when the occurrence has none.

Array<object>
<= 3 items
object
name
required

The participant’s name or, when it has none, their email address. null when both are missing.

string | null
avatarUrl
required

The participant’s avatar, or null when there is none.

string | null
Examples
{
"events": [
{
"id": "4167",
"uid": "de373eee-9440-4420-a53b-1be5ccd4eb18",
"calendarId": "10",
"nextAlarm": null,
"invId": "4167-4166",
"ms": 20125,
"rev": 20120,
"originalCalendarId": null,
"instances": [
{
"id": "4167",
"invId": "4167-4166",
"status": "CONF",
"recurrenceId": null,
"name": "Sprint review",
"location": "Meeting room 2",
"start": "2026-08-24T14:00:00-03:00",
"end": "2026-08-24T15:00:00-03:00",
"isOrganizer": true,
"isRecurring": false,
"isException": false,
"isAllDay": false,
"videoConferenceUrl": null,
"description": null,
"organizer": {
"email": "jane.doe@acme.example",
"name": "Jane Doe",
"type": "user",
"avatarUrl": null,
"sentBy": null
},
"recurrenceRule": null,
"userParticipationStatus": "ACCEPTED",
"originalTimezone": null,
"recurrenceBaseStart": null,
"recurrenceBaseEnd": null,
"attendees": [],
"alarms": [],
"locale": null
}
]
}
]
}

Missing, malformed or expired authentication key.

Media typeapplication/json

Authentication failures use an error key rather than message.

object
error
required
string
Examples
Examplemissing

No bearer token sent

{
"error": "JWT passport exception: Missing bearer token in request"
}

The query string failed validation.

Media typeapplication/json
object
message
required

The first validation message.

string
errors
required

Validation messages keyed by field name.

object
key
additional properties
Array<string>
Examples

Unknown organizer value (e.g. abc, true, IS_ORGANIZER)

{
"message": "The selected organizer is invalid.",
"errors": {
"organizer": [
"The selected organizer is invalid."
]
}
}

Rate limit exceeded. Retry after the window resets.

Media typeapplication/json

Generic error envelope used by policy, binding and framework failures.

object
message
required

Human-readable description of the failure.

string
Examples
Examplethrottled
{
"message": "Too Many Attempts."
}