Cal.com is an open‑source scheduling platform that developers can embed, customize, and self‑host. This tutorial shows you how to install Cal.com, configure API keys, and add a booking widget to a web app. Follow each step to get a production‑ready scheduler in minutes.
Cal.com provides a ready‑made Docker Compose file. Run these commands on a fresh Ubuntu 22.04 server:
sudo apt update && sudo apt install -y docker.io docker-compose
git clone https://github.com/calcom/cal.com.git
cd cal.com
cp .env.example .env
docker compose up -d
After the containers start, open http://your‑server:3000. The first admin account you create will own the installation.
If you prefer not to manage servers, sign up at app.cal.com. Choose the “Pro” plan ($12/month) to unlock API access and custom domains.
Cal.com exposes a REST API at /api/v1. Generate an API key from the dashboard:
Store the token securely (e.g., in an environment variable CALCOM_API_KEY).
# .env
CALCOM_API_KEY=sk_live_1234567890abcdef
curl -H "Authorization: Bearer $CALCOM_API_KEY" \
https://api.cal.com/v1/event-types
The response is a JSON array with fields like slug, duration, and bookable.
Webhooks let your app react when a user books a slot. Set up a POST endpoint that returns 200 OK within 5 seconds.
const express = require('express');
const app = express();
app.use(express.json());
app.post('/calcom/webhook', (req, res) => {
const { eventType, start, end, attendee } = req.body;
console.log(`New booking: ${eventType} ${start} → ${end}`);
// Insert into your database or trigger a workflow
res.sendStatus(200);
});
app.listen(4000, () => console.log('Webhook listening on :4000'));
In the Cal.com dashboard, go to Settings → Webhooks**, add the URL https://your‑domain.com/calcom/webhook, and select the “Booking Created” event.
Cal.com offers three embedding methods: iframe, script tag, and React component.
<iframe src="https://cal.com/yourteam/30min"
style="border:none;width:100%;height:600px;"></iframe>
Place the script before the closing </body> tag.
<script src="https://embed.cal.com/embed.js"></script>
<div id="cal-embed"></div>
<script>
CalEmbed('cal-embed', {
url: 'https://cal.com/yourteam/30min',
theme: 'light',
hideEventTypeDetails: false
});
</script>
Install the package and use it as a normal component.
npm install @calcom/embed-react
import { Cal } from '@calcom/embed-react';
function Scheduler() {
return (
<Cal
calLink="yourteam/30min"
style={{ width: '100%', height: '600px' }}
config={{ layout: 'month_view' }}
/>
);
}
Cal.com lets you change colors, fonts, and language via the branding endpoint.
curl -X PATCH -H "Authorization: Bearer $CALCOM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"primaryColor":"#ff5722"}' \
https://api.cal.com/v1/branding
Upload a translation file (JSON) through the dashboard or API.
{
"booking_confirmation": "Confirmation de réservation",
"select_time": "Sélectionnez une heure"
}
The table below highlights key differences between Cal.com, Calendly, and Doodle for developers.
| Feature | Cal.com | Calendly | Doodle |
|---|---|---|---|
| Self‑hosting | Yes (Docker) | No | No |
| Free open‑source tier | Yes | No (14‑day trial) | Limited |
| API rate limit | Unlimited (self‑host) | 100 req/min | 200 req/min |
| Webhooks | Full set, custom payloads | Booking created only | None |
| Custom branding | Full CSS control | Limited (Pro) | Basic |
| Pricing (per seat) | Free / $12 SaaS | $12 (Pro) | $6 (Premium) |
Yes. Cal.com offers a Docker‑based self‑hosted edition that runs on any Linux server with at least 2 GB RAM.
The open‑source version is free. The hosted SaaS plan starts at $12 per month for the Pro tier.
Cal.com provides deeper API access, custom branding, and self‑hosting, while Calendly focuses on a simpler UI and limited webhook support.
Yes. Use the Cal.com script tag or the @calcom/embed-react npm package to render the widget as a component.
Cal.com supports JWT, OAuth2, and API‑key authentication for its REST endpoints.
By following these steps, you can integrate Cal.com into any web project, automate booking workflows, and keep full control over data and branding. The platform’s open‑source nature makes it a solid choice for developers who need flexibility without a high price tag.