Migrate from Calendly to Cal.com
Scheduling / booking links · full migration guide
Calendly → Cal.com is a manual rebuild with a forward-cutover. Calendly does not export event-type definitions in a structured way (the CSV export is for past bookings only), and Cal.com does not yet ship a Calendly importer. The good news: event types are usually a small set (5-20 per user) and Cal.com's UI is close enough to Calendly's that recreating one event type takes 2-3 minutes. Calendar connections re-OAuth in seconds. The actual cutover is changing your booking link in email signatures, websites, and CRMs from `calendly.com/yourname/30min` to `cal.your-domain.com/yourname/30min`.
Prerequisites
- Calendly admin / owner access (you need access to event-type definitions and team settings).
- A self-hosted Cal.com instance — see /calendly/ for the 20-minute docker-compose recipe and ~$5-10/mo VPS sizing.
- Google Workspace or Microsoft 365 admin consent for OAuth (so users can re-connect their calendars to Cal.com).
- A domain you control for Cal.com — booking pages live at `cal.your-domain.com/yourname/event-type` rather than `calendly.com/yourname/...`.
- An inventory of every place your Calendly link is published (email signature, website CTAs, CRM, lead-magnet pages) — these all need updating during the cutover.
Step 1 — Export from Calendly
-
Export past bookings (for archival reference)
Calendly → Scheduled Events → Export. Pull a CSV of past bookings for record-keeping. This is purely archival — Cal.com does not import past bookings, and most teams don't need them in the new tool.
-
Document each event type
For each Calendly event type (15-min intro, 30-min sales call, etc.), open the event-type config and screenshot or document: name, slug, duration, calendar(s) checked, custom questions, redirect URL, conditional logic, Zapier/webhook integrations, reminders, and round-robin settings. This is your spec for the Cal.com rebuild.
-
Document team / round-robin pools
If you use Calendly Teams, list each team's members, their availability rules, and the round-robin event types they're part of. Cal.com Teams replicates this concept under Teams → Members → Round Robin.
-
Audit external embeds and integrations
Inventory: every page that embeds the Calendly inline widget, every Zapier zap that fires on a Calendly booking, every Salesforce/HubSpot integration. Each gets re-pointed at Cal.com post-migration.
Step 2 — Import into Cal.com
-
Stand up Cal.com and create user accounts
Run the docker-compose. Visit your Cal.com URL and click Sign Up — the first signup becomes admin. Create accounts for each team member (or invite via email).
-
Connect calendars
Each user: Cal.com → Settings → Apps → Google Calendar / Outlook. The OAuth flow reuses the same consent your team has already given to Calendly. Cal.com will read free/busy from the connected calendar and write new bookings back.
-
Recreate event types one by one
Cal.com → Event Types → New. For each Calendly event type, fill in: title, URL slug (preserve the Calendly slug like `30min` to keep link patterns familiar), duration, location (Google Meet / Zoom / phone — connect the integration first if needed), description, custom questions, redirect URL on confirmation. Save. Repeat per event type.
-
Set up team event types and round-robin
Cal.com → Teams → Create Team. Add members. Then Team → Event Types → New: select Round Robin or Collective. For round-robin, list members and assign weights. The model is similar enough to Calendly's that the rebuild is a click-through, not a rebuild from concepts.
-
Configure workflows (reminders / follow-ups)
Cal.com → Workflows → New Workflow. Trigger: 24h before event, on booking, on cancellation. Action: send email or SMS. Recreate each Calendly Workflow as a Cal.com Workflow — the trigger/action shapes match closely.
-
Update embeds and links
Replace `https://calendly.com/yourname/30min` with `https://cal.your-domain.com/yourname/30min` everywhere it appears. Cal.com supports an inline embed snippet (Cal.com → Embed → Inline) that is a drop-in replacement for Calendly's `<script src='https://assets.calendly.com/...'></script>`.
-
Forward Calendly bookings during overlap window
Calendly does not have a native 'redirect' but you can replace each event type's title and description with 'We've moved! Book at cal.your-domain.com/yourname/30min'. Existing booked events continue on Calendly until they happen; new ones go to Cal.com.
Field / concept mapping
| Calendly | Cal.com | Notes |
|---|---|---|
| Calendly user | Cal.com user | Manual recreation. Username (URL slug) can match. |
| Calendly event type | Cal.com event type | 1:1 conceptually. Manual recreate via UI or via the Cal.com API (`POST /api/v2/event-types`) for bulk. |
| Calendly URL slug (calendly.com/foo/30min) | Cal.com URL slug (cal.your-domain.com/foo/30min) | Preserve the slug to keep muscle memory; only the domain changes. |
| Calendly Google/Outlook connection | Cal.com Apps integration | Re-OAuth per user. Each user clicks 'Connect Google Calendar' once on Cal.com. |
| Calendly custom question | Cal.com booking question | Same shape: text, multi-line, single-select, multi-select, etc. Manually recreated per event type. |
| Calendly Workflow (reminder email) | Cal.com Workflow | Recreate via Workflows → New. Trigger types overlap; SMS via Twilio integration on Cal.com side. |
| Calendly Round Robin Team | Cal.com Team Event Type (Round Robin) | Cal.com Teams replicate Calendly Teams. Member weighting and event-type-per-team shape carries over. |
| Calendly Collective | Cal.com Team Event Type (Collective) | Both have a 'all members' meeting type. |
| Calendly Webhook | Cal.com Webhook | Cal.com sends webhooks on booking events. Update the destination URL in your CRM / Zapier; payloads differ slightly — `event` field replaces Calendly's `triggerEvent`. |
| Calendly Salesforce/HubSpot integration | Cal.com Apps + Zapier/Make | Cal.com has direct apps for HubSpot. For Salesforce, route via Zapier or n8n. Re-create the field mapping on the destination side. |
| Calendly redirect-on-confirm URL | Cal.com booking redirect | Per event type setting. Same UX. |
| Past Calendly bookings | Not migrated | Archive the CSV; Cal.com does not import historical bookings. |
Downtime estimate
Zero downtime if you run a 2-week overlap. Calendly stays live with redirected event-type descriptions; Cal.com handles new bookings. Hard cutover (single-day): plan 4-6 hours to recreate event types for one user, longer for team-heavy setups. Schedule the cutover for a low-traffic day so a missed event-type slot doesn't lose a real meeting.
Common gotchas
- Calendly does not have a structured event-type export. Don't waste time looking — go straight to manual recreation or scripting against the Calendly API (which exists for read but is rate-limited).
- Cal.com's default DB is SQLite — fine for personal use, but for teams switch to Postgres at install time (`DATABASE_URL=postgres://...`) before creating any data.
- Round-robin weights in Cal.com are per-team-event-type, not per-user globally. If a user is on multiple teams, set weights per team.
- Calendly's group event type (multiple attendees per slot) maps to Cal.com's Group event type — same concept, but the display UI is slightly different. Test from a guest's perspective before going live.
- Booking page styling: Calendly auto-pulls profile photos and brand colors. Cal.com requires a manual upload of the avatar and a CSS theme for branding.
Rollback plan
Calendly is unaffected during the migration since the data flow is one-way (manual recreate, not destructive). If Cal.com doesn't fit, point published links back to Calendly and you've lost only the time spent. Keep the Calendly account paid for 30 days post-cutover; the booking page returning a 404 mid-migration is the worst-case for the funnel and is preventable by keeping both live.
Looking for setup time, monthly cost, and other alternatives? See Self-host Calendly.