Skip to content

Calendly#

Calendly is registered for API sync with sync-coupled user import. It pulls scheduled events from the authenticated user's current Calendly organization into a reviewable import session, proposes TeamBoost user mappings from Calendly users and invitees, and projects each scheduled event into the internal integrations task-create draft for operator review.

Capability Method Status
SYNC Pull scheduled events from the Calendly API Built
USER_IMPORT Bring Calendly users and invitees into task-import mapping Built as part of API sync
CSV_IMPORT Upload a Calendly export Not built
WEBHOOK Verify Calendly webhook events Not built

The endpoints below live under /api/v1/providers/calendly/.... They are generic: the same routes serve any registered provider by substituting the {provider} path segment. All routes require an organization-scoped user token (see Authentication).

Discovery#

GET /api/v1/providers/calendly
{
  "status": "success",
  "data": { "provider": "calendly", "capabilities": ["SYNC", "USER_IMPORT"] }
}

Credential Verification#

Calendly personal access tokens can be stored and verified for API sync:

PUT /api/v1/providers/calendly/credentials?organization_id=<id>
POST /api/v1/providers/calendly/credentials/verify?organization_id=<id>

The stored secret is the Calendly token string:

{ "secret": "<calendly-personal-access-token>" }

Verification sends the secret as a Calendly bearer token, fetches GET /users/me, reads the current organization URI from the user resource, and then probes GET /scheduled_events for that organization. A rejected token, a token that does not expose a current organization, or missing API access for the sync probe returns invalid_api_key. Stored secrets are encrypted at rest and never returned by the credential endpoints.

Importing From The Calendly API#

POST /api/v1/providers/calendly/imports/sync?organization_id=<id>

Uses the stored encrypted Calendly token to fetch a bounded organization-scoped scheduled-event window. The current generic sync endpoint has no provider-specific request body, so the Calendly organization comes from the token's current_organization value.

The first shipped sync window is intentionally bounded:

  • 7 days in the past through 90 days in the future;
  • organization-scoped scheduled events;
  • active and canceled events when Calendly returns them;
  • invitees fetched per scheduled event for mapping and review context.

The adapter calls:

  • GET https://api.calendly.com/users/me
  • GET https://api.calendly.com/organization_memberships?organization=...
  • GET https://api.calendly.com/scheduled_events?organization=...&min_start_time=...&max_start_time=...
  • GET https://api.calendly.com/scheduled_events/{event_uuid}/invitees

Calendly collection pagination is followed. Rate limits (429) and transient server failures are retried with bounded backoff. Invalid or revoked tokens and missing-scope responses return credential errors.

User Mapping#

Calendly USER_IMPORT rides the sync flow. The adapter proposes mappings from:

  • the authenticated Calendly user;
  • users returned by GET /organization_memberships;
  • scheduled-event hosts;
  • scheduled-event invitees.

The primary matching key is the Calendly resource URI (sourceAccountId). Email is secondary when present, then name. Invitees are imported for matching and preserved as review context, but they are not automatically assigned as owners or requesters.

Projection Field Coverage#

Calendly source TeamBoost draft field Notes
Scheduled-event name title Error if shorter than 2 characters
Scheduled event type Meetings default to OTHER with a mapping note
Event description description Passed through when present
Event status status active maps to NOT_STARTED; canceled maps to CANCELED; unknown labels are left unset with a note
No native task priority priority Defaults to UNKNOWN with a mapping note
First event membership creatorId Resolved through the user mapping when possible
Invitees ownerId Invitees are imported for user mapping but are not assigned as owners automatically
Invitees requestedById Preserved in descriptionJson; requester mapping is left unset until the product rule is confirmed
Event start/end plannedStartDate, estimatedStartDate, plannedEndDate Meeting length is not converted into TeamBoost effort duration
Calendly projectTitle Defaults to Calendly
Event refs, invitees, location, calendar refs, cancellation, sync context descriptionJson Preserved for review

Not Built Yet#

  • CSV import.
  • OAuth app install flow.
  • Standalone user-directory import before sync.
  • Webhook registration and event verification.
  • Provider-specific sync filters or persisted incremental sync state.
  • Live Calendly PAT validation in this repo's automated tests; use a real Calendly owner/admin PAT and non-production organization for release smoke.