Microsoft deprecated Basic Auth for Exchange Online in October 2022, so every Outlook and Microsoft 365 account now connects through OAuth 2.0 and Microsoft Graph permissions. This page lists the exact Graph scopes Nylas requests for each email, calendar, and contacts feature, so you grant the narrowest set that still works.
For the generic cross-provider scope strings (Google plus Microsoft side by side), see OAuth scopes for email and calendar. This page is the Microsoft-only deep reference.
What Microsoft Graph scopes does Nylas request?
Section titled “What Microsoft Graph scopes does Nylas request?”Nylas requests Microsoft Graph delegated permissions: short names like Mail.Read with no URI prefix, scoped to the signed-in user rather than the whole tenant. The 7 scopes below cover reading and sending mail, managing calendars and events, and reading contacts. Add offline_access to every set so the access token can refresh.
The table maps each Nylas feature to the Graph scope it needs. These names are verified against the Microsoft tab in the granular scopes reference and the OpenAPI x-scopes, so you can copy them into your Azure app registration without guessing.
| Feature | Required Graph scope | Wider scope that also works |
|---|---|---|
| Read messages and attachments | Mail.Read | Mail.ReadWrite |
| Update or delete messages | Mail.ReadWrite | Mail.ReadWrite.Shared |
| Send email | Mail.Send | None |
| Read and write drafts | Mail.ReadWrite | Mail.ReadWrite.Shared |
| Read and write folders | Mail.ReadWrite | None |
| Read calendars and Free/Busy | Calendars.Read | Calendars.ReadWrite |
| Create or update events | Calendars.ReadWrite | None |
| Read contacts | Contacts.Read | People.Read |
| Read and write contacts | Contacts.ReadWrite | None |
| Read room and resource calendars | Place.Read.All | None |
Mail and calendar permissions are separate in Graph, so a calendar-only app never requests a Mail.* scope. Request Mail.ReadWrite and Mail.Send together when you schedule messages for future delivery, which the scopes reference calls out for scheduled send.
Two scopes tie to specific Nylas features rather than to a basic read or write action. Place.Read.All powers GET /v3/grants/<NYLAS_GRANT_ID>/resources, which lists bookable room and equipment resources for meeting scheduling. People.Read is required for the contacts inbox and domain sources, which surface people the user has emailed or who share their tenant directory. Skip both unless your app uses room booking or directory-derived contacts.
Why does Nylas need offline_access?
Section titled “Why does Nylas need offline_access?”Microsoft delegated access tokens expire after about 60 to 90 minutes. offline_access is the Graph scope that returns a long-lived refresh token alongside the access token, and without it the grant stops working after the first token expires with no way to renew. Nylas refreshes the token for you once the scope is granted.
Add offline_access to every scope set, even a read-only one. The hosted OAuth flow at GET /v3/connect/auth sends the connector’s scopes to Microsoft, the user consents once, and the returned refresh token keeps the grant alive until the user or the tenant admin revokes it. Without the refresh token, a background sync job that runs every few hours fails the moment the first 60-minute access token expires, and the grant reports an authentication error until the user reconnects.
The example below shows a read-and-send Microsoft scope set on the authorization request. The four scope names are space-separated in the scope query parameter, exactly as Microsoft expects them.
GET https://api.us.nylas.com/v3/connect/auth? client_id=<NYLAS_CLIENT_ID> &redirect_uri=https://myapp.com/callback &response_type=code &provider=microsoft &scope=Mail.Read Mail.Send Calendars.ReadWrite offline_accessDelegated vs application permissions in Microsoft Graph
Section titled “Delegated vs application permissions in Microsoft Graph”Microsoft Graph offers two permission types, and Nylas uses delegated permissions exclusively. Delegated permissions act on behalf of the signed-in user during an interactive OAuth flow, so the grant can only touch data that user can already see. Application permissions act tenant-wide with no user present and always require admin consent before any account connects.
The distinction decides whether a single admin click or per-user consent unblocks your app. Delegated scopes like Mail.Read let an ordinary user consent for their own mailbox on the standard consent screen. In a locked-down Microsoft 365 tenant, an administrator can still gate even delegated scopes behind tenant-wide approval, which is one click that covers every user at once. Application permissions never offer per-user consent, so granting an application-type Mail.Read in Azure and expecting the hosted flow to use it leads to a common dead end.
Plan for admin consent when your target customers run managed tenants. A 2022 Microsoft change tightened default consent settings, so many enterprise tenants now block user consent entirely and route every new app through an admin. Walk admins through the one-time grant with the Microsoft admin approval guide, and point users who hit the consent wall to Fix the need admin approval error.
When do you need the .Shared scopes?
Section titled “When do you need the .Shared scopes?”You need the .Shared scope variants when your app reads or writes a mailbox or calendar that the signed-in user doesn’t own, such as a shared support inbox or a delegate’s calendar. The base Mail.Read scope only covers the user’s own mailbox, so accessing a shared mailbox requires Mail.Read.Shared or Mail.ReadWrite.Shared on top of it.
Microsoft Graph defines 3 shared variants that map to the Nylas features below. Mail.Read.Shared and Mail.ReadWrite.Shared cover delegated mailbox folders, and Calendars.ReadWrite.Shared covers a delegate’s calendar. The scopes reference lists these 3 scopes as “other scopes” for the messages, drafts, folders, and calendar endpoints, so a delegated request still works when the wider shared scope is present.
| Shared scenario | Graph scope |
|---|---|
| Read a shared or delegated mailbox | Mail.Read.Shared |
| Write to a shared or delegated mailbox | Mail.ReadWrite.Shared |
| Manage a delegate’s calendar | Calendars.ReadWrite.Shared |
Request a .Shared scope only when the use case demands it. A help-desk app that reads one team inbox needs Mail.Read.Shared, but a personal email client never does, and asking for it inflates the consent screen for no reason. The shared Outlook folders guide covers how Nylas exposes delegated mailbox folders once the scope is granted.
How do I set Microsoft scopes in the Nylas SDKs?
Section titled “How do I set Microsoft scopes in the Nylas SDKs?”You set Microsoft scopes on the connector or pass them to the SDK’s OAuth URL builder, not on each API call. The urlForOAuth2 method takes your client ID, the microsoft provider, your callback URI, and a scope array of Graph permission names. Generate the URL per user, then redirect them to Microsoft to consent.
The 5 examples below build the same Microsoft authorization URL with a set of 4 scopes: Mail.Read, Mail.Send, Calendars.ReadWrite, and offline_access. Swap the array for ["Calendars.ReadWrite", "offline_access"] for a calendar-only app, or add Contacts.Read when you sync contacts.
const authUrl = nylas.auth.urlForOAuth2({ clientId: process.env.NYLAS_CLIENT_ID, provider: "microsoft", redirectUri: "https://myapp.com/callback", scope: ["Mail.Read", "Mail.Send", "Calendars.ReadWrite", "offline_access"],});auth_url = nylas.auth.url_for_oauth2({ "client_id": os.environ["NYLAS_CLIENT_ID"], "provider": "microsoft", "redirect_uri": "https://myapp.com/callback", "scope": ["Mail.Read", "Mail.Send", "Calendars.ReadWrite", "offline_access"],})auth_url = nylas.auth.url_for_oauth2({ client_id: ENV["NYLAS_CLIENT_ID"], provider: "microsoft", redirect_uri: "https://myapp.com/callback", scope: ["Mail.Read", "Mail.Send", "Calendars.ReadWrite", "offline_access"]})UrlForAuthenticationConfig config = new UrlForAuthenticationConfig.Builder( System.getenv("NYLAS_CLIENT_ID"), "https://myapp.com/callback") .provider(AuthProvider.MICROSOFT) .scope(new String[]{"Mail.Read", "Mail.Send", "Calendars.ReadWrite", "offline_access"}) .build();String authUrl = nylas.auth().urlForOAuth2(config);val config = UrlForAuthenticationConfig( clientId = System.getenv("NYLAS_CLIENT_ID"), redirectUri = "https://myapp.com/callback", provider = AuthProvider.MICROSOFT, scope = arrayOf("Mail.Read", "Mail.Send", "Calendars.ReadWrite", "offline_access"),)val authUrl = nylas.auth().urlForOAuth2(config)Choose the least-privilege Microsoft scope set
Section titled “Choose the least-privilege Microsoft scope set”Request the smallest scope that covers your features, then widen only when a feature needs it. A smaller consent screen converts better, and a leaked token reaches less data. The table maps 5 common app types to the minimal Microsoft scopes each needs, from a single scope for a read-only inbox up to 4 scopes for a mail-plus-calendar app, with offline_access on every row.
| App type | Microsoft Graph scopes |
|---|---|
| Read-only inbox | Mail.Read, offline_access |
| Full email client | Mail.ReadWrite, Mail.Send, offline_access |
| Calendar scheduler | Calendars.ReadWrite, offline_access |
| Contacts sync | Contacts.Read, offline_access |
| Mail plus calendar | Mail.ReadWrite, Mail.Send, Calendars.ReadWrite, offline_access |
Each row maps to a real product shape. A read-only inbox app that classifies or indexes mail needs only Mail.Read plus offline_access, two scopes total, because it never modifies or sends. A full email client that marks messages read, moves them between folders, and sends replies needs Mail.ReadWrite for the modify and folder operations and Mail.Send for outbound mail. A calendar scheduler that creates and updates events needs Calendars.ReadWrite and nothing from the Mail.* family. A one-way contacts sync that only reads the address book needs Contacts.Read, and upgrades to Contacts.ReadWrite only if it writes contacts back.
Don’t request Mail.ReadWrite when your app only reads mail. Unlike Google, Microsoft doesn’t push you into a third-party security assessment for write scopes, but a tenant admin reviewing the consent screen sees every permission you ask for, and an over-broad request is a common reason a connection gets blocked in a locked-down Microsoft 365 tenant. Over-requesting also draws more scrutiny during a tenant’s app review, and any later scope addition forces every connected user back through consent.
Run through this checklist before you finalize a Microsoft scope set:
- List the exact Nylas endpoints your app calls, then map each to its required scope in the table above.
- Drop any scope no endpoint needs, including
.Sharedvariants unless you read another user’s mailbox. - Use the read scope, not the write scope, wherever your app only reads.
Mail.ReadoverMail.ReadWrite,Calendars.ReadoverCalendars.ReadWrite. - Add
offline_accessso the grant can refresh, since every app needs it. - Add
Place.Read.Allonly for room booking andPeople.Readonly forinboxordomaincontact sources.
Things to know about Microsoft scopes
Section titled “Things to know about Microsoft scopes”Beyond the delegated-versus-application split and the .Shared variants covered above, a few more details change how and when these scopes take effect. Each of the 4 items below maps to a real failure mode developers hit during Microsoft integration.
- Adding a scope forces re-authentication. Microsoft only grants new scopes at consent time. Add
Mail.Sendafter a user already connected withMail.Read, and their existing grant doesn’t gain it. The user re-authenticates through the flow to pick up the wider access. - Conferencing autocreate needs an extra scope. Set up automatic Teams links on events and you also request
OnlineMeetings.ReadWritealongsideCalendars.ReadWrite. See enable autocreate for conferencing for the full setup. - Contacts sources change the scope. The base
Contacts.Readscope covers the user’s personal address book, but theinboxanddomaincontact sources needPeople.Read. Request it only when you read directory or recent-correspondent contacts. - EWS scopes differ. Exchange Web Services accounts don’t use Graph permission names. Microsoft retired EWS in Exchange Online in 2022, so most accounts should connect with the Graph scopes above instead.
The canonical list lives in the Microsoft Graph permissions reference. Cross-check any scope against it before you add it, because Microsoft renames and deprecates permissions over time.
What’s next
Section titled “What’s next”- OAuth scopes for email and calendar for the Google and Microsoft scope strings side by side
- Authenticating Microsoft accounts with Nylas for the full Microsoft auth flow
- Troubleshoot OAuth errors when a Microsoft connection fails or returns 403
- Granular scopes reference for required and optional scopes per Nylas API endpoint