Guide
Microsoft Graph calendarView Explained
Query the Microsoft Graph calendarView endpoint for events in a date range with recurrences expanded. Compare it to list events and read calendars from the CLI.
Written by Prem Keshari Senior SRE
What is the Microsoft Graph calendarView endpoint?
The calendarView endpoint is a GET to /me/calendar/calendarView?startDateTime={s}&endDateTime={e} that returns the events occurring inside a date range. Its defining behavior is recurrence expansion: a weekly standup shows up as one event per week in the window, each a real event instance you can read or update individually.
Both startDateTime and endDateTime are required query parameters, expressed as ISO 8601 date-time strings. According to the official calendarView list reference, the endpoint "gets the occurrences, exceptions, and single instances of events in a calendar view defined by a time range." The default page size is 10 events. The endpoint is read-only, so it never moves or rewrites events on the calendar it reads.
The request below reads a one-week window and trims the payload to four fields with $select. Sending thePrefer: outlook.timezone header pins the returned start and end values to a named time zone instead of the mailbox default, which removes a whole class of off-by-an-hour bugs.
GET https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2026-06-22T00:00:00&endDateTime=2026-06-29T00:00:00&$select=subject,start,end,type&$top=50
Authorization: Bearer <access_token>
Prefer: outlook.timezone="America/Los_Angeles"How does calendarView differ from GET /me/events?
The split is recurrence handling. GET /me/events returns the recurrence master, typed seriesMaster, plus any one-off exceptions, and never the generated occurrences. calendarView returns the expanded occurrences for the window, so a daily meeting over 7 days appears 7 times rather than once.
The event resource reference documents the four values of the type property: singleInstance, occurrence, exception, and seriesMaster. A plain event list returns seriesMaster for any recurring series, leaving you to expand the recurrence pattern yourself before you can answer "is there a meeting on Wednesday?". calendarView does that expansion server-side, returning occurrence and exception items already placed on their real dates. For a 30-day window with one daily recurrence, that's roughly 30 occurrence objects from calendarView versus a single master from the events list.
| Aspect | GET /me/calendar/calendarView | GET /me/events |
|---|---|---|
| Recurrences | Expanded into occurrences | One seriesMaster only |
| Required params | startDateTime, endDateTime | None |
type returned | occurrence, exception, singleInstance | seriesMaster, singleInstance |
| Best for | "What's scheduled in this range?" | Reading or editing a series definition |
What does a calendarView response look like?
A calendarView response is an OData collection: a value array of event objects plus an optional @odata.nextLink when more pages exist. Each occurrence carries its own id, seriesMasterId, type, and a start/end pair with a dateTime and timeZone.
Because each occurrence is a distinct object, you can act on a single instance without touching the series. The seriesMasterId links every occurrence back to its master, so a script can group instances by series in one pass. The payload below shows two days of a daily standup inside the requested window. Both items have type: occurrence and share one seriesMasterId, and the response is paged at the default 10 events until you raise $top.
{
"@odata.nextLink": "https://graph.microsoft.com/v1.0/me/calendar/calendarView?$skip=10&...",
"value": [
{
"id": "AAMk_occurrence_1",
"seriesMasterId": "AAMk_master",
"type": "occurrence",
"subject": "Daily standup",
"start": { "dateTime": "2026-06-22T09:00:00.0000000", "timeZone": "America/Los_Angeles" },
"end": { "dateTime": "2026-06-22T09:15:00.0000000", "timeZone": "America/Los_Angeles" }
},
{
"id": "AAMk_occurrence_2",
"seriesMasterId": "AAMk_master",
"type": "occurrence",
"subject": "Daily standup",
"start": { "dateTime": "2026-06-23T09:00:00.0000000", "timeZone": "America/Los_Angeles" },
"end": { "dateTime": "2026-06-23T09:15:00.0000000", "timeZone": "America/Los_Angeles" }
}
]
}How do you page and trim a calendarView query?
Two query options control payload size: $top sets the page size and $select limits the fields returned. When a window holds more events than one page, Graph returns @odata.nextLink, an opaque URL you follow verbatim until it stops appearing. The default page is 10 events.
Raising $top cuts round trips: a 50-event week needs five requests at the default 10 but one at $top=50. The calendarView reference lists $select, $top, $skip, and $orderby among the supported OData parameters. Don't hand-build the next URL from $skip yourself; follow @odata.nextLink exactly, because Graph encodes paging state inside it. The loop below walks every page of a one-week view and stops when no nextLink comes back.
url="https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2026-06-22T00:00:00&endDateTime=2026-06-29T00:00:00&\$top=50"
while [ -n "$url" ] && [ "$url" != "null" ]; do
page=$(curl -s -H "Authorization: Bearer $TOKEN" \
-H 'Prefer: outlook.timezone="America/Los_Angeles"' "$url")
echo "$page" | jq '.value[] | {subject, type, start: .start.dateTime}'
url=$(echo "$page" | jq -r '."@odata.nextLink" // "null"')
doneHow do you read the same window from the CLI?
The nylas calendar events list command reads events in a forward window the way calendarView does, with recurrences already expanded into instances. You pass -d/--days for the window and -n/--limit for the count, and the tool handles OAuth, time zones, and paging instead of you assembling a query string and header.
This removes the plumbing a direct call owns: token refresh, the required startDateTime/endDateTime pair, the Prefer header, and @odata.nextLink following. The --days flag defaults to 7 and accepts 0 for no limit; --limit defaults to 10 and auto-paginates past 200. The command below reads the next 30 days, asks for up to 200 events, and emits JSON for a script.
nylas calendar events list \
--days 30 \
--limit 200 \
--format jsonHow do you parse CLI events output with jq?
The --format json flag emits machine-readable output that pipes straight into jq, so a cron job or agent reads occurrences without screen scraping. The three accepted formats are table, json, and yaml; table is the default.
Piping to jq turns a one-line read into a building block for a pipeline. The example below pins the display zone with --timezone, asks for the next 14 days, and projects each event down to a title and start time. A 14-day read for a single calendar typically returns a few dozen events, small enough to inline into a prompt under a few hundred tokens.
nylas calendar events list \
--days 14 \
--limit 200 \
--timezone America/Los_Angeles \
--format json \
| jq '.[] | {title, start}'When should you call the Graph API directly instead?
Call Microsoft Graph directly when you need Microsoft-only controls: a specific calendar group, the $orderby/$filter OData surface, application permissions with Calendars.Read across a tenant, or a web app that already runs the MSAL OAuth flow. Reach for the terminal path for scripts, agent tools, and cron jobs that should also run against Google without a second integration.
The trade-off is ownership, not capability. A direct calendarView integration owns app registration in Azure AD, token refresh, the required date-range params, the Prefer: outlook.timezone header, and @odata.nextLink paging. The CLI owns command selection and output handling while the provider integration sits behind it. For a one-off range read or a cross-provider scheduler, the terminal keeps a short script from turning into a long-lived OAuth client maintained for one endpoint.
Next steps
- Microsoft Graph calendar quickstart -- auth, scopes, and your first calendar read
- Graph API delta query explained -- incremental sync with deltaLink instead of full range reads
- Microsoft Graph mail query -- the same OData $filter and $select options applied to messages
- Manage an Exchange calendar from the CLI -- create, list, and update events on Microsoft 365
- Full command reference -- every email, calendar, and contact command
- Microsoft Graph calendarView reference -- Microsoft's provider-native docs for query params, paging, and the response shape