October 1, 2026
Phased disablement starts. Tenants that never set EWSEnabled are switched to False, and EWS calls get a 403.
Exchange Online started switching EWS off on October 1, 2026. Workwae connects Microsoft 365 mailboxes through Microsoft Graph and gives your code one API for mail, calendars and contacts, so there is no EWS client left to port.
// Before: FindItem over EWS, SOAP, a stored mailbox login
// After: one call, whichever provider the mailbox is on
const { items } = await workwae.messages.list({
accountId,
unread: true,
});# Before: FindItem over EWS, SOAP, a stored mailbox login
# After: one call, whichever provider the mailbox is on
page = workwae.messages.list(
account_id=account_id,
unread=True,
)As of October 30, 2026, from Microsoft’s deprecation page and Exchange Team blog.
Phased disablement starts. Tenants that never set EWSEnabled are switched to False, and EWS calls get a 403.
Until April 2027, a tenant admin can turn EWS back on, with an app ID allow list. Your customers decide that, not you.
EWS is disabled for good in Exchange Online, with no exceptions past that date.
Exchange Server keeps EWS. Workwae does not speak EWS, so on-premises servers connect over IMAP and SMTP.
The full timeline, the tenant controls and the Graph mapping are in Exchange Web Services is being retired.
There is no EWS import. Workwae has no EWS connector, so the move is a code change plus one sign-in or admin consent per mailbox.
List the EWS operations your code uses and whether it runs as the user or impersonates mailboxes. Most apps use a handful.
Delegated sign-in for each user, or an organization connection that an administrator consents to for many mailboxes.
Send users through hosted connect, keyed to your own record with externalRef.
Replace each EWS operation with its Workwae call, from the table below.
Drop the streaming, pull or push subscription and add a Workwae webhook endpoint.
Run both side by side per mailbox, then remove your app from the tenant’s EWS allow list.
An EWS app holds EWS.AccessAsUser.All or full_access_as_app. Graph asks for separate permissions, so plan for users or an administrator to consent again.
Hosted connect asks for Mail.ReadWrite and Mail.Send, plus Calendars.ReadWrite and Contacts.ReadWrite only when you turn those on.
An organization connection uses your Entra app with Graph application permissions, consented by an administrator. It replaces full_access_as_app and impersonation.
Use your own Entra app so the consent screen names your product, or the platform app. GCC High and DoD need an app registered in that cloud.
A delegated grant with the .Shared permissions opens the shared mailboxes the user can reach.
// Delegated: one link per user, keyed to your own record
const session = await workwae.connectSessions.create({
redirectUri: "https://app.example.com/mail/connected", // allowlisted first, under Settings
providers: ["microsoft"],
externalRef: user.id,
loginHint: user.email,
options: { calendarEnabled: true, contactsEnabled: true },
});
// App-only: your Entra app, consented by the directory's administrator
const connection = await workwae.orgConnections.create({
kind: "microsoft_app",
name: "Contoso",
cloud: "global",
credential: { type: "certificate", clientId, certificate, privateKey },
directoryId,
});
await workwae.orgConnections.test({ connectionId: connection.id });# Delegated: one link per user, keyed to your own record
session = workwae.connect_sessions.create(
redirect_uri="https://app.example.com/mail/connected", # allowlisted first, under Settings
providers=["microsoft"],
external_ref=user.id,
login_hint=user.email,
options={"calendar_enabled": True, "contacts_enabled": True},
)
# App-only: your Entra app, consented by the directory's administrator
connection = workwae.org_connections.create(
kind="microsoft_app",
name="Contoso",
cloud="global",
credential={
"type": "certificate",
"client_id": client_id,
"certificate": certificate,
"private_key": private_key,
},
directory_id=directory_id,
)
workwae.org_connections.test(connection_id=connection.id)Workwae has its own mail, calendar and contact model, the same for Gmail, Microsoft 365 and IMAP. It is not a pass-through of Graph.
| In EWS | In Workwae |
|---|---|
FindItem, GetItem on messages | messages.list and messages.get; ranked full-text search over the synced index |
UpdateItem (read state and similar) | messages.update, written to the provider and the index |
CreateItem and SendItem for mail | outbox.create, with scheduling and undo |
| Calendar items | calendarEvents.create, calendarEvents.update and calendarEvents.respond |
GetUserAvailability | availability.find |
| Contacts | contacts.create and contacts.update |
SyncFolderItems, GetEvents | The change feed, paged by transaction id |
| Streaming, pull and push subscriptions | Signed webhooks with a delivery log and replays |
Impersonation with full_access_as_app | An organization connection with application permissions |
Workwae has no calls for these. Microsoft’s parity roadmap says which have a Graph equivalent.
Workwae ids are new. Keep the mailbox’s externalRef as your link, and key messages by Workwae id after each account’s first sync, which ends with account.initialized.
Yes, in most cases. An EWS grant is a different permission from the Graph ones Workwae uses, so users sign in through hosted connect, or an administrator consents once for an organization connection. If your own app already holds Graph consent for some users, you can import their refresh tokens with accounts.create instead (your own OAuth app).
Only if the customer’s tenant admin allows it. Admins can re-enable EWS until April 1, 2027, in Baseline Security Mode or with Set-OrganizationConfig -EWSEnabled $true. After that there is no switch.
Not over EWS. A server that allows IMAP and SMTP connects as an IMAP account. Microsoft is not retiring EWS in Exchange Server.
No, but your own app puts your product name on the consent screen and is the way to connect GCC High and DoD, where each cloud needs its own registration (GCC High and DoD).
Webhooks. Workwae keeps the Graph subscriptions and delta queries, with a backstop poll, and sends your endpoint signed events such as message.created. Verify them with parseWebhook in the TypeScript SDK or parse_webhook in the Python SDK (webhooks guide).
Commercial and GCC, GCC High and DoD over Graph. 21Vianet mailboxes connect over IMAP and SMTP, because Graph mail sync does not run there yet (Microsoft 365).
Not yet. @workwae/sdk for TypeScript is at 0.1.0-alpha and workwae for Python is at 0.1.0a2, and Workwae is in early access.
Tell us what your integration calls and which Microsoft clouds your customers are in, and we will plan the move with you.