You build one auth flow for Microsoft and assume it covers every “Exchange” account a customer throws at you. Then a finance company connects, their mailboxes sit on a server in their own data center, and your OAuth redirect goes nowhere. The word “Exchange” hides two completely different auth models, and picking the wrong one breaks the connection before you read a single message.
This page compares how authentication works for on-premises Exchange Server versus Microsoft 365, shows the request shape for each, and explains how one API connects both behind a single grant. For the protocol-level split, see EWS vs Microsoft Graph for email.
How does OAuth work differently for Exchange Server versus Microsoft 365?
Section titled “How does OAuth work differently for Exchange Server versus Microsoft 365?”Microsoft 365 uses standard OAuth 2.0: you redirect the user to Microsoft, they consent, and you exchange a code for an access_token and refresh_token. On-premises Exchange Server has no OAuth provider. It authenticates with a username and password over EWS, commonly through Basic or NTLM, against a server the customer runs themselves.
That difference shapes the whole integration. Microsoft 365 flows through Microsoft Entra and a managed cloud endpoint, so consent, token refresh, and scopes all follow OAuth conventions. On-prem Exchange Server predates that model entirely. Microsoft disabled Basic authentication for Exchange Online on October 1, 2022, but that change touched only the cloud. A self-hosted Exchange 2007 or later server keeps accepting whatever auth its administrator configured, which is why a single OAuth flow can’t cover both deployments.
Exchange Server vs Microsoft 365 auth, side by side
Section titled “Exchange Server vs Microsoft 365 auth, side by side”The two deployments split on every part of the auth flow, from where the credential lives to how long it lasts. Microsoft 365 issues short-lived OAuth tokens you refresh automatically; on-prem Exchange Server validates a password directly against the server on each connection. The table below maps the 6 auth dimensions that matter most, with the unified path in the last column.
| Auth dimension | On-prem Exchange Server (EWS) | Microsoft 365 (Graph) | Through Nylas (unified) |
|---|---|---|---|
| Mechanism | Username + password, Basic or NTLM | OAuth 2.0 redirect + token | One Hosted auth flow |
| Credential store | Customer’s own server | Microsoft Entra | A grant ID |
| Consent | None, direct sign-in | Admin or user consent per tenant | provider=ews or microsoft |
| Token refresh | No tokens, re-auth on expiry | refresh_token rotates access | Handled for you |
| Basic Auth status | Still supported on-prem | Disabled since Oct 1, 2022 | Both covered |
| Read mail call | FindItem SOAP | GET /me/messages | GET /v3/grants/{id}/messages |
What is the difference between the Outlook calendar API and the Microsoft Graph?
Section titled “What is the difference between the Outlook calendar API and the Microsoft Graph?”There’s no separate “Outlook calendar API” anymore. Microsoft Graph is the single REST API for Outlook and Microsoft 365 calendars, reached at graph.microsoft.com. The older standalone Outlook REST API was decommissioned on March 31, 2024, so Graph endpoints like GET /me/events and POST /me/calendar/events are now the only supported cloud path for Outlook calendar data.
For Microsoft 365 calendars, Graph requires an OAuth token scoped with Calendars.Read or Calendars.ReadWrite, approved through Microsoft Entra. On-premises Exchange Server is the exception: it has no Graph endpoint at all, and you read calendar data over the EWS SOAP protocol instead. So “Outlook calendar” can mean two unrelated APIs depending on where the mailbox lives. Microsoft documents the cloud surface in its calendar API overview. A unified layer hides that fork: you call GET /v3/grants/{grant_id}/events?calendar_id=primary for either deployment and get the same JSON back.
Which email APIs support Microsoft Exchange Server calendar API integration?
Section titled “Which email APIs support Microsoft Exchange Server calendar API integration?”Few email APIs reach on-premises Exchange Server, because it requires SOAP over EWS rather than REST and OAuth. Microsoft Graph covers only Exchange Online and Microsoft 365, not self-hosted servers. Nylas connects both: the ews connector reaches on-prem Exchange 2007 and later, while the microsoft connector handles Microsoft 365 through Graph, both behind one schema.
Most modern providers target the cloud only, so on-prem Exchange Server falls outside their coverage and you’re left writing raw EWS SOAP yourself. Supporting a self-hosted Exchange calendar means handling autodiscovery, NTLM, and a specific server address and port, none of which a cloud-only OAuth integration does. The unified approach treats both as grants: connect an on-prem mailbox with provider=ews, connect a Microsoft 365 mailbox with provider=microsoft, then call GET /v3/grants/{grant_id}/events?calendar_id=primary against either. The connect Exchange (EWS) accounts guide covers the on-prem connect flow end to end.
Connect a Microsoft 365 account with OAuth
Section titled “Connect a Microsoft 365 account with OAuth”For Microsoft 365, you start the OAuth flow by redirecting the user to GET /v3/connect/auth with provider=microsoft. The user consents in Microsoft Entra, then Microsoft sends a code back to your redirect_uri. This is the standard three-leg OAuth handshake, and it usually completes in under 30 seconds once admin consent is in place for the tenant.
The request below sends the user into the hosted Microsoft 365 consent screen. Set redirect_uri to a callback you registered, and pass provider=microsoft so the API routes to Graph and OAuth. The flow returns a code you exchange next.
curl --request GET \ --url "https://api.us.nylas.com/v3/connect/auth?client_id=<NYLAS_CLIENT_ID>&provider=microsoft&redirect_uri=<YOUR_CALLBACK_URL>&response_type=code"After the redirect, swap the code for a grant. Send a POST to /v3/connect/token with grant_type set to authorization_code. The response includes a grant_id plus access_token and refresh_token, and the API rotates the access token for you on later calls so you never refresh it by hand.
curl --request POST \ --url "https://api.us.nylas.com/v3/connect/token" \ --header "Content-Type: application/json" \ --data '{ "client_id": "<NYLAS_CLIENT_ID>", "client_secret": "<NYLAS_API_KEY>", "grant_type": "authorization_code", "code": "<RETURNED_CODE>", "redirect_uri": "<YOUR_CALLBACK_URL>" }'Connect an on-prem Exchange Server account
Section titled “Connect an on-prem Exchange Server account”On-premises Exchange Server skips OAuth entirely. You still call GET /v3/connect/auth, but with provider=ews, and the hosted page collects an Exchange username and password instead of showing a consent screen. The user signs in with a username formatted as [email protected] or DOMAIN\username, and the API authenticates straight against the server, typically in under 5 seconds when autodiscovery succeeds.
The request below starts the EWS connect flow. The shape matches the Microsoft 365 call, only provider changes, which is the whole point of the unified model. Replace the placeholders before running it.
curl --request GET \ --url "https://api.us.nylas.com/v3/connect/auth?client_id=<NYLAS_CLIENT_ID>&provider=ews&redirect_uri=<YOUR_CALLBACK_URL>&response_type=code"One honest tradeoff: if every customer you serve is cloud-only Microsoft 365 and you need Teams, SharePoint, or OneDrive too, calling Microsoft Graph directly gives you the full surface and one less layer. The unified API earns its place when you must support self-hosted Exchange Server, or more than one provider, without writing a separate SOAP integration for the on-prem case.
Read mail and calendar through one grant
Section titled “Read mail and calendar through one grant”Once connected, both deployments answer the same calls. You read mail with GET /v3/grants/{grant_id}/messages and calendar events with GET /v3/grants/{grant_id}/events?calendar_id=primary, whether the grant points at an on-prem EWS server or a Microsoft 365 mailbox on Graph. The response shape is identical, so you write one parser instead of branching on provider.
The request below lists up to 50 messages from any connected account. Swap the grant ID and the call stays the same across EWS and Graph, and across Google or iCloud grants too. Replace the bearer token with your API key.
curl --request GET \ --url "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages?limit=50" \ --header "Authorization: Bearer <NYLAS_API_KEY>"from nylas import Client
nylas = Client(api_key="<NYLAS_API_KEY>")
messages = nylas.messages.list( "<NYLAS_GRANT_ID>", query_params={"limit": 50},)
for message in messages.data: print(message.subject, message.from_)To audit which deployment a grant uses, list grants filtered by provider with GET /v3/grants?provider=ews or provider=microsoft. That tells you at a glance how many on-prem versus cloud mailboxes you’ve connected, which matters when you plan for the Exchange Online EWS retirement.
What’s next
Section titled “What’s next”- Connect Exchange (EWS) accounts for the full on-prem connect and grant flow
- EWS vs Microsoft Graph for email for the protocol-level comparison and retirement timeline
- OAuth scopes for email and calendar for the exact Microsoft Graph scope strings
- Getting started with Nylas to create a project, connector, and your first grant