Launched:self-serve migrations intoSuperhuman Docs (Coda)
Try it now
01Agent-first
Runs where you already work
Plug it into Claude, ChatGPT or Cursor. Describe the move in plain English; the agent runs it.
02Engineer-led
Our production engine, unlocked
The pipeline our engineers use on managed enterprise migrations — the same code, now something you can drive yourself.
03Pricing
Try 10 pages free, then $1 a page
Credit-based, pay-as-you-go. No scoping call, no quote — sample it on your own docs before you spend anything.
04Sources
NotionSlabConfluenceSoonGoogle DocsSoon
Skip to content

EWS Shuts Down Oct 2026: The SaaS Guide to Microsoft Graph Migration

Microsoft began a phased EWS disablement for Exchange Online in October 2026, and EWS is permanently off on April 1, 2027. Here's what breaks, what Graph API still can't do, and how to migrate your SaaS integration without data loss.

Roopendra Talekar Roopendra Talekar · · 23 min read
EWS Shuts Down Oct 2026: The SaaS Guide to Microsoft Graph Migration
TALK TO AN ENGINEER

Planning a migration?

Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.

Schedule a free call
  • 1,500+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included

Exchange Web Services (EWS) for Exchange Online is undergoing a phased, admin-controllable disablement that began in early October 2026. If your SaaS product reads email, syncs calendars, or manages contacts via EWS, your integration is actively at risk. This is not a soft deprecation with a sunset blog post and a vague timeline. Starting October 10, 2026, setting EWSEnabled=True is no longer enough to keep EWS working; tenants must also configure an EWSAllowedAppIDs allow list (techcommunity.microsoft.com). Starting April 1, 2027, EWS is fully and permanently disabled in Exchange Online — no exceptions, no re-enablement.

For multi-tenant SaaS companies whose products integrate with customer Outlook/Microsoft 365 inboxes, this migration to Microsoft Graph API is not a weekend project. It is a full protocol rewrite, an auth model overhaul, and a throttling redesign — all while keeping existing customer syncs alive.

For a broader view of Microsoft's 2026 deprecation wave — including SharePoint Server 2016/2019 and Office Online Server — see our Microsoft 2026 End-of-Support Timeline. EWS is not the only Microsoft workload being pushed onto Graph: Azure Communication Services Chat retires on September 30, 2028 and points at the same Graph chat APIs, with a different set of identity constraints — see our ACS Chat to Microsoft Graph migration guide.

Phased EWS Retirement Timeline

Microsoft is using a phased disablement plan that started in October 2026 and concludes with a complete shutdown of EWS in 2027. Per Message Center MC1485116, the rollout covers Worldwide, GCC, GCC High, and DoD environments, and is expected to complete by early July 2027. The October dates below apply to the Worldwide cloud first; other clouds receive their own Message Center timelines. Here is the exact sequence your engineering team needs to internalize:

Date What Happens
October 1, 2026 Microsoft starts blocking EWS for mailboxes licensed only with Exchange Online Kiosk, F1, or F3. These licenses never included EWS rights, but the restriction was not enforced before. Requests without a suitable license return HTTP 403 (MC1191578).
October 2, 2026 Microsoft records Worldwide tenants that have EWSEnabled=True but no allow list. After this date, any admin who sets EWSEnabled=True must populate EWSAllowedAppIDs themselves.
October 8–9, 2026 For tenants on the October 2 list, Microsoft creates EWSAllowedAppIDs and auto-fills it with the App IDs that used EWS in the previous 60 days.
October 10, 2026 EWSAllowedAppIDs is required when EWSEnabled=True. Any app whose App ID is not on the list is blocked (techcommunity.microsoft.com).
Rolling, after October 10 Tenants with EWSEnabled left at Null are switched to False as the phased rollout reaches them, with a 7-day Message Center warning. Shortly before the switch, Microsoft pre-populates the allow list from the prior 60 days of usage. After the switch, an admin who still needs EWS must set EWSEnabled back to True and maintain the allow list.
April 1, 2027 EWS is fully and permanently disabled in Exchange Online. Admins can no longer control EWSEnabled. There will be no exceptions past April 2027 (techcommunity.microsoft.com).

Two propagation delays matter when you help a customer fix access: changes to EWSAllowedAppIDs take 24 hours to take effect, while changes to EWSEnabled usually apply in under an hour but can take up to 4 hours (techcommunity.microsoft.com).

Danger

The Kiosk/F1/F3 trap: Many SaaS companies test their integrations against standard E3 or E5 enterprise licenses and miss this entirely. If your SaaS serves enterprise customers with retail workers, factory staff, or field technicians, your integration now fails for a subset of users even in tenants that kept EWS enabled. This creates a support nightmare where the integration works for the management team but fails for the frontline staff. Microsoft moved this enforcement from June 30 to October 1, 2026, so it is already in effect: requests to use EWS without a suitable license return an HTTP 403 response (MC1191578).

Why is Microsoft doing this now? Two reasons. First, EWS was built nearly 20 years ago, and while it served the ecosystem well, it no longer aligns with today's security, scale, or reliability requirements. Second: the Midnight Blizzard security incident in January 2024 involved EWS and elevated the urgency of the EWS deprecation effort. The scope was also widened from third-party applications to include all Microsoft applications. In that breach, Russian state-sponsored actors used a compromised legacy test OAuth application to grant their own malicious OAuth applications the Office 365 Exchange Online full_access_as_app role, which allows access to mailboxes through EWS (microsoft.com).

This applies only to Microsoft 365 and Exchange Online (all environments); there are no changes to EWS in Exchange Server on-premises. If some of your customers still connect on-prem Exchange mailboxes, Graph is not a universal replacement and you may need a split architecture or customer segmentation plan.

Info

Sovereign cloud and GCC note: GCC uses the worldwide Graph endpoint (graph.microsoft.com), but GCC High uses graph.microsoft.us and DoD uses dod-graph.microsoft.us (learn.microsoft.com). The October dates above are Worldwide-only; MC1485116 covers GCC, GCC High, and DoD too, and those clouds get their own Message Center timelines. Microsoft also lists sovereign cloud availability of the Exchange APIs needed for EWS migration as a Q4 CY2026 roadmap item (learn.microsoft.com). If your SaaS serves US government or sovereign cloud customers, confirm the schedule and Graph endpoint availability for each environment before planning your migration.

What SaaS Vendors Should Do Now: App ID Allow-Listing

If you still need to use EWS, you have a temporary bypass: your customer's integration can keep working after October 10 if the customer admin keeps EWSEnabled=True and adds your vendor App ID to EWSAllowedAppIDs. Microsoft has stated that organizations with a configured allow list will not have their EWSEnabled setting modified by Microsoft before April 2027 (MC1485116). Changes to EWSAllowedAppIDs take 24 hours to take effect, so an admin who adds your App ID today should not expect your integration to recover until tomorrow (techcommunity.microsoft.com).

Do not assume Microsoft's auto-filled list covers you. It only includes App IDs that called EWS in the previous 60 days, so a low-frequency integration, or one a customer has not connected recently, can be left off.

This buys you time to finish migrating to Microsoft Graph before the April 1, 2027 removal. We strongly recommend SaaS vendors immediately publish their App ID and provide exact, copy-paste instructions for customer admins to allow-list it.

But this is a bridge, not a solution. After April 1, 2027, EWS access will be permanently removed with no re-enablement.

For SaaS companies, the AllowList approach has a critical dependency: you do not control your customers' tenants. Each customer's admin must add your application's AppID to their allow list and ensure EWSEnabled=True. That is a support burden you do not want to carry into 2027.

Microsoft has also said it may perform temporary "scream tests" — shorter periods when it turns EWS off and back on — to help expose hidden dependencies before the final cutoff; tenants that set EWSEnabled=True are excluded (techcommunity.microsoft.com). If your product does not handle EWS failures gracefully today, those scream tests will surface as customer-reported outages.

EWS vs. Microsoft Graph: The Architectural Differences

This is not a find-and-replace migration. EWS and Microsoft Graph are architecturally different systems.

EWS Microsoft Graph
Protocol SOAP over HTTPS (XML envelopes) REST over HTTPS (JSON payloads)
Auth Model OAuth 2.0 in Exchange Online (Basic Auth deprecated); NTLM/Kerberos on-premises OAuth 2.0 only (via Microsoft Entra ID)
Access Scope Broad — full_access_as_app grants full mailbox access Granular — Mail.Read, Calendars.ReadWrite, individual scopes
Concurrency EWSMaxConcurrency default of 27 concurrent connections per user 4 concurrent requests per app ID + mailbox
Throttling Policies set by Microsoft in Exchange Online (admin-configurable only on-premises) Published per app ID + mailbox service limits
Notifications Streaming, push, and pull subscriptions Webhooks (change notifications) and delta queries
SDK EWS Managed API (.NET), EWS Java API Microsoft Graph SDKs (JS, .NET, Python, Java, Go)

Auth: From All-or-Nothing to Granular Scoping

Microsoft Graph mandates OAuth 2.0 via Microsoft Entra ID. This introduces the principle of least privilege. Instead of granting an app total access to a mailbox, admins can now assign granular scopes such as Mail.Read or Calendars.ReadWrite.

For multi-tenant SaaS, this means re-engineering your consent flow. Each customer tenant admin must approve your specific Graph permission scopes. If your current EWS integration was built around impersonation (the ApplicationImpersonation role, which Microsoft has already retired in Exchange Online, or its full_access_as_app replacement), you are moving to application-level Graph permissions with tenant admin consent — a different workflow that needs UX investment (learn.microsoft.com).

One trap to watch for: shared and delegated folder subscriptions require the corresponding application permission, not Mail.Read.Shared, Calendars.Read.Shared, or their peers, for change notifications on shared or delegated folders. (learn.microsoft.com)

Access tokens have a default lifetime of 60–90 minutes, and refresh tokens have a default lifetime of 90 days and replace themselves on each use (learn.microsoft.com). Your token management layer must handle this lifecycle without interrupting customer syncs.

For multi-tenant SaaS, understand the two consent models:

  • Application permissions (app-only): Granted by a tenant admin via an admin consent URL. Your app accesses mailboxes without a signed-in user. This is the typical model for background sync services.
  • Delegated permissions: Granted per user at sign-in. The app acts on behalf of the signed-in user only.

For background mail and calendar sync across customer tenants, you almost certainly need application permissions with admin consent. The re-consent migration is not a silent backend swap — it is a product-managed change. Each customer admin must visit your consent URL and approve the new Graph scopes. Plan this as a coordinated rollout with customer communication, not a feature flag flip.

Throttling: The 4-Connection Ceiling

This is the single biggest operational surprise for SaaS teams migrating from EWS to Graph.

The documented Outlook service limits are: 10,000 API requests in a 10-minute period per app ID + mailbox, 4 concurrent requests per app ID + mailbox, and 150 MB upload (PATCH, POST, PUT) in a 5-minute period per app ID + mailbox (learn.microsoft.com). Exceeding the limit for one mailbox doesn't affect your app's access to other mailboxes.

Compare this to EWS, where EWSMaxConcurrency defaults to 27 concurrent connections per user in Exchange Online (learn.microsoft.com). If your product does bulk mail syncs, calendar operations, or attachment pulls, you need to completely rethink your concurrency model.

Warning

Practical impact: With 4 concurrent connections per app-per-mailbox and 10,000 requests per 10-minute window, your sustained throughput ceiling per mailbox is roughly 16.7 requests/second (10,000 ÷ 600 seconds). With operations that average 200ms round-trip, 4 concurrent requests could issue about 20 requests/second, so the 10-minute request budget, not concurrency, becomes the binding limit. Compared to EWS's 27 concurrent connections, high-volume SaaS workloads will see significantly lower per-mailbox throughput on Graph. A naive port from EWS to Graph will produce unacceptable latency.

When a throttling threshold is exceeded, Microsoft Graph returns HTTP status code 429 Too Many Requests. It returns a suggested wait time in the response header of the failed request. You must implement exponential backoff with jitter, respect Retry-After headers, and distribute load across mailboxes. Immediate retries only make things worse: Microsoft Graph keeps logging resource usage while a client is throttled, so all requests accrue against your limits (learn.microsoft.com).

Warning

Batching limits: Graph supports JSON batching, but each batch is limited to 20 requests (learn.microsoft.com). Each subrequest within a batch is still throttled individually against the per-mailbox limits, and SDK auto-retry does not rescue throttled items inside a batch (learn.microsoft.com). If your EWS code sends large parallel request volumes, you cannot simply wrap them in Graph batch calls and expect equivalent throughput.

Be aware that per-mailbox limits are not the only constraint: Microsoft lists a large number of requests across all applications in a tenant as one of the most common causes of throttling (learn.microsoft.com). If your SaaS processes thousands of mailboxes in the same tenant simultaneously, you may hit aggregate throttling even if individual mailbox limits are respected. Monitor 429 responses at both the per-mailbox and per-tenant level.

Sync Model: Delta Queries and Webhooks

In EWS, developers relied on Streaming Notifications or Push/Pull Subscriptions and SyncFolderItems with a mailbox-wide SyncState string to track changes. Graph replaces this with two mechanisms: Change Notifications (Webhooks) and Delta Queries.

Graph's delta tracking is not mailbox-wide the way many EWS apps assume. Messages are delta-tracked per mail folder. Contacts are delta-tracked per contact folder. Tasks are delta-tracked per task list. Calendar delta on v1.0 is tied to a calendarView date range. If your current connector stores one watermark per mailbox, expect a data model change. (learn.microsoft.com)

Warning

Large mailbox initial sync: For mailboxes with hundreds of thousands of items, the initial delta query (before you have a delta link) returns the full set. This can time out or produce massive payloads. Paginate aggressively using $top and odata.nextLink, and be prepared for the initial sync to take significantly longer than incremental syncs. Budget for this in your migration timeline — a mailbox with 500,000 messages will not sync in one pass.

Graph Webhooks require a public-facing HTTPS endpoint that can answer validation requests within 10 seconds (learn.microsoft.com). Outlook message, event, and contact subscriptions have a max lifetime of under seven days (10,080 minutes), and rich notifications drop to under one day (1,440 minutes) (learn.microsoft.com). Microsoft caps Outlook subscriptions at 1,000 active subscriptions per mailbox across all apps. Subscription renewal and quota management become first-class ops work, not background glue code. (learn.microsoft.com)

Warning

If a subscription drops, you must fall back to a Delta Query to catch missed events. When Graph sends missed or subscriptionRemoved lifecycle notifications, repair with delta instead of assuming webhooks are lossless. Also note Microsoft's warning not to send /reauthorize and PATCH /subscriptions/{id} within the same 10-minute window — use a single PATCH to renew and reauthorize together (learn.microsoft.com). This dual-sync architecture is something EWS never required.

ID Behavior: The Immutable ID Trap

In EWS, an ItemId changes if a user moves an email to a different folder. EWS developers built complex tracking logic to handle this. Microsoft Graph introduces Immutable IDs, but you must explicitly opt in by appending the HTTP header Prefer: IdType="ImmutableId" to all Graph requests. By default, Graph IDs also change when items are moved.

If you fail to request Immutable IDs, your SaaS will create duplicate records every time a user organizes their inbox. Even with Immutable IDs enabled, the ID only stays stable within the same mailbox — moving an item to an archive mailbox or exporting and re-importing it changes the immutable ID. (learn.microsoft.com)

The Missing Endpoints: What Graph API Still Can't Do

There are still EWS feature areas that the Microsoft Graph API doesn't fully support. Microsoft tracks them in a "Roadmap for parity gaps" on its EWS deprecation page, and says the ETAs are targets that might change (learn.microsoft.com):

  • Targeted for Q3 CY2026: Notes (IPM.StickyNote), personal Contact Lists, and additional contact properties that EWS exposes but Graph doesn't. Q3 has now ended, so check the page for current status before you rely on them.
  • Targeted for Q4 CY2026: In-Place Archive access (generic CRUD), import-export for archive, public folder, and Microsoft 365 Group mailboxes, the Exchange Admin API, sovereign cloud availability, Report Message, non-draft MIME create/update, user configuration objects, and Mark All Items As Read.
  • Confirmed as never coming to Graph: generic Public Folder CRUD, generic Microsoft 365 Group mailbox CRUD (use the Graph group conversations, threads, and posts APIs instead), and Discovery Mailbox access (use Microsoft Purview eDiscovery instead).

Microsoft also warns that if an EWS capability isn't on that roadmap, you should not plan on a Graph or Exchange Admin API equivalent arriving before EWS is fully disabled.

Calendar sync has a separate constraint that isn't on the roadmap: in v1.0, event delta works only on a calendarView bounded by a start and end date. Delta on a calendar without a fixed date range is available only in beta (learn.microsoft.com).

Microsoft has shipped two bridge mechanisms:

  1. Graph Mailbox Import/Export APIs — reached general availability in May 2026 for primary and shared mailboxes (devblogs.microsoft.com). Archive, public folder, and group mailbox support is on the Q4 CY2026 roadmap.
  2. Exchange Online Admin API — a preview, REST-based, cmdlet-style surface for a few admin tasks that used to require EWS: organization configuration, distribution group membership, mailbox folder permissions, and Send on Behalf delegation (learn.microsoft.com). It is not a general mailbox data API, so keep as much of your code as possible on Graph.
Info

Public Folders: If your SaaS product relies on EWS public folder operations, there is no Graph replacement coming. Microsoft has confirmed generic Public Folder CRUD won't be added to Graph; only public folder import-export is on the roadmap. Advise customers to migrate to Shared Mailboxes before your EWS integration shuts down; Microsoft 365 Group mailboxes are not a drop-in target, because generic Group mailbox CRUD is also on the won't-add list.

The 5 Data Types You Must Migrate Cleanly

Every EWS-to-Graph migration touches five core data types. Each has unique pitfalls.

1. Messages (Mail)

Mail operations (FindItem, GetItem, CreateItem, SendItem) map fairly cleanly to Graph's /messages and /sendMail endpoints. The traps:

  • Delta is per folder, not per mailbox. Inbox, Sent Items, and custom folders each need separate state. Microsoft limits filtered message delta queries to receivedDateTime expressions and says filtered delta returns only up to 5,000 messages — making giant catch-up queries a bad backfill plan. (learn.microsoft.com)
  • Search limitations: Microsoft Graph $search on messages works only for a limited set of message properties (about 15, such as from, subject, body, to, and recipients) and returns up to 1,000 results. Use the recipients, to, cc, or bcc search properties for recipient-based queries (learn.microsoft.com).
  • Notifications migration: If your product uses EWS streaming or push notifications to detect new mail, the migration to Graph change notifications (webhooks) requires rebuilding your notification processing infrastructure to receive and validate HTTPS POST messages. If you are currently using EWS pull notifications, Microsoft points you to Get messages delta (learn.microsoft.com).

If you have stored EWS item IDs, use Graph's translateExchangeIds for crosswalk purposes, but do not confuse ID translation with state migration. The safer pattern is to start shadow sync with ImmutableId, keep an EWS-to-Graph crosswalk temporarily, and compare folder counts plus representative item samples before you switch writes.

2. Calendar Events

Calendar operations are the highest-risk data type in an EWS-to-Graph migration. The danger is de-duplication. During cutover, if your sync engine reads from both EWS and Graph simultaneously — or if historical sync state is not properly preserved — customers get duplicate calendar entries.

Key issues:

  • Recurring events: In v1.0, event delta works only within a date-bounded calendarView, which returns individual occurrences and exceptions of a recurring series rather than the series as one object (learn.microsoft.com). If your product syncs recurring event exceptions, test this exhaustively. To query recurring meetings, you must use the /calendarView endpoint to expand recurrences rather than the standard /events endpoint — otherwise you will miss exceptions like a user moving one instance of a weekly meeting.
  • Event IDs: EWS ItemId values do not map to Graph event IDs. Your sync state table that tracks which events have been synced is invalid. Use iCalUId as your primary reconciliation key — it is stable across both APIs. For recurring meetings, note that iCalUId is different for each occurrence of the series; reconcile series masters first and match occurrences and exceptions to their master (learn.microsoft.com).
  • Attendee status: Graph uses a different schema for attendee responses. If your product writes back acceptance/decline states, rebuild that mapper.
  • Timezone corruption: When expanding recurring events, be explicit about timezone handling. Silent timezone mismatches are a common source of off-by-one-hour meeting times after migration.

Test recurring series edits, moved occurrences, cancelled instances, organizer changes, and time-zone shifts inside the exact date windows your product syncs. If you do not, you can have both systems "succeed" technically while users see double-booked or resurrected meetings.

3. Contacts

Contacts move from EWS Contact items to Graph's /contacts endpoint. The data model is similar but not identical. Delta tracking is per contact folder, not per mailbox. If your current EWS code assumes one flat address book, you need to inventory folders first and carry separate folder state through the migration.

Extended MAPI properties that some SaaS products rely on require Graph's singleValueExtendedProperties or multiValueExtendedProperties resources — or you can migrate them to Graph Open Extensions or Schema Extensions. This requires mapping legacy MAPI property tags to JSON extension payloads. Validate your field mapping against production data, not test accounts with three contacts.

4. Tasks

EWS tasks — stored in the Exchange Tasks folder — map to Microsoft Graph's To Do API. Note that this is a more significant shift than the mail and calendar migrations: the underlying data model differs. The To Do API has different status values, different recurrence patterns, and a richer linked resources model. You cannot map EWS Tasks directly; you must rewrite your integration to use the /me/todo/lists and /me/todo/lists/{id}/tasks endpoints.

Task Permission Matrix

The permission story for Tasks is more fragmented than Mail or Calendar. Here is what you need to know:

Operation Application Permission Delegated Permission Admin Consent Required
List task lists Tasks.Read.All Tasks.Read Yes (app) / No (delegated)
Get task Tasks.Read.All Tasks.Read Yes (app) / No (delegated)
Create task Not supported Tasks.ReadWrite N/A (app) / No (delegated)
Update task Tasks.ReadWrite.All Tasks.ReadWrite Yes (app) / No (delegated)
Delete task Not supported Tasks.ReadWrite N/A (app) / No (delegated)

The critical gap: creating and deleting tasks do not support application permissions (learn.microsoft.com, learn.microsoft.com). If your SaaS product creates or deletes tasks across customer tenants using app-only auth, you must use delegated permissions with a signed-in user context for those operations — or redesign that workflow. Validate each verb against the permission model before you commit to scope design.

5. Attachments

Attachments in EWS are fetched inline with the parent item or via GetAttachment. In Graph, attachments are a sub-resource of messages and events (/messages/{id}/attachments). The key constraints:

  • For files under 3 MB, attach them directly in the JSON payload.
  • For files from 3 MB to 150 MB, initiate an upload session using the createUploadSession endpoint, chunk the file into byte ranges, and upload sequentially. Upload session URLs are pre-authenticated — do not send an Authorization header on the PUT. Note: the 150 MB ceiling applies to the Graph API upload path for message attachments; actual enforced limits can vary depending on whether the attachment is on a message vs. event, and whether the client is using the REST API vs. Outlook client. Test with your actual payload sizes. (learn.microsoft.com)
  • For To Do task attachments, the limit is 25 MB and the upload flow is different (it does require Authorization) (learn.microsoft.com).
  • Group calendar events do not support attachments (learn.microsoft.com).

EWS had no such thresholds. If your product handles large file attachments — common in business email — your upload path needs an overhaul. Migrate attachment code by workload, not behind one generic helper, because the failure handling differs.

The Graph mailbox import and export APIs export items as an opaque, full-fidelity stream and can import them into the same mailbox or a different one, currently for primary and shared mailboxes. Microsoft notes they aren't designed for mailbox backup and restore (learn.microsoft.com). If you are doing bulk operations, evaluate whether the Import/Export APIs fit your use case.

How to Avoid Sync Gaps and Data Loss During Cutover

The hardest part of this migration is not writing the new Graph code. It is cutting over without losing data or generating duplicates for your existing customers.

Run Parallel Syncs Before Cutover

Before switching off EWS, run your Graph implementation in shadow mode — reading the same mailboxes via Graph and comparing the results to EWS output. Do not write via Graph yet. This surfaces:

  • Throttling issues at your actual scale
  • Missing data (items EWS returns that Graph does not, due to parity gaps)
  • Permission gaps (scopes you forgot to request)

Translate IDs Before You Switch

Your database is filled with EWS Item IDs. You cannot use these IDs in Graph. Before cutover, use the Graph translateExchangeIds endpoint to convert stored EWS IDs into Graph Immutable IDs:

POST https://graph.microsoft.com/v1.0/me/translateExchangeIds
{
  "inputIds" : [
    "AAMkADh..."
  ],
  "sourceIdType": "ewsId",
  "targetIdType": "restImmutableEntryId"
}

You are limited to 1,000 IDs per request, and every ID in a request must be from the same mailbox (learn.microsoft.com). If your SaaS has millions of stored EWS IDs, you cannot translate them synchronously during cutover. Build a background migration job that batches these requests, handles rate limits, and updates your database mapping tables weeks in advance. Any new items synced via EWS during this transition period must also be translated on the fly.

For calendar events specifically, use iCalUId as your primary reconciliation key — it is stable across both APIs and eliminates the risk of duplicate creation.

Map Sync States to Delta Tokens

EWS used SyncFolderItems with a base64 SyncState string. Graph uses Delta Queries (/delta) with an odata.deltaLink URL. There is no direct translation between the two.

To cut over cleanly:

  1. Pause the EWS sync.
  2. Execute an initial Graph Delta Query to obtain the latest odata.deltaLink.
  3. Discard the data from the initial Delta Query (since you already have it from EWS).
  4. Save the odata.deltaLink in your database.
  5. Resume syncing using the new Delta Token.
  6. Verify that no items are missed by comparing counts and checksums.
GET https://graph.microsoft.com/v1.0/me/mailFolders/{folderId}/messages/delta
Prefer: IdType="ImmutableId"

That single header-plus-delta pattern is the foundation of a safer cutover: stable IDs for local state, delta links for replay, and fewer false duplicates after folder moves.

Tip

Opt into immutable IDs before your parallel run. If you already created subscriptions without that header, you must delete and recreate them to switch notification IDs. Do not wait until go-live week to fix your ID format — subscription format, and dedupe logic have to change before you trust Graph in production. (learn.microsoft.com)

Plan Your Rollback Path

The cutover section above explains how to switch from EWS to Graph. Equally important: what happens if your Graph integration fails in production?

As long as it is before April 2027 and the tenant still has EWSEnabled=True with your App ID on the EWSAllowedAppIDs list (or has not yet been switched to False in the rolling deployment), you can fall back to EWS:

  1. Re-enable your EWS sync pipeline.
  2. Use the translateExchangeIds crosswalk you built during pre-cutover to reconcile any items that were created or modified only via Graph during the failed period.
  3. Resume delta sync from the last known EWS SyncState.

After the phased rollout reaches a customer, this rollback path only works if the customer admin has explicitly opted in via the allow list. After April 1, 2027, there is no rollback — EWS is permanently off. This is why the parallel validation phase is not optional: you must have confidence in Graph before your EWS fallback disappears.

Manage the OAuth Token Migration

If your app already uses OAuth for EWS, you cannot reuse the same token for Graph. Graph tokens are resource-audience specific, so existing EWS token flows do not become Graph flows by configuration. The token must include Graph-specific scopes. This means:

  • You must trigger a re-consent flow for every connected customer
  • Plan this as a product-managed migration, not a silent backend swap
  • Communicate the change to customer admins well before cutover
  • Consider a gradual rollout: migrate one customer cohort at a time

To minimize friction, prompt users to re-authenticate inside your SaaS dashboard prior to the final April 2027 deadline.

Handle the Concurrency Cliff

Your EWS code may have been tuned for 27 concurrent connections. Graph limits you to 4 concurrent requests per app ID + mailbox. JSON batching is constrained so that Microsoft Graph sends up to 4 individual Outlook requests from a batch at a time (learn.microsoft.com). If you flip from EWS to Graph without rearchitecting your concurrency, you will hit 429 errors immediately.

Design your sync queue to:

  • Process mailboxes in parallel (limits are per-mailbox)
  • Limit concurrency to 3 per mailbox (leave headroom below the 4-connection ceiling)
  • Implement token bucket rate limiting per mailbox
  • Use delta queries and webhooks instead of polling

De-Duplication Strategy for Calendar Events

Calendar duplicates are one of the most visible failures in poorly executed EWS-to-Graph migrations. To prevent them:

  • Use iCalUId as your primary reconciliation key for single events; for recurring series, reconcile the series master first, since each occurrence has its own iCalUId
  • Never create a new event in Graph if your mapping table already shows it was synced via EWS
  • After cutover, run a de-duplication pass that checks for events with identical iCalUId and removes any that were double-created during the transition window

A Realistic Engineering Timeline

Here is what the migration actually looks like for a SaaS product with an existing EWS integration:

Phase Duration Work
Audit & scope 2–3 weeks Inventory every EWS call. Use Microsoft's EWS Code Analyzer — a Roslyn analyzer for .NET EWS code that finds EWS references and suggests equivalent Graph APIs. Map each call to a Graph equivalent or flag parity gaps.
Auth overhaul 3–4 weeks Register Graph app in Entra ID. Implement consent flows. Build token lifecycle management.
Core API rewrite 6–8 weeks Rewrite message sync, calendar sync, contact sync, task sync, attachment handling. Rebuild notification infrastructure.
Throttling & resilience 2–3 weeks Implement retry logic, rate limiting, circuit breakers for 429/503. Load test at production scale.
Parallel validation 3–4 weeks Shadow mode: run Graph alongside EWS, compare outputs, fix discrepancies.
Customer rollout 3–4 weeks Re-consent flow, staged migration, monitoring, customer communication.
Buffer 2+ weeks Edge cases, parity gap workarounds, customer-specific issues.

Total: 5–7 months of focused engineering effort, by our estimate. That assumes your team has Graph API experience. If they do not, add ramp-up time.

It is important to get started with this effort as soon as possible, as the Graph API patterns are quite different from EWS. Equivalent Graph API operations may exhibit subtle differences that affect your use cases and application designs in unanticipated ways.

This timeline assumes a single integration. If your product has multiple EWS touchpoints — email sync, calendar booking, contact management, task sync — each is its own migration workstream.

When to Build In-House vs. Bring in a Migration Partner

Not every SaaS team should build this in-house, and not every team needs outside help. Here are the objective criteria:

Build in-house when:

  • Your team already has production experience with Microsoft Graph and Entra ID
  • Your EWS surface is limited to one or two data types (e.g., mail sync only)
  • You have engineering capacity that is not competing with revenue-critical product work
  • Your customer base is small enough that a staged re-consent rollout is manageable

Bring in a migration partner when:

  • Your team lacks Graph API expertise — OAuth consent flows, Entra ID app registrations, delta query patterns, webhook validation are a different world from EWS
  • The migration would occupy senior engineers for months, stalling product development that directly impacts revenue
  • You have complex sync state — bidirectional sync with thousands of customer mailboxes means the cutover risk justifies someone who has done this before
  • You are running into parity gaps — archive mailboxes, public folders, date-bounded calendar delta require experience with the specific workarounds
  • You serve sovereign cloud or GCC customers and need to handle multiple Graph endpoints and compliance requirements

The core trade-off: this migration generates zero customer-visible value. Your customers do not care whether you use EWS or Graph — they care that their email sync works. You are spending engineering capacity to maintain the status quo.

Microsoft has confirmed there will be no exceptions past April 2027, so you cannot request an extension beyond the final deadline (techcommunity.microsoft.com).

Frequently Asked Questions

When does EWS stop working for Exchange Online?
Microsoft started a phased, admin-controllable disablement in early October 2026. Since October 10, 2026, tenants with EWSEnabled=True must also have an EWSAllowedAppIDs allow list, and apps not on it are blocked. Tenants left at Null are being switched to False in phases, with a 7-day Message Center warning. Mailboxes licensed only for Exchange Online Kiosk, F1, or F3 started losing EWS access on October 1, 2026. EWS is fully and permanently disabled on April 1, 2027, with no exceptions.
Does the EWS deprecation affect on-premises Exchange Server?
No. The EWS retirement applies only to Exchange Online (Microsoft 365); there are no changes to EWS in Exchange Server. Note that Exchange Server 2016 and 2019 reached end of support on October 14, 2025, so on-premises customers should be on Exchange Server Subscription Edition (SE).
Does Microsoft Graph have full feature parity with EWS?
Not yet. Microsoft's parity roadmap targets Q3 CY2026 for notes, contact lists, and additional contact properties, and Q4 CY2026 for archive mailbox access, archive/public folder/group mailbox import-export, and several other gaps. Microsoft has confirmed that generic public folder CRUD, generic Microsoft 365 Group mailbox CRUD, and Discovery Mailbox access will not be added to Graph.
How long does an EWS to Graph API migration take?
Our estimate for a typical SaaS product with email, calendar, and contacts integration is 5–7 months of focused engineering work covering audit, auth overhaul, API rewrite, throttling redesign, parallel validation, and staged customer rollout.
What are the Microsoft Graph API throttling limits for Outlook?
Microsoft documents 10,000 API requests per 10-minute period, 4 concurrent requests, and 150 MB of upload in a 5-minute period, each applied per app ID + mailbox combination.

More from our Blog