Microsoft started turning off Exchange Web Services (EWS) in Exchange Online on October 1,
2026. Tenants that never set EWSEnabled are being switched to
False as the rollout reaches them, and an integration that was working last week
now gets 403 Forbidden. Admins can still switch EWS back on until April 1, 2027,
and then it is gone for good. This post is for the developer who owns that integration: what
was announced, how to tell whether it is yours, how EWS operations, permissions and
notifications map to Microsoft Graph, and where Graph still falls short. Dates and limits are
as of October 30, 2026 and come from Microsoft’s own pages, linked inline.
What Microsoft announced.
- 2018 and 2023. EWS stopped receiving feature updates in 2018, and in 2023 Microsoft said it would be disabled in Exchange Online in October 2026 (Deprecation of EWS in Exchange Online).
- October 1, 2026. Phased, tenant-by-tenant disablement starts. A tenant with
EWSEnabledstillNullis changed toFalseas the rollout reaches it, which blocks EWS for every application in the tenant. A tenant that set an AppID allow list andEWSEnabled=Trueby the end of September was excluded from that change (Exchange Online EWS, Your Time is Almost Up). - April 1, 2027. EWS is disabled for good and tenant admins lose the switch. Microsoft’s FAQ says there will be no exceptions past that date.
The retirement covers Exchange Online in all environments. Exchange Server on premises keeps EWS: “there are no changes to EWS in Exchange Server,” and on-premises mailboxes can keep using it while cloud mailboxes must move to Graph. These pages give no separate EWS date for sovereign clouds. Microsoft’s parity roadmap does list “Sovereign Cloud availability” of the Exchange APIs needed for EWS migration as a Q4 2026 target, so check that a Graph feature exists in your tenant’s cloud before you rely on it.
Check whether you are affected.
A blocked EWS request returns 403 Forbidden with an
X-EWS-Policy-Reason header, which says why
(Control access to EWS):
| Header value | Meaning |
|---|---|
EWS is disabled for this user or tenant | The organization or mailbox EwsEnabled setting blocks the request. |
EWS is blocked by policy for this user or tenant |
An application access policy blocks it: the app ID is not in
EwsAllowedAppIDs, or its user agent fails the older allow or block list.
The header does not say which.
|
A 403 alone does not prove EWS was the cause, since other access restrictions also return it. Clients that do not read the header show other symptoms; Microsoft lists repeated credential prompts and an error that EWS is unavailable (EWS application stopped working? Do this.).
The tenant admin sees the change in the Message Center, in posts titled “Action may be required: EWS will be disabled in your tenant in 7 days” or “EWS has been disabled in your tenant.” The admin center also has an EWS usage report that lists the app IDs calling EWS. If you ship software to other companies, you cannot see their tenants, so expect support tickets from admins who can.
The tenant controls.
Two settings decide whether EWS works for an app. The organization-level
EWSEnabled is True, False or Null
(the default, which behaves as True), and EWSAllowedAppIDs is a list
of application IDs
(Introducing EWSAllowedAppIDs).
Since October 2026:
EWSEnabled | AppID allow list | Result |
|---|---|---|
Null | Ignored | All EWS allowed, until Microsoft changes the tenant to False |
True | Empty | All EWS blocked |
True | Populated | Only listed apps allowed |
False | Any | All EWS blocked |
Cross-tenant organization relationships keep working in the blocked rows. Microsoft said it would fill the allow list for tenants that had none, from each tenant’s EWS use over the last 60 days, and an admin who builds their own list keeps it unchanged. Changes to the list can take up to 24 hours to apply.
If a customer asks you to get their integration working again today, the admin has two routes,
and Microsoft support cannot do either for them. In the admin center’s Baseline Security
Mode page, clear and then re-apply “Block your entire organization from using EWS,”
or in Exchange Online PowerShell run Set-OrganizationConfig -EWSEnabled $true. It
usually takes under an hour and can take 4. Both are stopgaps that end in April 2027, and the
older user-agent EwsAllowList is a separate gate: a request has to pass both.
EWS to Graph, operation by operation.
Microsoft publishes a direct EWS to Graph mapping. The common mail and sync operations:
| EWS | Microsoft Graph |
|---|---|
FindItem, GetItem | List messages, get message |
CreateItem, UpdateItem, DeleteItem | Create, update, delete message |
MoveItem, CopyItem | Move, copy message |
SendItem | Send message or send mail |
CreateFolder, GetFolder, UpdateFolder, MoveFolder | Mail folder create, get, update and move |
CreateAttachment, GetAttachment | Add and get attachment |
SyncFolderItems | Get messages delta |
SyncFolderHierarchy | Get mail folder delta |
GetEvents (pull notifications) | Messages delta |
Subscribe (push notifications) | Create subscription |
GetUserAvailability | Get free/busy schedule |
GetUserOofSettings, SetUserOofSettings | Get and update mailbox settings |
ConvertId | Translate Exchange IDs |
Calendar items and contacts are CreateItem and FindItem calls in EWS,
too. In Graph they are their own resources:
events,
create event,
contacts and
create contact.
Sync for each has a delta function, as
calendarView/delta
and contact delta.
Permissions change shape.
An EWS app asks for one broad permission. Delegated apps request
EWS.AccessAsUser.All on the Exchange resource, and daemon apps use
full_access_as_app and name the mailbox to impersonate
(Authenticate an EWS application by using OAuth).
Graph splits the same access by data type:
- Delegated:
Mail.ReadWriteandMail.Send,Calendars.ReadWrite,Contacts.ReadWrite, andMailboxSettings.Readwhen you need the mailbox time zone. Shared mailboxes need the.Sharedvariants. Read-only integrations can ask for less, such asMail.ReadorCalendars.Read(permissions reference). - Application: the same names as application permissions, consented by an
administrator, calling
/users/{id or upn}because a client-credentials token has no/me. Unscoped, they reach every mailbox in the tenant, so limit them with RBAC for Applications in Exchange Online, which replaces Application Access Policies.
The token audience changes too: an EWS token is issued for outlook.office365.com
and a Graph token for graph.microsoft.com. The new permissions are separate
entries on the consent screen, so plan on every user or admin consenting again, unless your app
registration already holds them.
Notifications: from streams to webhooks and delta.
EWS offers three subscription types: streaming, pull and push (Notification subscriptions in EWS). Microsoft’s mapping sends pull to a delta query and push to a Graph subscription, and its mapping has no entry for streaming. In practice a streaming consumer ends up with the same pair as everyone else: a subscription that wakes you, and a delta query that reads the change.
That changes the shape of the service. A streaming client held an outbound connection open and
needed no public address. A Graph subscription POSTs to an HTTPS endpoint you expose, validates it
with a handshake, expires in under seven days and needs renewing, and says only where to look.
Microsoft Graph change notifications for
mail and calendar sync covers the handshake, lifecycle events, delta tokens and throttling.
A pull client is the easiest port, as SyncFolderItems and GetEvents
both become one delta call per folder.
Where the port bites.
- Stored ids stop matching. EWS and Graph ids are different formats. Translate
stored ids with
translateExchangeIds, and ask for immutable ids withPrefer: IdType="ImmutableId"on requests and when creating subscriptions. An immutable id survives a move between folders, but changes if the item moves to an archive mailbox or is exported and imported again (immutable identifiers). - Paging is explicit. Messages come ten at a time by default;
$toptakes 1 to 1,000 (list messages). - Large attachments need a session. A file under 3 MB is one POST; from 3 MB to 150 MB you create an upload session and PUT byte ranges (large attachments).
- MIME sending exists, MIME editing does not yet.
sendMailaccepts base64 MIME with atext/plainbody (send mail), but creating or updating a non-draft message from MIME is on the roadmap rather than shipped. - Throttling is per app and mailbox. Outlook allows four concurrent requests and 10,000 requests in 10 minutes (Outlook service limits). An EWS client that fanned out requests per item needs a queue.
What Graph does not cover.
Microsoft tracks the remaining gaps on its deprecation page and warns that a capability missing from the roadmap should not be expected before EWS ends. Targeted for Q3 or Q4 2026, and subject to change: notes, contact lists, extra contact properties, mark-all-as-read, report message, user configuration objects, MIME create and update for non-draft messages, in-place archive access, full-fidelity import and export for archives, public folders and groups, and Exchange Admin API folder permissions. Three capabilities are confirmed as never coming: generic public folder CRUD, generic Microsoft 365 group mailbox CRUD and discovery mailbox access. If your integration depends on one of those, the remaining choices are the Purview eDiscovery APIs for discovery work, or a redesign.
How Workwae handles Microsoft 365.
Workwae has no EWS connector, so none of its Microsoft 365 accounts depend on EWS. Mailboxes connect through Microsoft Graph, and your code calls Workwae’s API instead of Graph.
- Delegated sign-in asks for
User.Read,offline_access, thenMail.ReadWriteandMail.Sendfor mail,Calendars.ReadWriteandMailboxSettings.Readfor calendar andContacts.ReadWritefor contacts, each only when that data is switched on. The.Sharedpermissions are added only when shared mailboxes are turned on. - App-only access is an organization connection. Its Entra app needs
Mail.ReadWriteandMail.Send, and optionallyCalendars.ReadWrite,MailboxSettings.Read,Contacts.ReadWriteandUser.Read.All. - Sync uses delta queries for messages, folders, events and contacts, with
subscriptions on
me/messages,me/eventsandme/contactsand a backstop poll, as described in the notifications article. - Government clouds: GCC High accounts call
graph.microsoft.usand DoD accountsdod-graph.microsoft.us, each with its own app registration (GCC High and DoD email API). 21Vianet mailboxes connect over IMAP and SMTP instead, because Graph mail sync does not run there yet (Microsoft 365 provider). - Your side receives signed webhooks such as
message.created,message.updatedand thecalendar_event.*andcontact.*events, never a Graph notification (webhooks guide).
Limits.
- Users sign in again. Workwae connects through Graph scopes. An EWS grant,
which carries
EWS.AccessAsUser.All, is a different permission, so users sign in through hosted connect, or an admin consents for an organization connection. Plan for that in the move (Move an EWS integration to Workwae). - No EWS connector, and no on-premises Exchange over EWS. A server that allows IMAP and SMTP connects as an IMAP account.
- Workwae’s own model, not Graph’s. It has no public folders, archive mailboxes, inbox rules, out-of-office settings or MailTips. If you need those, the gaps above apply to you either way.
- Alpha SDKs.
@workwae/sdkis at 0.1.0-alpha andworkwaeat 0.1.0a2.