Cara Menggunakan API Calendly: Panduan Developer untuk Integrasi Penjadwalan

Ashley Innocent

Ashley Innocent

24 March 2026

Cara Menggunakan API Calendly: Panduan Developer untuk Integrasi Penjadwalan

Apidog untuk Perusahaan

Penerapan On-Premises

SSO & RBAC

Sesuai SOC 2

Jelajahi Apidog Enterprise

Intinya

API Calendly memungkinkan Anda mengotomatiskan alur kerja penjadwalan. Anda melakukan autentikasi dengan OAuth 2.0, mengakses tipe acara dan pemesanan melalui api.calendly.com, dan menerima pembaruan real-time melalui webhook. Untuk pengujian, gunakan Apidog untuk memvalidasi payload webhook dan menguji integrasi Anda tanpa membuat pemesanan nyata.

Pendahuluan

Calendly memproses jutaan pertemuan setiap bulannya. Orang-orang menggunakannya untuk panggilan penjualan, sesi dukungan, konsultasi, dan wawancara. API memungkinkan Anda menyematkan kekuatan penjadwalan tersebut ke dalam aplikasi Anda sendiri.

Pola umumnya: Anda ingin pemesanan Calendly memicu tindakan di sistem Anda. Seorang pengguna memesan demo, dan CRM Anda diperbarui. Sebuah konsultasi dijadwalkan, dan Anda mengirimkan kuesioner. Sebuah pertemuan dibatalkan, dan Anda memberi tahu tim Anda.

API Calendly menangani ini melalui webhook. Ketika acara terjadi (pemesanan dibuat, dibatalkan, dijadwal ulang), Calendly mengirimkan POST ke endpoint Anda. Anda memproses payload dan mengambil tindakan.

💡
Jika Anda membangun integrasi penjadwalan, Apidog membantu Anda menguji penangan webhook dan memvalidasi payload. Anda dapat menirukan respons Calendly selama pengembangan dan memastikan integrasi Anda menangani semua tipe acara sebelum terhubung ke kalender nyata.
button

Autentikasi dengan OAuth 2.0

Calendly menggunakan OAuth 2.0 untuk akses API. Anda tidak bisa hanya menggunakan kunci API.

Buat aplikasi OAuth

  1. Buka Calendly → Integrasi → API & Webhook
  2. Klik “Buat Aplikasi Baru”
  3. Atur URI pengalihan Anda (misalnya, https://yourapp.com/auth/calendly/callback)
  4. Dapatkan ID klien dan rahasia klien Anda

Alur OAuth

Langkah 1: Arahkan pengguna untuk 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: Pengguna mengotorisasi dan diarahkan kembali

https://yourapp.com/auth/calendly/callback?code=AUTHORIZATION_CODE

Langkah 3: Tukar kode untuk token akses

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. Gunakan token penyegaran untuk mendapatkan yang baru:

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 pengguna saat ini

curl -X GET "https://api.calendly.com/users/me" \
  -H "Authorization: Bearer ACCESS_TOKEN"

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 templat pertemuan yang dibuat pengguna (panggilan 30 menit, konsultasi 60 menit, dll.).

Daftar tipe acara

curl -X GET "https://api.calendly.com/event_types?user=https://api.calendly.com/users/ABC123" \
  -H "Authorization: Bearer ACCESS_TOKEN"

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 pemesanan aktual yang dibuat melalui 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 berdasarkan 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"

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 untuk 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 memberi tahu aplikasi Anda tentang acara pemesanan secara real time.

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"
  }'

Acara yang tersedia:

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 dengan tanda tangan di header Calendly-Webhook-Signature:

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')
  }
  
  // Process webhook
  handleWebhook(req.body)
  res.status(200).send('OK')
})

Proses acara pemesanan

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}`)
      // Add to CRM, send confirmation email, etc.
      syncToCRM(data)
      break
      
    case 'invitee.canceled':
      console.log(`Booking canceled: ${data.event.uri}`)
      // Update CRM, notify team, etc.
      removeFromCRM(data)
      break
      
    case 'invitee.rescheduled':
      console.log(`Booking rescheduled: ${data.event.start_time}`)
      // Update calendar, notify team, etc.
      updateCRM(data)
      break
  }
}

Pengujian dengan Apidog

API Calendly memerlukan OAuth, yang mempersulit pengujian. Apidog menyederhanakan hal ini.

1. Mock respons OAuth

Selama pengembangan, jangan melalui alur OAuth penuh setiap saat. Tirukan respons token:

{
  "access_token": "mock_access_token",
  "refresh_token": "mock_refresh_token",
  "expires_in": 7200,
  "created_at": 1700000000
}

2. Uji penangan 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 penanganannya.

3. Variabel lingkungan

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

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')
  
  // Verify 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 atau kedaluwarsa.

Perbaikan:

  1. Periksa token belum kedaluwarsa (kedaluwarsa 2 jam)
  2. Gunakan token penyegaran untuk mendapatkan token akses baru
  3. Pastikan header Otorisasi adalah Bearer {token}

403 Terlarang

Penyebab: Lingkup OAuth tidak cukup.

Perbaikan: Token OAuth memerlukan lingkup yang sesuai. Saat meminta otorisasi, sertakan lingkup yang dibutuhkan. Lingkup Calendly bersifat implisit berdasarkan apa yang diotorisasi pengguna.

404 Tidak Ditemukan

Penyebab: Sumber daya tidak ada atau pengguna tidak memiliki akses.

Perbaikan:

  1. Verifikasi URI sumber daya sudah benar
  2. Pastikan pengguna yang diautentikasi memiliki akses ke sumber daya tersebut
  3. Periksa apakah tipe acara atau ID acara valid

422 Entitas Tidak Dapat Diproses

Penyebab: Kesalahan validasi dalam permintaan.

Perbaikan: Periksa respons untuk detailnya:

{
  "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 memiliki dokumentasi API dan alur OAuth yang paling rapi. Cal.com adalah alternatif sumber terbuka dengan autentikasi kunci API yang lebih sederhana.

Kasus penggunaan dunia nyata

Integrasi CRM Penjualan. Sebuah perusahaan B2B SaaS menyematkan Calendly di halaman harga mereka. Ketika seseorang memesan demo, webhook memicu:

  1. Membuat prospek di Salesforce
  2. Mengirim notifikasi Slack ke tim penjualan
  3. Menambahkan ke urutan otomatisasi pemasaran
  4. Mencatat aktivitas di platform sukses pelanggan

Platform konsultasi. Platform layanan hukum memungkinkan klien memesan konsultasi dengan pengacara. Integrasi API:

  1. Menyinkronkan pemesanan ke sistem penjadwalan internal
  2. Menghasilkan tautan pertemuan Zoom
  3. Mengirim kuesioner awal 24 jam sebelumnya
  4. Membuat berkas kasus saat pertemuan selesai

Penjadwalan wawancara. Platform rekrutmen menggunakan Calendly untuk wawancara kandidat. Webhook:

  1. Memperbarui ATS dengan detail wawancara
  2. Memberi tahu manajer perekrutan melalui email
  3. Mengirim undangan kalender ke semua peserta
  4. Melacak ketidakhadiran untuk tindak lanjut

Kesimpulan

Inilah yang telah Anda pelajari:

Langkah Anda selanjutnya:

  1. Buat aplikasi OAuth di Calendly
  2. Implementasikan alur OAuth
  3. Siapkan langganan webhook
  4. Uji dengan payload tiruan di Apidog
  5. Deploy ke produksi

Uji webhook Calendly dengan Apidog - gratis

FAQ

Apakah saya memerlukan paket Calendly berbayar untuk menggunakan API?Tidak. API tersedia di semua paket termasuk yang gratis. Namun, paket gratis memiliki fitur terbatas. Webhook tersedia di semua paket.

Apa perbedaan antara webhook tingkat pengguna dan tingkat organisasi?Webhook tingkat pengguna hanya menangkap acara untuk satu pengguna. Webhook tingkat organisasi menangkap acara untuk semua anggota tim. Sebagian besar integrasi menggunakan lingkup organisasi.

Bagaimana cara mendapatkan rahasia penandatanganan webhook?Saat Anda membuat webhook melalui API, responsnya menyertakan signing_key. Simpan ini dengan aman. Ini digunakan untuk memverifikasi tanda tangan webhook.

Dapatkah saya membuat pemesanan melalui API?Tidak. Calendly tidak memiliki endpoint API untuk membuat pemesanan. Pemesanan harus terjadi melalui UI Calendly atau widget tersemat. API bersifat baca-saja untuk pemesanan.

Bagaimana cara menangani konversi zona waktu?Semua stempel waktu di API adalah UTC (ISO 8601). Konversikan ke waktu lokal di aplikasi Anda. Zona waktu pengguna tersedia di sumber daya pengguna.

Berapa batas laju (rate limit)?Calendly tidak mendokumentasikan batas laju secara publik. Gunakan pola permintaan yang wajar. Jika Anda mencapai batas, terapkan backoff eksponensial.

Bisakah saya mendapatkan pemesanan historis?Ya. Gunakan min_start_time dan max_start_time untuk menanyakan acara historis. Tidak ada batasan seberapa jauh ke belakang Anda dapat menanyakan.

Bagaimana cara menguji alur OAuth secara lokal?Gunakan layanan tunneling seperti ngrok untuk mengekspos server lokal Anda. Atur URI pengalihan ke URL ngrok Anda. Selesaikan alur OAuth di browser, lalu periksa callbacknya.

Mengembangkan API dengan Apidog

Apidog adalah alat pengembangan API yang membantu Anda mengembangkan API dengan lebih mudah dan efisien.