Cal.com is an open-source scheduling platform - like Calendly, but self-hostable and free. Connecting InstantDM to Cal.com lets you send booking links in Instagram DMs and track when leads schedule appointments.
Why Use Cal.com with InstantDM?
- Free and open source - no per-seat pricing
- Self-hostable - full control over your data
- Webhooks included - booking notifications on all plans (unlike Calendly)
- API access - programmatic control over events and bookings
- Custom branding - white-label the booking page
What You'll Need
| Requirement | Details |
|---|---|
| InstantDM account | Trendsetter, Trendsetter Pro, or any Multi plan |
| Cal.com account | Free (cal.com) or self-hosted |
| InstantDM API key | Found at Settings → API in your InstantDM dashboard |
Sending Booking Links in DMs
Get Your Cal.com Link
Your booking link is https://cal.com/yourname/30min (or your custom domain if self-hosted).
Add to InstantDM Flow
Send as a button in your DM flow:
{
"action": "send_message",
"type": "buttons",
"recipient_id": "INSTAGRAM_USER_ID",
"message": "Let's schedule a call! Pick a time:",
"buttons": [
{ "title": "Book a Call", "url": "https://cal.com/yourname/30min" }
]
}
Pre-Fill with Lead Data
https://cal.com/yourname/30min?name=John+Doe&email=john@example.com
Booking Notifications via Webhooks
Cal.com includes webhooks on all plans (including free).
Step 1: Create a Webhook in Cal.com
- Go to Settings → Developer → Webhooks.
- Click New Webhook.
- Set the URL to your server.
- Select trigger: Booking Created.
- Save.
Step 2: Handle the Webhook
const express = require('express');
const app = express();
app.use(express.json());
app.post('/calcom-webhook', async (req, res) => {
const { triggerEvent, payload } = req.body;
if (triggerEvent !== 'BOOKING_CREATED') {
return res.status(200).json({ status: 'skipped' });
}
const attendeeEmail = payload.attendees?.[0]?.email;
const startTime = payload.startTime;
// Look up Instagram user by email
const instagramUserId = await lookupInstagramUser(attendeeEmail);
if (instagramUserId) {
await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.INSTANTDM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'send_message',
type: 'text',
recipient_id: instagramUserId,
message: `✅ Call booked for ${new Date(startTime).toLocaleString()}! See you then.`,
}),
});
}
res.status(200).json({ status: 'processed' });
});
app.listen(3000);
Via Make.com
- Use a Custom Webhook trigger in Make.com to receive Cal.com booking events.
- Add an HTTP Request module to send a confirmation DM via InstantDM API.
Troubleshooting
| Issue | Solution |
|---|---|
| Webhook not firing | Verify the webhook URL is publicly accessible. Check Cal.com webhook settings. |
| Pre-fill not working | Ensure query parameters are URL-encoded. |
| Can't match booking to Instagram lead | Store email-to-Instagram mapping when leads are captured. |
Cal.com vs. Calendly
| Feature | Cal.com | Calendly |
|---|---|---|
| Price | Free (self-hosted) or free tier | Free tier, Pro from $10/mo |
| Webhooks | All plans | Professional+ only |
| Self-hosting | Yes | No |
| API access | All plans | Professional+ |
| Open source | Yes | No |
What's Next
- Set up Calendly if you prefer a managed solution.
- Connect to Google Calendar for direct calendar integration.
- Read the Slack guide for booking notifications in Slack.
- Explore the full API docs at instantdm.com/instagram-api-docs.