External Calendar Sync Guide

Connect Google and Outlook calendars to resources so external events block availability and confirmed appointments create calendar events.

When to Use

  • Keep provider calendars in sync so double-bookings never occur.
  • Let providers own their existing Google or Outlook workflows while the API remains the system of record.
  • Trigger immediate syncs before quoting availability (syncExternal=true).

Concepts

  • Resource-Centric: Calendars attach to Resource records (/v3/resource/:id/...). One resource can connect multiple read calendars plus one write calendar.
  • Pending vs Active: Newly created calendars are pending until the resource follows the authUrl and completes OAuth.
  • Read vs Write: Read calendars block time; the single write calendar receives confirmed appointments.

Endpoint Overview

EndpointPurpose
POST /v3/resource/:id/externalCalendarCreate a connection (returns authUrl).
PUT /v3/resource/:id/externalCalendar/:externalCalendarId/regenerateAuthUrlReissue an OAuth URL when the previous link expired.
GET /v3/resource/:id/externalCalendarsList calendars for the resource (pending + active).
DELETE /v3/resource/:id/externalCalendar/:externalCalendarIdDisconnect and remove cached unavailability.
GET /v3/resource/:id/externalCalendars/listFetch the user’s Google calendars once OAuth succeeds.
POST /v3/resource/:id/externalCalendars/selectChoose read calendars and a single write calendar (readCalendarIds, writeCalendarId).
POST /v3/resource/:id/externalCalendar/createUnavailabilityBulkManually trigger ingestion of external events into OnSched’s Unavailability table for a date range.

All routes require verifyToken + verifyCompany. Only Google supports multi-calendar selection; Outlook connections read/write the primary calendar.

Typical Setup Flow

  1. Create connection: POST /v3/resource/:id/externalCalendar with { "provider": "google" }. Response includes an authUrl.
  2. Authorize: Provider authenticates using the returned URL; OnSched receives refresh tokens and marks the record as active.
  3. Select calendars (Google only):
    • Call POST /v3/resource/:id/externalCalendars/list to show available calendars.
    • Invoke POST /v3/resource/:id/externalCalendars/select with arrays of IDs to read, plus the ID to write to.
  4. Sync events: Availability automatically respects external events. To force an immediate ingest (for same-minute updates), call POST /v3/resource/:id/externalCalendar/createUnavailabilityBulk?startDate=...&endDate=....
  5. Invalidate caches: Any change triggers a cache purge via DeleteAvailabilityCache, ensuring fresh slots the next time you call GET /v3/availability.

Data You Receive

Each calendar record contains:

  • provider: google or outlook.
  • pending: Boolean indicating OAuth completion.
  • read / write: Flags that determine whether events block availability or receive appointment events.
  • calendarId and calendarEmail: Maps back to the provider’s identifiers.
  • refreshToken: Stored securely; never share this outside your backend.

Best Practices

  • Limit External Syncs: syncExternal=true on GET /v3/availability fetches external events just-in-time but adds latency. Use it only when the UI must account for updates that happened seconds ago. Otherwise rely on the background sync cadence triggered by bookings and periodic jobs.
  • Clean Disconnects: Always delete calendars before removing resources to ensure provider tokens are revoked (deleteExternalCalendar handles this).
  • Read vs Write: Selecting more than one write calendar is not allowed. If you change the write target, the old calendar automatically has its write flag cleared.

Troubleshooting

  • No Google calendars listed: The resource must authorize first; only then can /list succeed.
  • Multiple Google accounts connected: Use the optional externalCalendarId path when calling /select so the API knows which account to operate on.
  • External events missing: Confirm the resource chosen read calendars via /select and that the user granted read permissions. Trigger createUnavailabilityBulk for immediate ingestion if needed.

External calendar syncing keeps OnSched availability accurate without revealing internal scheduling rules, while still respecting provider preferences.