Use Microsoft Graph to read and write Outlook calendars: for reliable sync, prefer delta queries combined with change notifications, and reserve ICS subscriptions for simple publish-only scenarios. Authenticate with OAuth and pick delegated or application scopes based on whether a user is present, and always set dateTimeTimeZone and isOnlineMeeting correctly to avoid time-shift and missing-link bugs.
TL;DR:
- Use delegated scopes when a signed in person connects a calendar; background services need application permissions and tenant administrator consent.
- Pair change notifications with delta queries, save each opaque deltaLink, and process @removed entries; ICS subscriptions are read only and refresh less predictably.
- Set dateTimeTimeZone on both event endpoints; online bookings also need isOnlineMeeting and a provider, then verify the returned joinUrl before confirming success.
- Shared calendars sync near instantly only within the same tenant or when shared by an Outlook.com user; other arrangements may rely on slower ICS feeds.
WattleKeep Bookings Connected to Your CalendarWattle’s AI front desk can book appointments through Google Calendar or Cal.com and manage customer conversations across phone, web chat, WhatsApp, and SMS.Explore Wattle
Table of Contents
- What the Outlook calendar API can do and common integration scenarios
- Authentication and permission model: choosing delegated or application flows
- Sync strategies: delta queries, change notifications and ICS subscriptions
- Creating and managing events with correct time zones and online meetings
- Calendar sharing, delegation and how shared calendars sync
- Common pitfalls and troubleshooting checklist
- A minimal developer flow for creating events and keeping sync current
- Direct Graph integration versus middleware: which is worth building
- Another option: let an AI front desk handle the booking instead
- FAQ
- Sources
What the Outlook calendar API can do and common integration scenarios
Microsoft Graph exposes the core operations most integrations need: listing calendars, querying calendarView for a date range, creating, updating and deleting events, and managing calendar groups and categories. The Outlook calendar API overview confirms support for calendar groups, categories, delegation and group calendars, alongside scheduling helpers like findMeetingTimes and room lists.
That range of operations maps onto a handful of recurring scenarios:
- Appointment and booking systems that create events on behalf of customers or staff.
- Calendar overlays that pull multiple calendars into one unified view.
- Reminder and notification pipelines built on event properties.
- Room and resource booking using
emailAddressobjects for places.
One detail worth flagging early: calendar data lives in Exchange Online mailboxes, and your app’s access is scoped to the tenant and mailbox permissions you’ve been granted, which shapes what delegated versus application flows can actually reach.
Authentication and permission model: choosing delegated or application flows
The permission model decides what your integration can see and do, so get it right before writing any sync logic. Delegated permissions act on behalf of a signed-in user and are the right fit when a human is present during the flow, such as a staff member connecting their own calendar. Application permissions run without a signed-in user, which suits background services and automation that need to read or write across mailboxes.
Common calendar scopes to request:
Calendars.Readfor read-only access to a user’s own calendar.Calendars.ReadWritefor creating and modifying events.Calendars.Read.Sharedfor reading calendars shared with the signed-in user.Calendars.ReadWrite.Sharedfor writing to shared calendars.
Application-only scenarios need admin consent before they can run, since they bypass the usual per-user consent screen.
Pro Tip: Set up a Microsoft 365 developer test tenant before touching production data, and run both the delegated consent flow and the admin consent flow at least once so you catch scope mistakes early.
Sync strategies: delta queries, change notifications and ICS subscriptions
Three mechanisms cover most synchronisation needs, and picking the right one (or combination) determines how reliable your sync ends up being.
- Delta queries: run an initial full sync against
calendarView, then use the returned@odata.nextLinkto page through results and the final@odata.deltaLinkto fetch only what changed next time. The event delta reference is clear that this token should be treated as opaque state: save the full string and never attempt to parse it. - Change notifications: subscribe to a mailbox or calendar so Microsoft Graph pushes a webhook when something changes, then call the delta endpoint to retrieve what actually changed. Delta query guidance recommends pairing webhooks with delta calls specifically because polling alone misses updates and wastes calls.
- ICS subscriptions: a one-way, read-only feed suited to public or publish-only calendars, with a slower and less predictable refresh cadence than an API-driven sync.
Delta queries beat naive polling for reliability, according to Microsoft’s own delta query guidance, which recommends persisting delta tokens so a sync round can resume after a restart without re-fetching everything.
A few scalability details matter once you’re running this in production: set $top sensibly to control page size, handle @removed entries explicitly rather than ignoring them (the event delta documentation notes these can include items deleted within your date range or items that moved outside it), and avoid triggering repeated full syncs by always reusing the stored deltaLink rather than starting fresh.
Creating and managing events with correct time zones and online meetings
Time zone bugs are one of the most common support complaints in calendar integrations, and they’re avoidable. Use a proper dateTimeTimeZone object on both start and end, and consider sending the Prefer: outlook.timezone header so responses come back in a known zone rather than requiring manual UTC conversion on your end. Microsoft’s guidance on cross-timezone appointments warns that mishandling this can cause an event to render as an all-day appointment, which is a confusing failure mode for end users.
For online meetings, set isOnlineMeeting to true and specify a provider such as teamsForBusiness. The Outlook calendar online meetings documentation confirms Graph then returns a joinUrl inside the onlineMeeting object, which should be used instead of the deprecated onlineMeetingUrl property.
- Set
locationas anemailAddressobject when booking a room or resource. - Add
categoriesandreminderMinutesBeforeStartwhen your workflow depends on them. - Handle recurring series and individual exceptions as distinct objects rather than assuming one event ID covers the whole series.
Pro Tip: Always read back the created event and check for a populated joinUrl before marking an online meeting booking as successful; a missing value usually means the provider field was left out.
Calendar sharing, delegation and how shared calendars sync
Shared calendars, delegate access and group calendars behave differently, and conflating them is a common source of integration bugs. A shared calendar gives another user visibility (and sometimes edit rights) into your calendar; a delegate can act on your behalf, including sending responses; a group calendar belongs to a Microsoft 365 group rather than an individual mailbox.
- Shared calendars between users in the same tenant, or shared by an Outlook.com user, can sync near-instantly under Microsoft’s newer sharing model.
- Outside those conditions, Microsoft’s calendar sharing documentation notes that an ICS subscription is generated instead, with a refresh cadence that varies and is noticeably slower than instant sync.
- Reading shared calendar data programmatically generally relies on
Calendars.Read.SharedorCalendars.ReadWrite.Shareddelegated scopes, or equivalent application permissions when no user is signed in.
Common pitfalls and troubleshooting checklist
Most sync complaints trace back to a short list of causes. Work through these in order before assuming the API itself is at fault:
- Confirm the token type and scopes match the scenario: a delegated token with
Calendars.Readcannot write events, and application-only calls need admin consent granted at the tenant level. - Check that your deltaLink is being saved and reused correctly, and that
@removedentries and anyskipTokenpaging are handled rather than silently dropped. - Verify time zone fields on every event and confirm the
Prefer: outlook.timezoneheader matches what your display logic expects. - If a shared calendar feels stale, check whether it’s running on instant sync or an ICS subscription, since ICS feeds can lag by design.
For environments where admin-level Microsoft 365 configuration is part of the problem, a practical shared-calendar troubleshooting guide walks through PowerShell checks that complement the API-side fixes above.
A minimal developer flow for creating events and keeping sync current
A reliable end-to-end flow looks like this: obtain an OAuth token with the right scope, create the event with dateTimeTimeZone and isOnlineMeeting set correctly, store the returned event id and iCalUId locally, subscribe to change notifications on the calendar, and use calendarView delta calls to fetch changes as they’re reported, persisting the new deltaLink after every round.
- Persist the event ID, iCalUId and the latest deltaLink, not just the raw event payload.
- On resume after downtime, call the stored deltaLink directly rather than starting a fresh full sync.
- Test by checking the
joinUrlis populated, confirming room bookings actually appear on the room’s calendar, and re-running updates to make sure edits don’t create duplicate events.
Pro Tip: Log every deltaLink your app receives, even during testing, so a broken sync round can be replayed instead of debugged blind.
Direct Graph integration versus middleware: which is worth building

Building directly against Microsoft Graph gives full control over scopes, event properties and sync timing, and it’s the only path to feature parity when a business genuinely needs Teams meeting links, room booking and category management working exactly as specified. The cost is real: OAuth consent flows, delta state management and webhook validation all need ongoing maintenance.
Middleware and prebuilt connectors earn their keep when a team needs to support several calendar providers at once or wants to ship faster than an in-house Graph integration allows. The honest trade-off is depth for speed. Teams underestimate how much of the “simple” calendar sync work is actually token lifecycle and edge-case handling, not the happy-path API calls.
— Christopher
Another option: let an AI front desk handle the booking instead
If the real goal is fewer missed bookings rather than a custom Graph integration, we built Wattle to take that work off your plate entirely. Our voice agents answer calls, web chat, WhatsApp and SMS, capture the booking details, and write events into your connected calendar as part of a broader workflow, so you’re not maintaining delta tokens and webhook subscriptions yourself.
Everything lands in one inbox regardless of channel, which matters if your team currently juggles separate phone, chat and messaging tools. For teams comparing the engineering cost of a direct integration against a managed option, our pricing plans outline Starter, Pro and Max tiers, and our feature catalogue details exactly how calendar and workflow integrations connect.
FAQ
How do I get an ICS link for my Outlook calendar?
In Outlook on the web, open calendar settings and look for the “publish a calendar” or “share calendar” option, which generates an ICS link for read-only subscription by others. This works well for simple publish-only sharing but isn’t suited to two-way sync or write access.
How do I get my Outlook calendar to sync on all devices?
Signing in with the same Microsoft 365 or Outlook.com account on each device keeps the calendar synced automatically through Exchange Online. If a specific device lags, check whether it’s relying on an ICS subscription rather than a direct account connection, since ICS feeds refresh more slowly than native account sync.
Why are Outlook calendars not syncing?
The most common causes are an expired or mis-scoped auth token, a deltaLink that wasn’t saved or reused correctly, or a shared calendar running on a slower ICS subscription instead of instant sync. Working through scopes, delta state and sharing mode in that order resolves most sync problems.
Is there a calendar that syncs with Outlook?
Microsoft Graph supports two-way sync with Outlook calendars for any application built against the Calendars API, and Google Calendar and other providers can be connected through custom integrations or middleware. For businesses that want calendar-linked bookings without building that integration themselves, platforms like Wattle connect booking workflows directly to calendar actions.
Sources
- event: delta - Microsoft Graph v1.0 | Microsoft Learn
- Outlook calendar API overview - Microsoft Graph | Microsoft Learn
- Delta query guidance - Microsoft Learn
