Intinya
API Calendly memungkinkan otomatisasi alur kerja penjadwalan. Anda melakukan autentikasi dengan OAuth 2.0, mengakses tipe acara dan pemesanan melalui api.calendly.com, serta menerima pembaruan real-time lewat webhook. Untuk pengujian, gunakan Apidog untuk memvalidasi payload webhook dan menguji integrasi tanpa membuat pemesanan nyata.
Pendahuluan
Calendly memproses jutaan pertemuan tiap bulannya—digunakan untuk panggilan penjualan, sesi dukungan, konsultasi, dan wawancara. API-nya memungkinkan Anda menyematkan penjadwalan ke aplikasi sendiri.
Pola umum: Anda ingin pemesanan Calendly memicu aksi di sistem Anda. Contoh: pengguna memesan demo, CRM Anda diperbarui; konsultasi dijadwalkan, Anda kirim kuesioner; pertemuan dibatalkan, tim Anda mendapat notifikasi.
API Calendly mendukung ini dengan webhook. Setiap ada event (pemesanan dibuat/dibatalkan/dijadwal ulang), Calendly mengirimkan POST ke endpoint Anda. Proses payload tersebut dan tindak lanjuti otomatis.
💡 Jika membangun integrasi penjadwalan, Apidog memudahkan pengujian handler webhook dan validasi payload—tirukan respons Calendly selama development untuk memastikan integrasi Anda menangani semua event sebelum terkoneksi kalender nyata.
Autentikasi dengan OAuth 2.0
Calendly menggunakan OAuth 2.0. Anda tidak bisa memakai API key.
Buat aplikasi OAuth
- Buka Calendly → Integrasi → API & Webhook
- Klik “Buat Aplikasi Baru”
- Atur URI pengalihan (misal:
https://yourapp.com/auth/calendly/callback) - Catat client ID dan client secret
Alur OAuth
Langkah 1: Arahkan user ke otorisasi
https://auth.calendly.com/oauth/authorize?
client_id=YOUR_CLIENT_ID&
response_type=code&
redirect_uri=https://yourapp.com/auth/calendly/callback
Langkah 2: User otorisasi, diarahkan kembali
https://yourapp.com/auth/calendly/callback?code=AUTHORIZATION_CODE
Langkah 3: Tukar kode ke akses token
const response = await fetch('https://auth.calendly.com/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64')
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authCode,
redirect_uri: 'https://yourapp.com/auth/calendly/callback'
})
})
const { access_token, refresh_token, expires_in } = await response.json()
Langkah 4: Gunakan token
curl -X GET "https://api.calendly.com/users/me" \
-H "Authorization: Bearer ACCESS_TOKEN"
Token penyegaran
Token akses kedaluwarsa setelah 2 jam. Untuk mendapatkan token baru gunakan refresh token:
const response = await fetch('https://auth.calendly.com/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64')
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: storedRefreshToken
})
})
Mendapatkan informasi pengguna
Dapatkan user saat ini
curl -X GET "https://api.calendly.com/users/me" \
-H "Authorization: Bearer ACCESS_TOKEN"
Contoh respons:
{
"resource": {
"avatar_url": "https://calendly.com/avatar.jpg",
"created_at": "2024-01-15T10:00:00Z",
"current_organization": "https://api.calendly.com/organizations/ABC123",
"email": "you@example.com",
"name": "John Doe",
"scheduling_url": "https://calendly.com/johndoe",
"slug": "johndoe",
"timezone": "America/New_York",
"uri": "https://api.calendly.com/users/ABC123"
}
}
Dapatkan keanggotaan organisasi
curl -X GET "https://api.calendly.com/organization_memberships/me" \
-H "Authorization: Bearer ACCESS_TOKEN"
Tipe acara
Tipe acara adalah template meeting yang dibuat user (misal: panggilan 30 menit, konsultasi 60 menit).
Daftar tipe acara
curl -X GET "https://api.calendly.com/event_types?user=https://api.calendly.com/users/ABC123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Contoh respons:
{
"resource": {
"uri": "https://api.calendly.com/event_types/ETC123",
"active": true,
"booking_method": "instant",
"color": "#0066FF",
"created_at": "2024-01-15T10:00:00Z",
"description_html": "<p>30-minute consultation</p>",
"duration": 30,
"internal_note": "Use Zoom link",
"kind": "solo",
"name": "30 Min Consultation",
"pooling_type": null,
"profile": {
"name": "John Doe",
"type": "User",
"owner": "https://api.calendly.com/users/ABC123"
},
"scheduling_url": "https://calendly.com/johndoe/30min",
"slug": "30min",
"type": "StandardEventType"
},
"pagination": {
"count": 1,
"next_page": null
}
}
Dapatkan tipe acara tertentu
curl -X GET "https://api.calendly.com/event_types/ETC123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Acara terjadwal (pemesanan)
Acara adalah booking aktual yang dibuat via Calendly.
Daftar acara terjadwal
curl -X GET "https://api.calendly.com/scheduled_events?user=https://api.calendly.com/users/ABC123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Filter berdasar rentang tanggal:
curl -X GET "https://api.calendly.com/scheduled_events?min_start_time=2026-03-01T00:00:00Z&max_start_time=2026-03-31T23:59:59Z" \
-H "Authorization: Bearer ACCESS_TOKEN"
Contoh respons:
{
"resource": {
"uri": "https://api.calendly.com/scheduled_events/ABC123",
"status": "active",
"tracking": {
"utm_campaign": "spring_sale",
"utm_source": "email",
"utm_medium": "newsletter"
},
"created_at": "2026-03-24T10:00:00Z",
"end_time": "2026-03-25T11:00:00Z",
"event_type": "https://api.calendly.com/event_types/ETC123",
"invitees_counter": {
"active": 1,
"limit": 1,
"total": 1
},
"location": {
"type": "zoom",
"join_url": "https://zoom.us/j/123456789"
},
"start_time": "2026-03-25T10:30:00Z",
"updated_at": "2026-03-24T10:00:00Z"
}
}
Dapatkan detail acara
curl -X GET "https://api.calendly.com/scheduled_events/EVENT_ID" \
-H "Authorization: Bearer ACCESS_TOKEN"
Dapatkan peserta suatu acara
curl -X GET "https://api.calendly.com/scheduled_events/EVENT_ID/invitees" \
-H "Authorization: Bearer ACCESS_TOKEN"
Respons:
{
"resource": [
{
"cancel_url": "https://calendly.com/cancellations/ABC123",
"created_at": "2026-03-24T10:00:00Z",
"email": "jane@example.com",
"event": "https://api.calendly.com/scheduled_events/ABC123",
"name": "Jane Smith",
"new_invitee": null,
"old_invitee": null,
"reschedule_url": "https://calendly.com/reschedulings/ABC123",
"status": "active",
"text_reminder_number": "+15551234567",
"timezone": "America/New_York",
"tracking": {
"utm_campaign": null,
"utm_source": null
},
"updated_at": "2026-03-24T10:00:00Z",
"uri": "https://api.calendly.com/scheduled_event_invitees/INV123",
"canceled": null
}
]
}
Webhook untuk pembaruan real-time
Webhook mengirim notifikasi real-time ke aplikasi Anda tentang event booking.
Buat langganan webhook
curl -X POST "https://api.calendly.com/webhook_subscriptions" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/calendly",
"events": [
"invitee.created",
"invitee.canceled",
"invitee.rescheduled"
],
"organization": "https://api.calendly.com/organizations/ORG123",
"scope": "organization"
}'
Event yang tersedia:
-
invitee.created— booking baru dibuat -
invitee.canceled— booking dibatalkan -
invitee.rescheduled— booking dijadwal ulang
Daftar langganan webhook
curl -X GET "https://api.calendly.com/webhook_subscriptions?organization=https://api.calendly.com/organizations/ORG123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Hapus webhook
curl -X DELETE "https://api.calendly.com/webhook_subscriptions/WEBHOOK_ID" \
-H "Authorization: Bearer ACCESS_TOKEN"
Menangani payload webhook
Verifikasi tanda tangan webhook
Calendly menandatangani webhook melalui header Calendly-Webhook-Signature. Contoh verifikasi (Node.js):
import crypto from 'crypto'
function verifySignature(payload, signature, secret) {
const [t, v1] = signature.split(',')
const timestamp = t.split('=')[1]
const hash = v1.split('=')[1]
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + payload)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(hash),
Buffer.from(expectedSignature)
)
}
app.post('/webhooks/calendly', (req, res) => {
const signature = req.headers['calendly-webhook-signature']
const payload = JSON.stringify(req.body)
if (!verifySignature(payload, signature, process.env.CALENDLY_WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature')
}
// Proses webhook
handleWebhook(req.body)
res.status(200).send('OK')
})
Proses event booking
function handleWebhook(payload) {
const { event, payload: data } = payload
switch (event) {
case 'invitee.created':
console.log(`New booking: ${data.event.start_time}`)
console.log(`Invitee: ${data.email}`)
// Sinkronkan ke CRM, kirim email konfirmasi, dll
syncToCRM(data)
break
case 'invitee.canceled':
console.log(`Booking canceled: ${data.event.uri}`)
// Update CRM, notifikasi tim, dll
removeFromCRM(data)
break
case 'invitee.rescheduled':
console.log(`Booking rescheduled: ${data.event.start_time}`)
// Update kalender, notifikasi tim, dll
updateCRM(data)
break
}
}
Pengujian dengan Apidog
API Calendly memerlukan OAuth, yang bisa mempersulit pengujian. Apidog menyederhanakan proses ini.
1. Mock respons OAuth
Selama dev, tidak perlu alur OAuth penuh. Tirukan respons token:
{
"access_token": "mock_access_token",
"refresh_token": "mock_refresh_token",
"expires_in": 7200,
"created_at": 1700000000
}
2. Uji handler webhook
Buat payload webhook tiruan:
{
"created_at": "2026-03-24T10:00:00Z",
"event": "invitee.created",
"payload": {
"email": "test@example.com",
"name": "Test User",
"event": {
"start_time": "2026-03-25T10:30:00Z",
"end_time": "2026-03-25T11:00:00Z",
"event_type": {
"name": "30 Min Consultation"
}
}
}
}
Kirim ke endpoint webhook Anda dan verifikasi handler berjalan sesuai logika.
3. Variabel lingkungan
Gunakan variabel lingkungan berikut untuk integrasi:
CALENDLY_CLIENT_ID: abc123
CALENDLY_CLIENT_SECRET: xyz789
CALENDLY_ACCESS_TOKEN: stored_token
CALENDLY_REFRESH_TOKEN: stored_refresh
CALENDLY_WEBHOOK_SECRET: webhook_signing_secret
4. Validasi tanda tangan webhook
Contoh skrip Postman/Apidog:
pm.test('Webhook signature is valid', () => {
const signature = pm.request.headers.get('Calendly-Webhook-Signature')
pm.expect(signature).to.exist
const payload = pm.request.body.raw
const secret = pm.environment.get('CALENDLY_WEBHOOK_SECRET')
// Verifikasi signature
const valid = verifySignature(payload, signature, secret)
pm.expect(valid).to.be.true
})
Uji webhook Calendly dengan Apidog — gratis.
Kesalahan umum dan perbaikan
401 Tidak Sah
Penyebab: Token tidak valid/kedaluwarsa.
Solusi:
- Periksa token belum kedaluwarsa (2 jam).
- Gunakan refresh token untuk akses token baru.
- Header Authorization harus
Bearer {token}.
403 Terlarang
Penyebab: Lingkup OAuth kurang.
Solusi: Sertakan scope yang dibutuhkan saat meminta otorisasi. Scope Calendly berdasarkan otorisasi user.
404 Tidak Ditemukan
Penyebab: Resource tidak ada atau user tidak punya akses.
Solusi:
- Cek URI resource.
- Pastikan user yang diautentikasi punya akses.
- Pastikan event type/ID valid.
422 Entitas Tidak Dapat Diproses
Penyebab: Validasi request gagal.
Solusi: Lihat respons untuk detail error:
{
"title": "Validation Error",
"message": "Invalid parameter: url must be a valid HTTPS URL"
}
Alternatif dan perbandingan
| Fitur | Calendly | Acuity | Cal.com | Calendly |
|---|---|---|---|---|
| Paket gratis | Terbatas | Terbatas | Gratis mandiri | ✓ |
| Akses API | ✓ | ✓ | ✓ | ✓ |
| Webhook | ✓ | ✓ | ✓ | ✓ |
| OAuth | ✓ | Kunci API | Kunci API | OAuth |
| Penjadwalan tim | ✓ | ✓ | ✓ | ✓ |
| Sumber terbuka | Tidak | Tidak | Ya | Tidak |
Calendly punya dokumentasi API dan alur OAuth paling rapi. Cal.com adalah alternatif open-source dengan autentikasi API key yang sederhana.
Kasus penggunaan dunia nyata
Integrasi CRM Penjualan:
Perusahaan SaaS B2B menyematkan Calendly di halaman harga. Saat demo dipesan, webhook memicu:
- Buat lead di Salesforce
- Notifikasi Slack ke tim sales
- Tambahkan ke automasi marketing
- Catat aktivitas di platform customer success
Platform konsultasi:
Platform layanan hukum memungkinkan klien booking konsultasi dengan pengacara. Integrasi API:
- Sinkronkan booking ke sistem internal
- Generate link Zoom
- Kirim kuesioner 24 jam sebelum meeting
- Buat berkas kasus setelah meeting
Penjadwalan wawancara:
Platform rekrutmen menggunakan Calendly untuk interview kandidat. Webhook:
- Update ATS dengan detail wawancara
- Notifikasi email ke hiring manager
- Kirim undangan kalender ke peserta
- Lacak absensi untuk follow up
Kesimpulan
Yang telah Anda pelajari:
- Calendly menggunakan OAuth 2.0 untuk autentikasi API
- Akses tipe acara dan acara terjadwal lewat API
- Webhook menyediakan notifikasi pemesanan real time
- Selalu verifikasi tanda tangan webhook demi keamanan
- Uji dengan Apidog sebelum koneksi ke kalender nyata
Langkah selanjutnya:
- Buat aplikasi OAuth di Calendly
- Implementasikan alur OAuth
- Siapkan webhook subscription
- Uji dengan payload tiruan di Apidog
- Deploy ke produksi
Uji webhook Calendly dengan Apidog — gratis.
FAQ
Apakah perlu paket berbayar untuk API Calendly?
Tidak. API tersedia di semua paket, termasuk gratis (fitur terbatas). Webhook tersedia di semua paket.
Perbedaan webhook user dan organisasi?
Webhook user hanya untuk event user itu. Webhook organisasi untuk semua tim. Mayoritas integrasi gunakan scope organisasi.
Bagaimana mendapatkan webhook signing secret?
Saat membuat webhook via API, respons memuat signing_key. Simpan dengan aman, gunakan untuk verifikasi signature.
Bisakah membuat booking via API?
Tidak. Calendly tidak punya endpoint untuk membuat booking. Booking hanya via UI atau widget. API hanya read-only untuk booking.
Cara handle konversi zona waktu?
Semua timestamp API dalam UTC (ISO 8601). Konversi ke waktu lokal di aplikasi Anda. Zona waktu user tersedia di resource user.
Berapa rate limitnya?
Calendly tidak mendokumentasikan rate limit publik. Gunakan permintaan wajar. Jika limit tercapai, terapkan backoff eksponensial.
Bisa dapatkan booking historis?
Ya. Gunakan min_start_time & max_start_time untuk query event historis. Tidak ada batas seberapa jauh ke belakang.
Cara uji OAuth flow secara lokal?
Gunakan tunneling seperti ngrok untuk expose server lokal Anda. Set URI pengalihan ke URL ngrok. Selesaikan alur OAuth di browser lalu cek callback.

Top comments (0)