Setting up the Outlook integration: steps on the Outlook and i-Reserve side
The Outlook integration needs configuration on two sides: an app registration in Azure / Entra ID (the customer tenant) and the integration itself in i-Reserve. Because the Redirect URI contains i-Reserve's integration id, you start in i-Reserve by creating the integration to obtain that URL, then do the Azure registration, and finally complete the i-Reserve integration. This article follows that order.
1. Start in i-Reserve: create the integration
The Redirect URI you will need in Azure contains i-Reserve's integration id (the {int_id} part). That id only exists once the integration has been created, so start here:
- Go to Administration → Integrations and add an Outlook integration.
- Note the Redirect URL that i-Reserve shows (typically
{base_url}/integrations/redirect/{int_id}). You need it in step 2. - Skip the other fields for now — you fill them in step 3, after the Azure registration is done.
2. On the Outlook / Azure side
2.1 App registration
- Azure Portal → App registrations → New registration.
- Register as single tenant (accounts in this organisation only).
- Note the Application (client) ID and the Directory (tenant) ID.
- Certificates & secrets → create a client secret and note the value immediately (it is not readable later). Only secret-based auth is used, no certificate.
- Set the Redirect URI (type Web) to the Redirect URL you noted in step 1 (
{base_url}/integrations/redirect/{int_id}).
2.2 Permissions per mode
Under API permissions → Microsoft Graph add the right permission for the mode you use:
| Mode | Permission | Notes |
|---|---|---|
| Delegated | Delegated → Calendars.ReadWrite | Consent is given by the user who signs in. Scope: openid offline_access Calendars.ReadWrite (offline_access yields the refresh token). |
| Application | Application → Calendars.ReadWrite | Admin consent required (“Grant admin consent”). Without it Graph returns 403 on users/{upn}/…. |
| Optional (recommended) | Application → Place.Read.All | Not required for the sync itself, but recommended: it lets you easily retrieve the room mailbox UPNs instead of looking them up by hand. Requires admin consent. |
One app registration can carry multiple permission types, so the same app can serve both modes. Not required: User.Read, Calendars.ReadWrite.Shared.
2.3 Least privilege (recommended for app-only)
By default an app with application Calendars.ReadWrite can read/write every mailbox in the tenant. Restrict it with an ApplicationAccessPolicy (Exchange Online PowerShell) that pins the app to a security group containing only the room mailboxes:
New-ApplicationAccessPolicy -AppId <client-id> `
-PolicyScopeGroupId zalen-rooms@klant.nl `
-AccessRight RestrictAccess `
-Description "i-Reserve room sync: room mailboxes only"
2.4 Mailboxes / rooms
- Delegated: at least one licensed user with a mailbox to sign in with. That user's default calendar syncs.
- Application: create the rooms via Microsoft 365 admin → Resources → Rooms & equipment. A resource mailbox is normally Unlicensed — that is correct. Note each room's UPN (e.g.
ZaalA@klant.onmicrosoft.com) and add them to the security group from step 2.3.
3. On the i-Reserve side
Open the Outlook integration you created in step 1 (Administration → Integrations). It has an authentication screen and a configuration screen.
3.1 Authentication screen (Azure credentials)
| Field | What to enter |
|---|---|
| Tenant ID | The directory (tenant) ID of the M365 tenant. |
| Client ID | The application (client) ID of the app registration. |
| Client secret | The generated client secret value. |
| Return url | The redirect URI. Use exactly the value i-Reserve shows and register that same URI in the Azure app. |
Then run the two buttons in order:
- Step 1: consent — opens the Microsoft consent screen. Sign in with the dedicated user (delegated) or grant admin consent (application) and approve the requested calendar permission.
- Step 2: connect to Outlook — exchanges the consent for the stored tokens (delegated: access + refresh; application: app-only token). After this the connection is live.
3.2 Configuration screen — general behaviour
| Field | What to enter |
|---|---|
| Field for i-Reserve booking id | The booking field that stores the Outlook event id (the link between booking and calendar event). Default external_id. |
| Template | The template used to build the event subject/body (outbound). |
| Create Teams link | Yes/No — create a Teams online meeting for the event. |
| Field for Teams link | Booking field to store the Teams join URL (if the above is Yes). |
| Use customer data | Yes/No — add the customer as attendee / use customer details on the event. |
| Create calendar entry on status | The booking status(es) on which an event is created in Outlook (outbound, delegated). |
| Delete on status | The booking status(es) on which the Outlook event is deleted. |
| E-mail on problems | E-mail address notified on integration problems. |
3.3 Configuration screen — inbound
| Field | What to enter |
|---|---|
| Authentication mode | Delegated (one user) or Application (per room, app-only). This switches the mapping field below. |
| Room ↔ object (application) | Per row: the room mailbox UPN and the i-Reserve object it maps to. One row per room; use “Add room”. |
| Inbound object (delegated) | The single i-Reserve object that events from the user's calendar are booked on. |
| Inbound status | Status used to create a new inbound booking. |
| Inbound status with customer | Alternative status when the organiser matched a known customer. |
| Lock statuses (update) | Bookings in these statuses are not updated by inbound. |
| Lock statuses (delete) | Bookings in these statuses are not cancelled by inbound. |
| Allow booking update | Yes/No — let inbound changes update existing bookings. |
| Ignore validation errors on update | Yes/No — apply inbound updates even if validation would normally reject them. |
3.4 Activate
Save and set the integration to active. Confirm the connection on the test/diagnostics screen and verify a Graph subscription (webhook) was created (delegated: one; application: one per room).






