Source: https://cli.nylas.com/guides/microsoft-graph-calendar-view

# 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](https://cli.nylas.com/authors/prem-keshari) Senior SRE

Updated June 19, 2026

> **TL;DR:** You ask Microsoft Graph "what's on my calendar next week?" and a plain `GET /me/events` hands back a recurring meeting once, as a `seriesMaster`, with zero generated occurrences. The fix is `GET /me/calendar/calendarView?startDateTime=…&endDateTime=…`, which expands every recurrence into individual instances inside the window. Both query params are required, and the default page size is 10. From the terminal, `nylas calendar events list` reads the same expanded window without you assembling the query string.

> **Related paths:** Read this beside [the Microsoft Graph calendar quickstart](https://cli.nylas.com/guides/microsoft-graph-calendar-quickstart), [Graph API delta query](https://cli.nylas.com/guides/graph-api-delta-query-explained), and [managing an Exchange calendar from the CLI](https://cli.nylas.com/guides/manage-exchange-calendar-cli).

## 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](https://learn.microsoft.com/en-us/graph/api/calendar-list-calendarview), 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 the`Prefer: 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.

```http
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](https://learn.microsoft.com/en-us/graph/api/resources/event) 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`.

```json
{
  "@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](https://learn.microsoft.com/en-us/graph/api/calendar-list-calendarview) 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.

```bash
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"')
done
```

## How 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.

```bash
nylas calendar events list \
  --days 30 \
  --limit 200 \
  --format json
```

## How 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.

```bash
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](https://cli.nylas.com/guides/microsoft-graph-calendar-quickstart) -- auth, scopes, and your first calendar read
- [Graph API delta query explained](https://cli.nylas.com/guides/graph-api-delta-query-explained) -- incremental sync with deltaLink instead of full range reads
- [Microsoft Graph mail query](https://cli.nylas.com/guides/microsoft-graph-mail-query) -- the same OData $filter and $select options applied to messages
- [Manage an Exchange calendar from the CLI](https://cli.nylas.com/guides/manage-exchange-calendar-cli) -- create, list, and update events on Microsoft 365
- [Full command reference](https://cli.nylas.com/docs/commands) -- every email, calendar, and contact command
- [Microsoft Graph calendarView reference](https://learn.microsoft.com/en-us/graph/api/calendar-list-calendarview) -- Microsoft's provider-native docs for query params, paging, and the response shape

## Related hubs

- [Email agents](https://cli.nylas.com/ai-answers/email-agents.md)
- [Calendar agents](https://cli.nylas.com/ai-answers/calendar-agents.md)
- [Scheduling and availability agents](https://cli.nylas.com/ai-answers/scheduling-agents.md)
- [Contacts agents](https://cli.nylas.com/ai-answers/contacts-agents.md)
- [Notetaker and meeting agents](https://cli.nylas.com/ai-answers/notetaker-agents.md)
- [MCP agents](https://cli.nylas.com/ai-answers/mcp-agents.md)
- [Agent accounts](https://cli.nylas.com/ai-answers/agent-accounts.md)
- [Framework and language email agents](https://cli.nylas.com/ai-answers/framework-email-agents.md)
- [Email and calendar API comparisons](https://cli.nylas.com/ai-answers/ai-agent-email-api-comparisons.md)
- [Email integration and automation recipes](https://cli.nylas.com/ai-answers/email-integration-recipes.md)
- [Agent email workflows](https://cli.nylas.com/ai-answers/agent-email-workflows.md)
- [Security for email and calendar agents](https://cli.nylas.com/ai-answers/security-for-email-agents.md)
- [Operations runbooks for agents](https://cli.nylas.com/ai-answers/operations-for-email-calendar-agents.md)

## Try Nylas CLI

Install the CLI with `curl -fsSL https://cli.nylas.com/install.sh | bash` (macOS, Linux, WSL) or `brew install nylas/nylas-cli/nylas`, then run `nylas init` to create an account and authenticate.

**Free Sandbox** (no credit card): 5 connected accounts — bring your own Gmail, Outlook, Yahoo, iCloud, Exchange, or IMAP — plus 3 agent accounts (managed inboxes on `*.nylas.email`). Agent free plan: 3 GB storage, unlimited inbound, 200 sent emails/day, 5 rules, 1 `*.nylas.email` subdomain, and unlimited custom domains. Production is uncapped and requires a credit card: https://www.nylas.com/pricing/
