Source: https://cli.nylas.com/guides/ews-to-graph-migration

Guide

# EWS to Microsoft Graph Migration

Microsoft blocks EWS for Exchange Online on October 1, 2026, and permanently removes it on April 1, 2027. This guide covers the full timeline, auth model changes (NTLM to OAuth 2.0), feature parity gaps, and three migration paths. Includes code examples for Graph API and a provider-agnostic alternative. Works with Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP.

Written by [Caleb Geene](https://cli.nylas.com/authors/caleb-geene) • Director, Site Reliability Engineering

Reviewed by [Nick Barraclough](https://cli.nylas.com/authors/nick-barraclough)

Updated April 11, 2026

Verified

 —

CLI

3.1.1

 ·

Exchange

 ·

last tested

April 11, 2026

> **TL;DR:** EWS calls to Exchange Online stop working October 1, 2026. You have three options: migrate to Microsoft Graph API, set up an AppID AllowList for a temporary extension until April 2027, or switch to a unified abstraction that handles both EWS and Graph internally. On-prem Exchange is not affected.

## The deprecation timeline

Microsoft announced EWS retirement in September 2023 and has been tightening the schedule since. According to [Microsoft's official deprecation page](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-ews-exchange-online), here are the dates that matter:

| Date | What happens |
| --- | --- |
| **July 1, 2026** | F1, F3, and Kiosk licenses start returning HTTP 403 for EWS |
| **August 2026** | Deadline to configure AppID AllowList for temporary exemption |
| **October 1, 2026** | EWS blocked for all non-Microsoft apps without AllowList |
| **April 1, 2027** | EWS permanently removed. No re-enablement, no exceptions |

If you do nothing, your EWS-based code returns errors starting October 2026. The [TechCommunity announcement](https://techcommunity.microsoft.com/blog/exchange/retirement-of-exchange-web-services-in-exchange-online/3924440) confirms that Microsoft will set `EWSEnabled=False` on tenants that haven't opted in.

## On-premises Exchange: not affected

EWS on Exchange Server 2016 and 2019 is **not deprecated**. On-prem mailboxes continue to use EWS with no changes. This creates a split for hybrid deployments: cloud mailboxes must use Graph, on-prem mailboxes still use EWS. If you maintain both, you need two codepaths -- or an abstraction that handles the routing.

## Auth model: NTLM/Basic to OAuth 2.0

EWS traditionally used NTLM, Kerberos, or Basic Auth. Graph API requires OAuth 2.0 with Azure AD (Entra ID) app registrations. The migration means:

- **Register an Azure AD app** with Mail.Read, Mail.Send, Calendars.ReadWrite, or other scopes
- **Choose a flow**: authorization code (delegated) for user context, client credentials (application) for daemon/service apps
- **Handle token lifecycle**: access tokens expire in 60-90 minutes, refresh tokens in 90 days
- **Admin consent**: application-level permissions need tenant admin approval

```powershell
# EWS (old) - Basic Auth or NTLM
$cred = Get-Credential
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
$service.Credentials = $cred
$service.Url = "https://outlook.office365.com/EWS/Exchange.asmx"

# Graph API (new) - OAuth 2.0 with MSAL
Connect-MgGraph -Scopes "Mail.Read","Mail.Send"
$messages = Get-MgUserMessage -UserId "me" -Top 10
```

## Feature parity gaps (as of April 2026)

Graph API covers most EWS scenarios, but [gaps remain](https://techcommunity.microsoft.com/blog/exchange/exchange-online-ews-your-time-is-almost-up/4492361):

| EWS Feature | Graph API Status |
| --- | --- |
| Archive mailbox access | Not available |
| Public folder CRUD | Not planned -- restricted to Outlook clients only |
| Mailbox import/export | Not available |
| Recurring event delta queries | Partial support |
| User configuration (dictionary items) | Covered by Exchange Admin API (preview) |
| Extended properties (custom MAPI props) | Supported via singleValueExtendedProperties |
| Autodiscover | Not needed -- Graph uses a single endpoint |
| Mail read/send/search | Full parity |
| Calendar events CRUD | Full parity |
| Contacts CRUD | Full parity |

Microsoft released the [Exchange Admin API](https://office365itpros.com/2025/11/18/exchange-admin-api-preview/) as a temporary bridge for some gaps. But there's no firm date for when all parity gaps close.

## Three migration paths

### Path 1: Migrate to Microsoft Graph API

The official path. Replace every EWS call with its Graph equivalent. Microsoft provides an [EWS code analyzer](https://devblogs.microsoft.com/microsoft365dev/exchange-web-services-code-analyzer-and-usage-report/) that scans your codebase and maps EWS operations to Graph API equivalents.

```powershell
# EWS: Find emails by subject
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(50)
$filter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring(
  [Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject, "invoice")
$results = $service.FindItems(
  [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox, $filter, $view)

# Graph: Same operation
$messages = Get-MgUserMessage -UserId "me" -Filter "contains(subject, 'invoice')" -Top 50
```

**Pros:** Stays within the Microsoft ecosystem, access to newest features. **Cons:** Azure AD app registration, OAuth token management, no support for non-Microsoft providers, feature parity gaps.

### Path 2: Temporary AppID AllowList

Buys time until April 2027. Register your app's ID in the tenant's EWS AllowList before August 2026:

```powershell
# Check current EWS settings
Get-OrganizationConfig | Select-Object EwsEnabled, EwsAllowList

# Add your app to the AllowList
Set-OrganizationConfig -EwsAllowList @{Add="your-app-client-id"}
Set-OrganizationConfig -EwsEnabled $true
```

**Pros:** No code changes needed immediately. **Cons:** Only delays the problem by 6 months. EWS is permanently removed April 1, 2027.

### Path 3: Use a unified abstraction

Instead of migrating from one Microsoft-specific protocol to another, use a tool that abstracts away the provider layer entirely. Nylas CLI connects to Exchange Online, on-prem Exchange, Gmail, Outlook, Yahoo, iCloud, and IMAP through one interface:

```bash
# Install
brew install nylas/nylas-cli/nylas

# Authenticate (handles OAuth, EWS, Graph internally)
nylas auth config

# Read email -- works regardless of whether the mailbox is
# Exchange Online (Graph), Exchange on-prem (EWS), or Gmail
nylas email list --limit 10

# Search
nylas email search "invoice" --limit 50

# Send
nylas email send \
  --to "colleague@company.com" \
  --subject "Report" \
  --body "Attached." \
  --attach ./report.pdf
```

**Pros:** No protocol-specific code, no Azure AD app registration, works across all providers, on-prem and cloud through one interface. **Cons:** External dependency. Requires Nylas API key.

## Side-by-side comparison

| Concern | EWS (retiring) | Graph API | Nylas CLI |
| --- | --- | --- | --- |
| Auth | NTLM / Basic / OAuth | OAuth 2.0 only | One-time `nylas auth config` |
| Azure AD app required | No (Basic) / Yes (OAuth) | Yes | No |
| On-prem Exchange | Supported | Not supported | Supported (via EWS internally) |
| Exchange Online | Blocked Oct 2026 | Supported | Supported (via Graph internally) |
| Gmail, Yahoo, iCloud | Not supported | Not supported | Supported |
| Token management | Manual | Manual (MSAL) | Automatic |
| Code changes needed | N/A (retiring) | Full rewrite from EWS | One-time migration |

## Hybrid Exchange: the dual-codebase problem

Many organizations run hybrid Exchange -- some mailboxes in Exchange Online, some on-prem. After October 2026, cloud mailboxes need Graph API while on-prem mailboxes still need EWS. Microsoft Graph doesn't support on-prem Exchange Server at all.

This forces two authentication flows, two API surfaces, and two sets of error handling in the same application. The Nylas platform handles this routing internally -- it detects whether a mailbox is cloud or on-prem and uses the appropriate protocol.

## Migration checklist

1. **Audit your EWS usage** -- Run Microsoft's [EWS code analyzer](https://devblogs.microsoft.com/microsoft365dev/exchange-web-services-code-analyzer-and-usage-report/) to inventory every EWS call
2. **Check for parity gaps** -- Compare your EWS operations against the feature gap table above
3. **Register your app before August 2026** -- If you need more time, add your app to the AllowList
4. **Test with F1/F3 licenses first** -- These were blocked in March 2026, so they're already on the new behavior
5. **Plan for hybrid** -- If you have on-prem Exchange, decide how to handle the dual-protocol split
6. **Monitor Microsoft's updates** -- Feature parity gaps are closing quarterly

## Frequently asked questions

### When is EWS being retired for Exchange Online?

Microsoft blocks EWS requests from non-Microsoft apps starting October 1, 2026. Tenants that configure an AppID AllowList before August 2026 get a temporary exemption. All EWS access is permanently removed on April 1, 2027.

### Is EWS deprecated for on-premises Exchange Server?

No. EWS remains fully supported for Exchange Server 2016 and 2019. The deprecation only affects Exchange Online (Microsoft 365).

### What EWS features are missing from Graph API?

As of April 2026, Graph API lacks archive mailbox access, public folder CRUD, mailbox import/export, and full recurring event delta support. Microsoft is closing gaps quarterly but hasn't committed to a date for full parity.

### Can I skip the migration entirely?

Yes, if you use an abstraction layer. The Nylas platform connects to Exchange Online, on-prem Exchange, and 4 other providers through a single interface. Provider-side deprecations don't require code changes on your end.

## Next steps

- [List Exchange emails from the CLI](https://cli.nylas.com/guides/list-exchange-emails) -- read and search Exchange mailboxes without EWS or Graph
- [Manage Exchange calendar from the CLI](https://cli.nylas.com/guides/manage-exchange-calendar-cli) -- create, update, and delete events
- [Replace Send-MgUserMessage](https://cli.nylas.com/guides/replace-send-mgusermessage) -- migrate from Graph PowerShell cmdlets
- [Manage Office 365 email from PowerShell](https://cli.nylas.com/guides/office365-email-powershell) -- read, search, and organize your M365 inbox
- [Send email from the terminal](https://cli.nylas.com/guides/send-email-from-terminal) -- the cross-provider email sending guide
- [Full command reference](https://cli.nylas.com/docs/commands) -- every flag and subcommand documented
