Hi team,
I am integrating Microsoft calendars through Nylas Hosted Auth. Google connects fine.
For Microsoft:
If the flow hits /common, I get: You cannot sign in here with a personal account. Use your work or school account instead.
If I force /consumers, Microsoft shows consent and emails me that the app is connected, but my app returns to /app/assistant/calendar?error=oauth_error.
I need help making personal Microsoft accounts work on /common and completing the Nylas token exchange without errors.
Environment
Please assume redacted values below. I will share exact values with support privately if needed.
- Region: Nylas US
- Framework: Next.js (App Router)
- Microsoft Graph permissions: User.Read, offline_access, openid, email, profile, Calendars.Read, Calendars.ReadWrite
- Azure sign in audience: Accounts in any organizational directory and personal Microsoft accounts
What I am trying to do
Let users connect a Microsoft personal account or a work account to my app using Nylas Hosted Auth. Store the Nylas grant and list calendars.
Expected result
Personal Microsoft accounts should sign in on /common
After consent, Nylas should redirect back to my callback and I should be able to exchange for a Nylas grant
Actual result
/common: Microsoft shows “You cannot sign in here with a personal account. Use your work or school account instead.”
/consumers: Microsoft consent completes and sends the security email, then my app lands on
…/calendar?error=oauth_error&message=Calendar connection was cancelled or failed.
Repro steps
Start OAuth using Nylas Hosted Auth URL generated by the SDK
For /common: user enters a personal Microsoft account and gets the work or school only message
For /consumers: user completes consent, Microsoft emails confirmation, then redirect to my app shows oauth_error
Current configuration
- Azure App Registration
- Application ID: <AZURE_CLIENT_ID>
- Supported account types: Any organizational directory and personal Microsoft accounts
- Redirect URIs (Web): includes https://api.us.nylas.com/v3/connect/callback
- Certificates and secrets: client secret value is set and not expired
- Nylas Microsoft connector
- Provider: microsoft
- Tenant: common
- Client ID: <AZURE_CLIENT_ID>
- Client secret: <AZURE_CLIENT_SECRET_VALUE>
- Scopes mirror the Azure app
App code
Start of flow (server action):
const authUrl = nylasClient.auth.urlForOAuth2({clientId: process.env.NYLAS_CLIENT_ID!,redirectUri: ${process.env.NEXT_PUBLIC_APP_URL}/app/integrations/nylas/oauth/callback,state: JSON.stringify({ businessId: “”, provider: “microsoft” }),provider: “microsoft”});
Callback exchange:
const grant = await nylasClient.auth.exchangeCodeForToken({clientId: process.env.NYLAS_CLIENT_ID!,redirectUri: ${process.env.NEXT_PUBLIC_APP_URL}/app/integrations/nylas/oauth/callback,code,});
Observed behavior and URLs
URL via tenant common
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=<AZURE_CLIENT_ID>&redirect_uri=https%3A%2F%2Fapi.us.nylas.com%2Fv3%2Fconnect%2Fcallback&response_type=code&scope=User.Read+offline_access+openid+email+profile+Calendars.Read+Calendars.ReadWrite&prompt=select_account&state=<REDACTED>&tenant=common
Result: personal accounts are blocked with the work or school only message.
URL via tenant consumers
https://login.live.com/oauth20_authorize.srf?client_id=<AZURE_CLIENT_ID>&redirect_uri=https%3A%2F%2Fapi.us.nylas.com%2Fv3%2Fconnect%2Fcallback&response_type=code&scope=User.Read+offline_access+openid+email+profile+Calendars.Read+Calendars.ReadWrite&prompt=select_account&state=<REDACTED>&tenant=consumers
Result: consent completes and Microsoft sends the app connected email. My app then receives an oauth_error on the return from Nylas.
Troubleshooting already done
- Confirmed Azure app sign in audience allows personal accounts
- Confirmed Azure redirect URIs include the Nylas Hosted Auth callback
- Confirmed Nylas connector tenant is common and credentials match the Azure app
- Confirmed provider string passed to Nylas is microsoft
- Google calendar OAuth works end to end with the same callback handler
- Reproduced that forcing /consumers reaches consent, so the Azure app and scopes are valid
Can you please help understand what I am doing wrong? Thanks a lot
