InsightHireHelp Center

Calendar & meetings

Microsoft Teams and Google Meet OAuth, admin consent, and live interview scheduling.

Calendar integrations let recruiters schedule live interviews with automatic Microsoft Teams or Google Meet links. Connections are per-user (delegated OAuth), not org-wide service accounts. Calendar cards live on Settings → Integrations under Calendar & meetings.

Feature gates

Two platform feature flags control availability:

Flag slugProvider
meetings_microsoft_teamsMicrosoft 365 / Teams
meetings_google_meetGoogle Calendar / Meet

Platform admins grant these per tenant. The API also requires server-side OAuth app configuration:

ProviderRequired env vars
MicrosoftMICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET, MICROSOFT_REDIRECT_URI
GoogleGOOGLE_CALENDAR_CLIENT_ID, GOOGLE_CALENDAR_CLIENT_SECRET, GOOGLE_CALENDAR_REDIRECT_URI

calendar.capabilities returns enabled, configured, connected, and tenantConsented flags so the UI shows real connect buttons only when both platform grant and server config are present.

Settings path

ActionPath
Connect calendar/dashboard/settings/integrations
Schedule interviewCandidate profile or position Schedule tab
After OAuthRedirect to ?google=connected or ?ms=admin_consent_granted

These slugs are hidden from the ATS integrations grid — they only appear as dedicated calendar cards.


Microsoft Teams

OAuth flow

  1. Recruiter clicks Connect Microsoft on the calendar card.
  2. Client calls calendar.startMicrosoftConnect → receives authorizeUrl + CSRF state.
  3. Browser redirects to Microsoft login.
  4. Microsoft redirects to /api/auth/microsoft/callback with code + state.
  5. API exchanges tokens and stores encrypted row in user_calendar_integrations.
  6. UI polls calendar.listIntegrations or reads ?connected=1 query param.

InsightHire requests only scopes any user can self-consent to:

  • User.Read
  • Calendars.ReadWrite
  • offline_access

Teams meeting links are created inline on the calendar event (event.isOnlineMeeting=true), which works with Calendars.ReadWrite alone. The admin-consent-required OnlineMeetings.ReadWrite scope is not requested.

Some Entra ID tenants require tenant-wide admin approval before users can consent.

Option A — Copy admin consent URL

calendar.getMicrosoftAdminConsentUrl builds a link targeted at the customer's tenant domain (e.g. prismcare.com) so IT skips the tenant picker.

Option B — Email IT admin

calendar.emailMicrosoftAdminConsent sends a templated email with the consent link and Reply-To set to the requesting recruiter.

After admin consent, organizations.microsoftTenantConsentedAt is set and other recruiters in the org skip the "IT admin needs to approve" panel.

Disconnect

calendar.disconnectMicrosoft removes the user's Microsoft integration row.


Google Meet

OAuth flow

Same pattern as Microsoft:

  1. calendar.startGoogleConnect → authorize URL
  2. Redirect to Google consent
  3. Callback at /api/auth/google/callback
  4. Tokens stored in user_calendar_integrations with provider GOOGLE

Scopes

Minimal set for Meet-bearing events on the recruiter's calendar:

  • openid, email
  • https://www.googleapis.com/auth/calendar.events

No Google Workspace admin involvement required for standard Google accounts.

Disconnect

calendar.disconnectGoogle removes the Google integration row.


Scheduling live interviews

Scheduling is implemented in candidate-interviews router. When a recruiter creates an interview:

Location types

TypeBehavior
TEAMSCreate Outlook event via Microsoft Graph with Teams link
GOOGLE_MEETCreate Google Calendar event with Meet conference
INSIGHTHIRE_LIVEProvision Daily.co room (separate insighthire_live_interviews flag)
PHONE, IN_PERSON, OTHERPersist row + reminder emails only

Calendar connected vs fallback

If the organizer has a connected calendar for the chosen provider:

  • Event created on their calendar
  • Candidate receives standard calendar invite (works in Gmail, Apple Mail, Outlook)
  • Reschedule/cancel propagates to attendees

If no calendar connected:

  • Interview row persisted with metadata.inviteDelivery='ICS_EMAIL'
  • .ics email invites sent via interview-ics-emails.service.ts

The schedule modal uses calendar.capabilities to show "auto-create meeting" vs "email invites" hints.

Journey scheduling nodes

Live interviews are scheduled from:

  • Candidate profile — Schedule interview action
  • Position Schedule tab/dashboard/positions/[id]?tab=schedule

Scheduling requires at least one of: Teams enabled, Google Meet enabled, or InsightHire Live enabled (ensureMeetingsEnabled).

Per-location gates apply at create time — choosing Teams when only Google is granted returns a precondition error.

Email delivery

  • Graph/Google path: provider sends calendar invites
  • ICS fallback: InsightHire sends .ics attachments
  • Live interview updates/cancels: live-interview-emails.service.ts
  • From address for live interview mail: hello@insighthire.com

Capability checklist

StepMicrosoftGoogle
Platform admin grants featuremeetings_microsoft_teamsmeetings_google_meet
API env vars set✅ MICROSOFT_*✅ GOOGLE_CALENDAR_*
Recruiter connects account✅ OAuth✅ OAuth
Admin consent (if required)✅ One-time per tenant❌ Usually not needed
Schedule TEAMS/GOOGLE_MEET interview

Troubleshooting

IssueResolution
Connect button disabledAsk platform admin to grant feature + verify API env vars
"Admin needs to approve"Send admin consent URL to IT
Teams link missing on eventOrganizer may lack Teams license; use ICS fallback or InsightHire Live
Google connect failsVerify redirect URI in Google Cloud Console matches API callback
Scheduler not availableEnable at least one of Teams, Google Meet, or InsightHire Live flags

External docs