Configuring Microsoft 365 (Graph API)

This guide explains how to configure authentication for the Nextcloud Exchange Connector using the Microsoft Graph API.

Note:

Microsoft is ending support for Exchange Web Services (EWS) in October 2026. To ensure uninterrupted synchronization, Microsoft 365 (Cloud) environments must migrate to the Graph API using modern OAuth 2.0 app-only authentication via Microsoft Entra ID.

Pre-requirements

Before you begin the app registration process, ensure you have the following:

  1. Administrative Access: You must have Global Administrator privileges in your Microsoft Entra ID tenant to grant organizational consent for the required API permissions.

  2. Active Microsoft 365 Tenant: An active Microsoft 365 subscription.

Step 1. Register the Application in Microsoft Entra

Why this is needed: Registering the application generates a unique Application (client) ID and Directory (tenant) ID. These identifiers serve as the routing credentials for your connector to communicate securely with the Microsoft 365 cloud.

  1. Open a browser and log in to the Microsoft Azure Portal.

  2. Navigate to Microsoft Entra ID.

image.png
  1. Navigate to App registrations (located in the left sidebar under Manage).

image.png
  1. Click New registration at the top of the page.

image.png
  1. Fill out the registration form with the following parameters:

    • Name: Enter a friendly name (e.g., Sendent Sync Service - Graph API).

    • Supported account types: Select Accounts in this organizational directory only (Single tenant).

    • Redirect URI: Leave this field empty.

  2. Click Register.

image.png
  1. Once the app is created, you will be redirected to the Overview page. Copy and save the following identifiers; you will need them later:

  • Application (client) ID (This will be your AppId)

  • Directory (tenant) ID (This will be your TenantId)

Pro Tip: EWS to Graph API Migration

If you are migrating an existing setup from EWS to Graph API, your TenantId will remain exactly the same, as both applications reside in the same organizational tenant. You will only need to update your configuration with the new AppId and ClientSecret generated during this process.

In the .env file this means changing EventSyncClients__0__Provider from Ews to Graph, removing EventSyncClients__0__Settings__ExchangeType, and replacing AppId / ClientSecret with the new values. TenantId stays the same.

Step 2. Configure Permissions for App-only Access

Why this is needed: The connector operates as a background daemon without a signed-in user present. It requires "Application permissions" to interact with the Graph API and sync calendars and contacts across the organization.

  1. In your app registration menu, navigate to Manage > API permissions.

  2. Click Add a permission.

Untitled.png
  1. Select Microsoft Graph.

image.png
  1. Select Application permissions.

image.png
  1. Search for and check the following permissions:

    • Calendars.ReadWrite

    • Contacts.ReadWrite

    • User.Read.All

  2. Optional permissions for additional features:

    Feature

    Permission

    API

    Room Sync

    Place.Read.All

    Microsoft Graph

    Room Sync, mailbox provisioning

    Exchange.ManageAsApp

    Office 365 Exchange Online

    User Presence Sync

    Presence.ReadWrite.All

    Microsoft Graph

    Exchange.ManageAsApp is found under APIs my organization uses > Office 365 Exchange Online, not under Microsoft Graph. Room provisioning additionally requires the app's service principal to hold the Exchange Administrator role in Microsoft Entra ID. Graph webhooks (push notifications) need no extra permission beyond Calendars.ReadWrite.

  3. Click Add permissions.

image.png

Warning: Grant Admin Consent

Adding the permissions is not enough. A tenant administrator must click the Grant admin consent for [Your Organization] button on the API permissions page. If this step is skipped, the permissions will remain inactive, and Graph API will deny all synchronization requests.

Optional Security Step

By default, the application receives access to all mailboxes in your tenant. To restrict the connector’s access to a specific group of users, refer to our Restricting App Access using RBAC for Applications guide.

Step 3. Create a Client Secret

Why this is needed: The Client Secret acts as the password for your newly registered application, proving its identity to Microsoft Entra ID when requesting an access token.

  1. Navigate to Manage > Certificates & secrets.

  2. Under the Client secrets tab, click New client secret.

  3. Add a description and choose an expiration period, then click Add.

image.png
  1. Immediately copy the Value of the client secret. You will not be able to view it again once you leave the page.

image.png

Pro Tip: Managing Scalability and Throttling

If your application experiences 429 (Too Many Requests) or throttling errors during heavy synchronization, lower Service__ConcurrencyConfiguration__MaxUsersPerAdmin in .env, or register additional app registrations and add them to admins.json with "Provider": "Graph" so the load is spread across several identities. See Managing Service Accounts (admins.json).

Step 4. Save Credentials for Installation

You have successfully generated the required Graph API access keys. Put them on a Graph sync client in your .env file.

Configuration mapping cheat sheet

EventSyncClients__0__Identifier=graph
EventSyncClients__0__Provider=Graph
EventSyncClients__0__Settings__TenantId=your-directory-tenant-id
EventSyncClients__0__Settings__AppId=your-application-client-id
EventSyncClients__0__Settings__ClientSecret=your-client-secret-value
 
EventSyncClients__1__Identifier=dav
EventSyncClients__1__Provider=Dav
EventSyncClients__1__Settings__BaseUrl=https://cloud.example.com/
EventSyncClients__1__Settings__ServiceUsername=sync-admin
EventSyncClients__1__Settings__ServicePassword=your-password
EventSyncClients__1__Settings__SharedSecret=your-shared-secret
 
EventSync__Pairs__0__SourceClientId=graph
EventSync__Pairs__0__TargetClientId=dav
EventSync__CalendarPriorityOrder__0=graph
EventSync__CalendarPriorityOrder__1=dav

Do not set ExchangeType, OnPremUrl, or OnPremDomain on a Graph client.

If you already have an EWS client, follow the Pro Tip in Step 1 instead of adding a second Exchange-side client.

Next Steps

To prevent the application from accessing unauthorized mailboxes or restrict it to specific data types (for example, allowing calendar sync but explicitly blocking contacts), you can bind the app to a specific Mail-Enabled Security Group using RBAC. Read the Restricting App Access using RBAC for Applications guide.


Was this article helpful?