How to build Cal.com scheduling dashboards in Metabase
Cal.com is the open-source scheduling platform — bookings, event types, availability schedules, teams, and webhooks, available as a hosted product or self-hosted on your own Postgres. Metabase is where you turn that record into shared, trustworthy scheduling dashboards. This guide covers two complementary paths: a lightweight MCP + CLI route that pulls live data with the Cal.com MCP server and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that lands Cal.com data in a database so you can build dashboards anyone can read.
How do you connect Cal.com to Metabase?
Most teams combine both routes: quick answers through MCP and CLI uploads first, then recurring reporting on a warehouse-backed model.
Cal.com is the only scheduling tool here with a third route: it's open source, so if you self-host, the booking data already lives in a Postgres database Metabase can query directly — no connector, no export, no sync lag.
Live answers in, quick analysis out
Pair the Cal.com MCP server with the Metabase CLI. Use MCP for live account and meeting lookups, write a scoped result to CSV, then load it into Metabase as a ready-to-query table and model.
- Quick questions such as "show me bookings by event type and host"
- Loading Cal.com exports into Metabase in seconds
- Spot-checks and one-off investigations without pipeline work
- Great for exploration, not the governed numbers a QBR runs on
- Use read-only credentials or scoped API keys wherever supported
- CSV uploads are snapshots — refresh or move to the pipeline for history
Durable dashboards with history
Land Cal.com data in a database or warehouse — via connector or scheduled API pulls — then point Metabase at it.
- Cal.com dashboards sales and marketing both trust
- Joining meetings with CRM opportunities and marketing sources
- Long-run trends for bookings by event type and host and no-show and cancellation rates
- You own the refresh schedule and the snapshot grain
- Decide once what counts as a held meeting — every rate depends on it
- Records mutate after creation, so plan a trailing re-read
What can you analyze from Cal.com data in Metabase?
These all come from the same core objects — bookings, plus the event types, availability schedules, teams and members your sync exposes:
- Bookings by event type and host
- No-show and cancellation rates
- Availability utilization against offered slots
- Team round-robin distribution fairness
- Booking lead time from creation to meeting
Which Cal.com scheduling dashboards should you build in Metabase?
Booking volume
The shape of demand on the calendar.
- Bookings per week (line)
- Bookings by event type (bar)
- Bookings by host (bar)
- Booked vs. canceled (combo)
Meeting quality
Cancellations and no-shows, counted honestly.
- No-show rate, cancellations excluded (number + trend)
- Cancellation rate by event type (bar)
- Cancellation reasons (table)
- Attendees per booking (bar)
Availability and fairness
Whether round-robin routing is really even.
- Booking distribution across round-robin hosts (bar)
- Offered slots vs. booked slots (combo)
- Utilization by host (bar)
- Hosts with no bookings this week (table)
Lead time
How far ahead people book, by event type.
- Median hours from booking to meeting (line)
- Lead time by event type (bar)
- Share of same-day bookings (number + trend)
- Bookings by attendee timezone (table)
How do you use the Cal.com MCP server with the Metabase CLI?
Pair the Cal.com MCP server with the Metabase CLI for fast, hands-on analysis. MCP is useful for scoped lookups and summarized exports; the Metabase CLI's upload command loads CSV data into Metabase
and creates a ready-to-query table and model.
Example workflow
- Ask the MCP server for bookings for the trailing 90 days with event type, host, status, and attendee counts.
- Export the result as CSV, keeping stable IDs, owners, statuses, and dates — and hashing or dropping any personal contact fields.
-
Run
mb upload csvto load it into Metabase as a table and model, then build questions and dashboards on top.
Be honest about the limits
- MCP lookups are excellent for exploration, not scheduled reporting.
-
A CSV upload is a snapshot; refresh it with
mb upload replaceor move to the pipeline for real history. - Bookings change status after creation, so trend views need a trailing re-read; a self-hosted Postgres connection sidesteps this because the current state is always live.
-
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up Cal.com MCP and the Metabase CLI?
Cal.com MCP server official
- Transport
- Vendor-hosted remote MCP, or local via npx over stdio
- Auth
- OAuth 2.1 for the hosted server; `CAL_API_KEY` for the local one
- Best for
- Live scoped meeting lookup and export
Metabase CLI official
- Install
npm install -g @metabase/cli- Auth
mb auth login- Load data
mb upload csv --file data.csv- Requires
- An uploads database (Admin → Settings → Uploads)
{
"mcpServers": {
"cal-com": {
"type": "http",
"url": "https://mcp.cal.com/mcp"
}
}
} Cal.com publishes both a hosted server (OAuth, no key to manage) and a local one — npx @calcom/cal-mcp@latest with a CAL_API_KEY, which is the better fit for scripted exports. The local server exposes a core set of tools by default and unlocks the full API surface behind an --all-tools flag. Cal.com describes the project as in active development and subject to rapid change, so pin a version if you build a workflow on it.
# Install the Metabase CLI
npm install -g @metabase/cli
# Log in (opens your browser; requires Metabase v62+)
mb auth login --url https://your-metabase.example.com
# Load a bookings export — creates a table AND a model
mb upload csv --file cal-com-bookings.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file cal-com-bookings.csv Can you generate a Cal.com dashboard with AI?
Yes. Use the prompt below with any assistant that can run the Cal.com MCP server
and the Metabase CLI. It works end to end: if Cal.com tables already exist
in Metabase it analyzes those; otherwise it pulls scoped, summarized data, loads
it with mb upload csv, then builds the dashboard and caveats
any metric that needs missing history.
Create a polished Metabase dashboard for Cal.com scheduling analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help sales and revenue operations leaders understand bookings by event type and host, no-show and cancellation rates, round-robin fairness, and booking lead time from Cal.com data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for cal-com tables and
models). If durable Cal.com data is already present — a warehouse sync or
an earlier upload — use it and skip to Step 2.
- If nothing is there, pull a scoped, summarized export with the Cal.com MCP server:
bookings, plus event types, availability schedules, teams and members.
Prefer one row per meeting or invitee over raw activity
feeds. Write each result to a CSV, then load it with the Metabase CLI — run
"mb upload csv --file <export>.csv" so each upload creates a table and a
ready-to-query model. Use "mb upload replace <table-id> --file <export>.csv"
to refresh an existing table instead of creating duplicates.
Step 2 — Inspect before querying:
Do not assume exact table or column names. Inspect available fields, owners,
segments, statuses, and date ranges before creating trend cards.
Important:
- Build on whatever data is present; don't claim Metabase connects natively to
Cal.com — it reads a database or CLI-uploaded tables.
- Exclude canceled meetings from no-show denominators: a meeting that was
called off was never an opportunity to show up.
- Use medians, not averages, for speed-to-lead and booking lead time — a few
far-future bookings drag the mean badly.
- Records mutate after creation (cancellations, reschedules, no-show marks), so
say plainly on the dashboard how recently the window was re-read.
- Don't load raw invitee email addresses into the warehouse; hash or drop them.
Dashboard title: Cal.com Scheduling Overview
Sections:
1. Executive summary: Bookings this month; Held bookings;
No-show rate; Cancellation rate; Median booking lead time.
2. Volume: Bookings per week; by event type; by host.
3. Quality: No-show rate with cancellations excluded; cancellation reasons;
attendees per booking.
4. Fairness: Round-robin distribution; offered vs. booked slots; utilization.
5. Lead time: Median hours from booking to meeting; same-day share; timezones.
Filters: Date range, Host or rep, Event type, Status, Lead source.
Output: Build the dashboard if you have permission; otherwise provide the exact
questions, SQL, model definitions, and layout. Include caveats for any metric
that cannot be calculated from the available data. How do you sync Cal.com data into a database or warehouse?
For dashboards that need history and reliability, land Cal.com data in a database first, then connect Metabase to that database.
Connector options
- Managed ETL — use a connector when one covers the objects you need, and read its support level and sync mode before you rely on it.
- Custom pipeline — use the Cal.com API v2 for control over snapshot grain, fields, and refresh cadence.
- MCP + CSV — use this for quick exploration and one-off slices.
Self-hosting is the standout option: point Metabase at a read replica of your Cal.com Postgres database and every booking, event type, and availability record is queryable in place. For Cal.com's hosted product, no managed connector is confirmed — neither Airbyte nor Fivetran publishes a documented Cal.com source — so schedule API v2 pulls for bookings and event types instead, or subscribe to booking webhooks and append events to your warehouse as they happen.
Notes
- Decide the snapshot grain first (one row per meeting, one row per invitee) — it drives storage and every trend card.
- Land raw tables first, then build clean Metabase models on top.
- Normalize meeting-id, host-user, event-type, created-at, start-time, status, and attendee-count fields.
How should you model Cal.com data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
scheduled_meetings | one row per booking | meeting_id, event_type_id, host_user, created_at, start_time, end_time, status, cancellation_reason |
meeting_invitees | one row per attendee per booking | attendee_id, meeting_id, email_hash, timezone, no_show_at |
event_types | one row per event type | event_type_id, title, owner_user, team_id, length_minutes, scheduling_type, is_active |
Modeling advice
-
Build a clean
scheduled_meetingsmodel with the same columns across scheduling tools, so a team running two of them doesn't fork the definitions. - Keep status, cancellation time, reschedule flags, and no-show marks as explicit columns — every rate metric depends on which of them lands in the denominator.
- Re-read a trailing window on each sync rather than only new rows: meeting records keep changing after they are created.
- Hash or drop invitee email addresses before they reach the warehouse, and join meetings to CRM accounts on a stable key rather than on an email domain.
Which Cal.com scheduling metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Meetings booked | Bookings created per period, by host and event type. | Booked and held are different numbers — show both. |
| No-show rate | No-shows over bookings that were not canceled. | Cancellations belong outside the denominator. |
Scheduling data is the top of the funnel, so most of its value shows up in pipeline metrics further down. See Sales analytics for conversion, velocity, and win-rate definitions that use these meetings as their first step.
What SQL powers Cal.com scheduling dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). If you self-host, they run against a read replica too, once you map Cal.com's application tables onto these names.
Booking volume with the share that was later canceled.
SELECT
date_trunc('week', created_at) AS booked_week,
host_user,
COUNT(*) AS meetings_booked,
COUNT(*) FILTER (WHERE status = 'canceled') AS canceled_later,
ROUND(
100.0 * COUNT(*) FILTER (WHERE status = 'canceled')
/ NULLIF(COUNT(*), 0), 1
) AS cancel_rate_pct
FROM scheduled_meetings
WHERE created_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY 1, 2
ORDER BY booked_week DESC, meetings_booked DESC; Only bookings that actually went ahead are in the denominator.
-- Canceled meetings are excluded from the denominator: a meeting that
-- was called off was never an opportunity for anyone to show up.
SELECT
date_trunc('month', m.start_time) AS month,
COUNT(*) AS invitees_expected,
COUNT(*) FILTER (WHERE i.no_show_at IS NOT NULL) AS no_shows,
ROUND(
100.0 * COUNT(*) FILTER (WHERE i.no_show_at IS NOT NULL)
/ NULLIF(COUNT(*), 0), 1
) AS no_show_rate_pct
FROM meeting_invitees i
JOIN scheduled_meetings m ON m.meeting_id = i.meeting_id
WHERE m.status <> 'canceled'
AND m.start_time < now()
AND m.start_time >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY 1
ORDER BY 1; How far ahead people book, per event type, as a median.
-- Median, not average: a handful of bookings made months ahead
-- would distort the mean for every event type.
SELECT
e.title AS event_type,
e.length_minutes,
COUNT(*) AS bookings,
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (m.start_time - m.created_at)) / 3600
)::numeric, 1
) AS median_lead_time_hours
FROM scheduled_meetings m
JOIN event_types e ON e.event_type_id = m.event_type_id
WHERE m.created_at >= CURRENT_DATE - INTERVAL '90 days'
AND e.is_active
GROUP BY 1, 2
ORDER BY bookings DESC; What are common mistakes when analyzing Cal.com in Metabase?
PERCENTILE_CONT
and report the median.
Related
Related analytics
Related dashboards
Related integrations
FAQ
Does Metabase connect natively to Cal.com?
Should Metabase replace Cal.com?
Can Metabase read Cal.com data directly?
How do I get data out of Cal.com's hosted product?
npx @calcom/cal-mcp@latest with a CAL_API_KEY) is the convenient option: it exposes a core set of tools by default and the full API surface behind --all-tools. Cal.com describes the project as in active development and subject to rapid change, so pin a version.