An API that connects multiple Microsoft services, enabling data access and automation across platforms
The described behavior is consistent with using /calendarView without handling paging and without using delta tokens to track changes over time.
Key points in the current request:
GET https://graph.microsoft.com/v1.0/users/{resource_email}/calendarView
?startDateTime={startDateTime}
&endDateTime={endDateTime}
&$top=50
&$orderby=start/dateTime
Potential causes of “lost” reservations:
- Not paging through all results
-
$top=50limits the response to at most 50 events per call. - If there are more than 50 events in the requested time range, Graph returns an
@odata.nextLinkURL. - If the code does not follow
@odata.nextLinkuntil there is no more link, some events will never be read, and which ones are returned can change between runs as the calendar content changes.
-
- Not using delta query for incremental sync
-
/calendarViewsupports delta queries via/calendarView/delta. - Without delta, each run is a fresh snapshot; if the time window, paging, or ordering changes slightly, events that were previously seen may not be re-fetched or may fall outside the window.
- With delta, the app can:
- Do an initial full sync of the time range.
- Store the
@odata.deltaLink. - On subsequent runs, call the
deltaLinkto get only changes (new, updated, deleted events) and keep its own database consistent.
-
- Time window and time zone handling
- The request uses
Prefer: outlook.timezone="Europe/Paris", which is correct for local times, but thestartDateTimeandendDateTimeparameters must be consistent across runs. - If the cron job changes the window (for example, “next 30 days from now”), events can move out of the window between runs and appear “lost” if the application expects a cumulative list instead of a sliding window.
- The request uses
Recommended changes:
- Implement full paging for
/calendarView- After the first GET, check for
@odata.nextLinkin the response. - Keep calling the
nextLinkURL until it is no longer present. - Aggregate all events from all pages before updating the reservations table.
- After the first GET, check for
- Use delta query to keep reservations in sync
- For each resource mailbox, do an initial sync:
GET https://graph.microsoft.com/v1.0/users/{resource_email}/calendarView/delta ?startDateTime={startDateTime} &endDateTime={endDateTime} - Page through all results (follow
@odata.nextLink). - At the end, store the
@odata.deltaLink. - On subsequent runs, call the stored
deltaLinkinstead of a fresh/calendarViewURL. - Apply the returned changes (added/updated/deleted events) to the local reservations table.
- For each resource mailbox, do an initial sync:
- Clarify business logic for the time window
- If the goal is “all reservations ever made in a given global period,” keep the same fixed
startDateTime/endDateTimeand use delta to track changes. - If the goal is “future reservations only,” ensure the code explicitly removes events that fall before
nowrather than relying on a sliding/calendarViewwindow without state.
- If the goal is “all reservations ever made in a given global period,” keep the same fixed
These changes align with the documented patterns for working with events and synchronizing a calendar view using Microsoft Graph.
References: