Step 1 — Entra app registration
The permissions must be Application, not Delegated. This single distinction cost a full day, because the portal defaults to Delegated and the consent screen shows green ticks either way.
In Microsoft Entra admin centre → Identity → Applications → App registrations → New registration:
-
Supported account types: Accounts in this organisational directory only for a single tenant. Choose Any organisational directory only if one shared app will serve many customers.
-
Redirect URI: platform Web, value https://calendar-adapter.zenspace.io/api/v1/calendar/callback/microsoft. No trailing slash, no http. Microsoft compares it character by character.
-
API permissions → Add a permission → Microsoft Graph. The next screen offers two large boxes. Click Application permissions — it is not the default, and this is the step everyone misses.
| Permission | Type | Why |
|---|---|---|
| Calendars.ReadWrite | Application | Create, update and delete bookings on room calendars |
| Place.Read.All | Application | List the tenant's rooms during discovery |
| User.Read | Delegated | Records who connected, once, at sign-in |
Then press Grant admin consent as a Global Administrator. Accepting the sign-in consent screen does not do this — it grants only the delegated scopes, and the adapter will report that permissions were never approved.
Finally, Certificates & secrets → New client secret. Copy the Value column, not the Secret ID; the two look alike and the Value is hidden permanently once the page reloads. Note the expiry date — when it lapses the adapter stops silently.