Calendar integration: M365 Service Account method details
Table of Contents
Note: This document covers details about the Service Account method for the M365 Calendar Integration. Click here to view an overview of all calendar integration methods and here for how to configure the M365 calendar integration in the Paradox CEM account.
The M365 Service Account integration method utilizes a single account (example: olivia@clientname.com) in your Azure tenant to connect with the application. This account is the Service Account. Using the service account, Paradox retrieves user calendar availability, and can optionally create and send interview invitations via that account's email address.
This integration approach is Paradox’s most common method of integration with an O365 or an Exchange Online environment. There are beneficial protections of having the Olivia Scheduling application only scoped to a single account, limiting the exposure of data to only one account (mailbox). A service account also enables all scheduling communications to come from a specified domain.
After a tenant is connected (ie. Paradox is connected at the global level), all the users will be automatically connected based on their email address (all users who exist with the same email domain in the Entra ID Active Directory, in a tenant the service account has access to). The Paradox “connection" to these emails is just that the service account can see them (ie. users have not individually authenticated into their emails in Paradox), meaning that if the user is connection in Paradox then we're actively checking their free/busy calendar data.
- There is no individual action needed, the connected email will auto-populate in pages like Roles and Permissions and My Calendar.
- It is possible to disconnect individual users there/allow them to set up a different individual connection.
- If there are many users currently existing in the Paradox account, their individual calendars auto-connection will be a batched process that happens over time. This is why we recommend, during implementation, to connect the tenant in the Paradox CEM first before adding in all users to the account.
Paradox Azure Application
Paradox’s O365 calendar integration leverages a configured Enterprise Application in Azure. An Azure Global Administrator grants admin consent to connect the application to your tenant. Once consented, the application acts on behalf of your designated azure admin, using that specific user's identity context to execute Microsoft Graph API calls via OAuth 2.0 application permissions.
There are two ways that the Paradox application can be created and managed within your Azure environment: 1) Paradox Default Application, 2) Managed Application.
-
Paradox Default Application
- Through the application consent process, we can connect your tenant to the Paradox Default application. This is a preconfigured application that can be added to your tenant through the OAuth consent of the service account user.
- This typically requires an Azure global admin to consent to adding the application to the environment.
-
Managed Application (registering an application in Azure)
- If you prefer to manage your own application in your environment, that is something that can be accomplished. In order to manage a custom application, Register an Enterprise Application within Azure.
- You will need to provide the following registered application details to Paradox (example):
- App ID: 1a058ccb-060a-432c-****-************
- Tenant ID: 99bbf8d0-600c-4b78-****-************
- Secret Value: yiX4Omm~6~Mu6I********************
- Expiration date for the secret key
Configuration Diagram

Click here to learn how to configure the M365 calendar integration.
Licensing
- The service account requires an active mailbox, as it is essentially a user account being used for the integration.
- If utilizing MS Teams, the account will need a full license that allows the generation of MS Teams meetings.
Security Configuration
- You should have Sharing Policy in Azure set to Availability Only as default, this is recommended.
- This allows the Service Account to only see when a user is free/busy instead of receiving all details on the events in the calendar. If this is not the case, the API calls will respond with calendar details. Paradox never stores this data but it is a callout we make for security purposes that the data has the potential to be transferred to our system.
- Paradox will only make requests against calendars that are existing users in the Paradox CEM.
- Service accounts should have all other tenant calendars shared with it by default.
- In Azure, the only permission that is provided to all users by default is the ability to view the free/busy data in other user calendars (this is AvailabilityOnly role).
- MFA is supported for service accounts. However, Paradox recommends not enabling MFA for the following reasons:
- MFA reset or password policy changes performed after the integration setup will break integration keys without warning, which can lead to inconsistencies with the integration and scheduling actions.
- MFA requires an individual to own the device that is the second authentication method. This creates a Single Point of Failure (SPoF) if that individual leaves the organization, changes their device, or is unavailable at a time of escalation.
- Adding MFA after service account creation can cause a disruption as well that will require reconnection.
Tenant available actions
The connected tenant can be enabled for the following functionality:
- Send Calendar Invites – The service account sends interview invites to candidates and interviewers.
-
Read Calendar Availability – The service account checks free/busy times for scheduling.
- Calendar Timezone Sync – This allows Paradox's timezone to sync with O365 Working Hours timezone each time the calendar is accessed.
-
Microsoft Teams Meetings – Teams is used as the virtual technology, meaning Teams meetings links is created for every scheduled virtual interview.
- Recording and Transcription – Allows auto-recording and transcription for Teams meetings. This media is accessible by the meeting organizer(s).
- Attendees as co-organizers – Allows for interviewers to be set as co-organizers for Teams meetings.
-
Lobby Bypass – Sets who is admitted into the meeting and bypass the meeting lobby.
- Organizer
- Organization
- Organization and Federated
- Everyone
- Invited
- Organization Excluding Guests
Permission Scope
- This method uses delegated permissions.
- Delegated permissions in Azure require each user to individually consent to the permissions of the application, which means the service account will be logged in and be able to confirm the permissions.
- There is often a concern for how much access Paradox has by consenting these permissions → delegated permissions is the guardrail for this.
- Because Paradox uses delegated permissions rather than tenant-wide application permissions, the app only gains access to the account that authenticates.
- The only account that authenticates is the Service Account. Paradox cannot access or view full calendar details for other users across the tenant; its view of standard user schedules is strictly limited to free/busy availability per your Azure default sharing policy. All calendar actions and interview invites are managed centrally and executed solely on behalf of the Service Account.
Only the Service Account will ever be connected to this application and thus, the permissions are limited to a single account.
- The following permissions are utilized for the Paradox Interview Scheduling Application. Which permissions are required correlate to the functionality chosen for the integration. See this Microsoft documentation to learn more about these permissions.
-
Calendars.ReadBasic- Needed if functionality ‘Read Calendar Availability' is enabled
- Used to read the free/busy data of other users within your tenant.
- Because of the “delegated” designation, the read permission only gives permission for the service account and does not give calendar read access to other users' calendars
- Link to Microsoft Documentation
-
Calendars.ReadWrite- Needed if functionality ‘Send Calendar Invites' is enabled
- Used to read the free/busy data of other users within your tenant and for the creation of the interview calendar event with the service account as the owner.
- Because of the “delegated” designation, the read/write permission only gives permission for the service account and does not give calendar read/write access to other users' calendars
- Link to Microsoft Documentation
-
Mail.read- Needed if functionality ‘Send Calendar Invites' is enabled
- Used to read the emails in the service account’s inbox to understand when a calendar event has changed. Based on the invitee’s responses, Paradox will be able to take action on the interview to aid with rescheduling or canceling if necessary.
- The read permission only gives permission for the service account and does not give mailbox read access to other user’s mailboxes
- Link to Microsoft Documentation
-
OnlineMeetings.ReadWrite- Needed for functionality ‘Microsoft Teams Meetings’ is enabled
- Used to create and manage Microsoft Teams URLs for all interviews. The service account will act as the meeting owner when creating the Teams URLs.
- The read/write permission only gives permission for the service account and does not give Teams read/write access to other user’s Teams.
- Link to Microsoft Documentation
-
Offline_access- Needed as default permission
- Used to maintain access to the service account’s data while offline.
-
User.read- Needed as default permission
- Used to read the service account’s profile and gives access to sub claim.
- Link to Microsoft Documentation
-
Example Microsoft Graph API request
- Paradox cannot send an API request on behalf of any other user in your tenant because Paradox does not have API permission for any user outside of the Service Account.
- The following examples are of a request that the Paradox CEM would make on behalf of a service account in your O365 tenant. The request is made by the service account olivia@paradoxolivia.onmicrosoft.com with the interviewer email: test@paradoxolivia.onmicrosoft.com.
- Calendar Availability
- Paradox will then use the get free/busy API call to get the free/busy data of the interviewer(s)
- Documentation: getSchedule
- To get the Free/Busy data of an interviewer, we add the value “test@paradoxolivia.onmicrosoft.com” into the “Schedules” parameter of the API request. Since the service account has the ability to view the free/busy data of “test@paradoxolivia.onmicrosoft.com”, the API request returns a response.
See API request and response
Example request:
POST https://graph.microsoft.com/v1.0/me/calendar/getschedule{ "schedules": ["recruiter@contoso.com"], "startTime": { "dateTime": "2025-01-01T09:00:00", "timeZone": "UTC" }, "endTime": { "dateTime": "2025-01-01T10:00:00", "timeZone": "UTC" } }Example Response:
{ "value": [ { "scheduleId": "recruiter@contoso.com", "scheduleItems": [ { "status": "busy", "start": { "dateTime": "2025-01-01T09:00:00.0000000", "timeZone": "Pacific Standard Time" }, "end": { "dateTime": "2025-01-01T10:00:00.0000000", "timeZone": "Pacific Standard Time" } } ], "workingHours": { "timeZone": { "name": "Pacific Standard Time" } } } ] }
- Calendar Event Creation
- After a candidate selects an available time for their interview, Paradox will make an API request to create calendar invites to send to both the candidate and interviews. Paradox sends separate calendar invites to candidates and interviewers. This allow Paradox to customize content specific for each persona.
- Documentation: Create event
See API request and response
Example request:
POST https://graph.microsoft.com/v1.0/me/events{ "subject": "New Team Meeting", "body": { "contentType": "text", "content": "Quarterly planning session" }, "start": { "dateTime": "2025-01-20T10:00:00", "timeZone": "America/New_York" }, "end": { "dateTime": "2025-01-20T11:00:00", "timeZone": "America/New_York" }, "location": { "displayName": "Room 202", "address": null }, "attendees": [ { "type": "required", "emailAddress": { "address": "alice@example.com", "name": "Alice Smith" } }, { "type": "optional", "emailAddress": { "address": "bob@example.com", "name": "Bob Jones" } } ], "sensitivity": "normal" }Example Response:
Paradox reads from the response:
id(required),iCalUId. Keepsubject,body,start,end,location,attendees,sensitivityif present.
- MS Teams - Meeting Creation
- Documentation: Create onlineMeeting
See API request and response
Example request:
POST https://graph.microsoft.com/v1.0/me/onelineMeetings{ "startDateTime": "2025-11-05T10:00:00Z", "endDateTime": "2025-11-05T11:00:00Z", "subject": "Interview meeting", "joinMeetingIdSettings": { "isPasscodeRequired": true } }Example Response:
{ "joinUrl": "https://teams.microsoft.com/l/meetup-join/...", "joinWebUrl": "https://teams.microsoft.com/l/meetup-join/...", "joinMeetingIdSettings": { "joinMeetingId": "123456789", "passcode": "abc123" }, "audioConferencing": { "tollNumber": "+1 469-998-7681", "conferenceId": "129851622" } }