Kısaca
Calendly API'leri, planlama iş akışlarını otomatikleştirmenizi sağlar. OAuth 2.0 ile kimlik doğrulaması yapar, api.calendly.com üzerinden etkinlik türlerine ve rezervasyonlara erişir ve webhook'lar aracılığıyla gerçek zamanlı güncellemeler alırsınız. Test için, gerçek rezervasyonlar oluşturmadan entegrasyonunuzu ve webhook yüklerini doğrulamak için Apidog'u kullanın.
Giriş
Calendly, her ay milyonlarca toplantıyı işler. İnsanlar bunu satış görüşmeleri, destek oturumları, danışmanlıklar ve mülakatlar için kullanır. API, bu planlama gücünü kendi uygulamalarınıza entegre etmenizi sağlar.
Yaygın senaryo: Calendly rezervasyonlarının sisteminizde eylemleri tetiklemesini istersiniz. Bir kullanıcı bir demo rezervasyonu yapar ve CRM'niz güncellenir. Bir danışmanlık planlanır ve bir anket gönderirsiniz. Bir toplantı iptal edilir ve ekibinize bildirimde bulunursunuz.
Calendly'nin API'si bunu webhook'lar aracılığıyla halleder. Etkinlikler gerçekleştiğinde (rezervasyon oluşturuldu, iptal edildi, yeniden planlandı), Calendly uç noktalarınıza POST isteği gönderir. Yükü işler ve eyleme geçersiniz.
OAuth 2.0 ile Kimlik Doğrulama
Calendly, API erişimi için OAuth 2.0 kullanır. Sadece bir API anahtarı kullanamazsınız.
Bir OAuth uygulaması oluşturun
- Calendly → Entegrasyonlar → API ve Webhook'lar bölümüne gidin
- "Yeni Uygulama Oluştur"a tıklayın
- Yönlendirme URI'nızı ayarlayın (örn.
https://yourapp.com/auth/calendly/callback) - İstemci Kimliğinizi (client ID) ve İstemci Sırrınızı (client secret) alın
OAuth akışı
Adım 1: Kullanıcıyı yetkilendirmeye yönlendirin
https://auth.calendly.com/oauth/authorize?
client_id=YOUR_CLIENT_ID&
response_type=code&
redirect_uri=https://yourapp.com/auth/calendly/callback
Adım 2: Kullanıcı yetkilendirir ve geri yönlendirilir
https://yourapp.com/auth/calendly/callback?code=AUTHORIZATION_CODE
Adım 3: Kodu erişim belirteciyle değiştirin
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()
Adım 4: Belirteci kullanın
curl -X GET "https://api.calendly.com/users/me" \
-H "Authorization: Bearer ACCESS_TOKEN"
Yenileme belirteçleri
Erişim belirteçleri 2 saat sonra sona erer. Yeni belirteçler almak için yenileme belirteçlerini kullanın:
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
})
})
Kullanıcı bilgileri alma
Mevcut kullanıcıyı al
curl -X GET "https://api.calendly.com/users/me" \
-H "Authorization: Bearer ACCESS_TOKEN"
Yanıt:
{
"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"
}
}
Kuruluş üyeliğini al
curl -X GET "https://api.calendly.com/organization_memberships/me" \
-H "Authorization: Bearer ACCESS_TOKEN"
Etkinlik türleri
Etkinlik türleri, kullanıcıların oluşturduğu toplantı şablonlarıdır (30 dakikalık görüşme, 60 dakikalık danışmanlık vb.).
Etkinlik türlerini listele
curl -X GET "https://api.calendly.com/event_types?user=https://api.calendly.com/users/ABC123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Yanıt:
{
"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
}
}
Belirli bir etkinlik türünü al
curl -X GET "https://api.calendly.com/event_types/ETC123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Planlanmış etkinlikler (rezervasyonlar)
Etkinlikler, Calendly üzerinden yapılan gerçek rezervasyonlardır.
Planlanmış etkinlikleri listele
curl -X GET "https://api.calendly.com/scheduled_events?user=https://api.calendly.com/users/ABC123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Tarih aralığına göre filtrele:
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"
Yanıt:
{
"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"
}
}
Etkinlik detaylarını al
curl -X GET "https://api.calendly.com/scheduled_events/EVENT_ID" \
-H "Authorization: Bearer ACCESS_TOKEN"
Bir etkinlik için davetlileri al
curl -X GET "https://api.calendly.com/scheduled_events/EVENT_ID/invitees" \
-H "Authorization: Bearer ACCESS_TOKEN"
Yanıt:
{
"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
}
]
}
Gerçek zamanlı güncellemeler için Webhook'lar
Webhook'lar, uygulamanıza gerçek zamanlı olarak rezervasyon etkinlikleri hakkında bildirim gönderir.
Bir webhook aboneliği oluştur
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"
}'
Mevcut etkinlikler:
invitee.created- Yeni rezervasyon yapıldıinvitee.canceled- Rezervasyon iptal edildiinvitee.rescheduled- Rezervasyon yeniden planlandı
Webhook aboneliklerini listele
curl -X GET "https://api.calendly.com/webhook_subscriptions?organization=https://api.calendly.com/organizations/ORG123" \
-H "Authorization: Bearer ACCESS_TOKEN"
Bir webhook'u sil
curl -X DELETE "https://api.calendly.com/webhook_subscriptions/WEBHOOK_ID" \
-H "Authorization: Bearer ACCESS_TOKEN"
Webhook yüklerini işleme
Webhook imzalarını doğrula
Calendly, Calendly-Webhook-Signature başlığında bir imza ile webhook'ları imzalar:
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')
})
Rezervasyon etkinliklerini işle
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
}
}
Apidog ile test etme
Calendly'nin API'si OAuth gerektirir, bu da test etmeyi karmaşıklaştırır. Apidog bunu basitleştirir.

1. OAuth yanıtlarını taklit etme
Geliştirme sırasında, her seferinde tam OAuth akışından geçmeyin. Belirteç yanıtını taklit edin:
{
"access_token": "mock_access_token",
"refresh_token": "mock_refresh_token",
"expires_in": 7200,
"created_at": 1700000000
}
2. Webhook işleyicilerini test etme
Taklit webhook yükleri oluşturun:
{
"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"
}
}
}
}
Webhook uç noktanıza gönderin ve işlemeyi doğrulayın.
3. Ortam değişkenleri
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. Webhook imzalarını doğrula
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
})
Calendly webhook'larını Apidog ile test edin - ücretsiz
Yaygın hatalar ve düzeltmeler
401 Yetkilendirilmedi
Neden: Geçersiz veya süresi dolmuş belirteç.
Düzeltme:
- Belirtecin süresinin dolmadığını kontrol edin (2 saatlik geçerlilik süresi)
- Yeni bir erişim belirteci almak için yenileme belirtecini kullanın
- Yetkilendirme başlığının
Bearer {token}olduğundan emin olun
403 Yasak
Neden: OAuth kapsamı yetersiz.
Düzeltme: OAuth belirteci uygun kapsamlara ihtiyaç duyar. Yetkilendirme isterken, gerekli kapsamları ekleyin. Calendly'nin kapsamları, kullanıcının yetkilendirdiklerine göre örtülüdür.
404 Bulunamadı
Neden: Kaynak mevcut değil veya kullanıcının erişimi yok.
Düzeltme:
- Kaynak URI'sinin doğru olduğunu doğrulayın
- Kimliği doğrulanmış kullanıcının kaynağa erişimi olduğundan emin olun
- Etkinlik türünün veya etkinlik kimliğinin geçerli olduğunu kontrol edin
422 İşlenemeyen Varlık
Neden: İstekte doğrulama hatası.
Düzeltme: Detaylar için yanıtı kontrol edin:
{
"title": "Validation Error",
"message": "Invalid parameter: url must be a valid HTTPS URL"
}
Alternatifler ve karşılaştırmalar
| Özellik | Calendly | Acuity | Cal.com | Calendly |
|---|---|---|---|---|
| Ücretsiz katman | Sınırlı | Sınırlı | Kendi kendine barındırılan ücretsiz | ✓ |
| API erişimi | ✓ | ✓ | ✓ | ✓ |
| Webhook'lar | ✓ | ✓ | ✓ | ✓ |
| OAuth | ✓ | API anahtarı | API anahtarı | OAuth |
| Ekip planlama | ✓ | ✓ | ✓ | ✓ |
| Açık kaynak | Hayır | Hayır | Evet | Hayır |
Calendly, en iyi düzenlenmiş API belgelerine ve OAuth akışına sahiptir. Cal.com, daha basit API anahtarı kimlik doğrulamasına sahip açık kaynaklı alternatiftir.
Gerçek dünya kullanım senaryoları
Satış CRM entegrasyonu. Bir B2B SaaS şirketi, fiyatlandırma sayfasına Calendly'yi yerleştirir. Birisi bir demo rezervasyonu yaptığında, webhook şunları tetikler:
- Salesforce'ta potansiyel müşteri oluştur
- Satış ekibine Slack bildirimi gönder
- Pazarlama otomasyonu dizisine ekle
- Müşteri başarı platformunda etkinliği kaydet
Danışmanlık platformu. Bir hukuk hizmeti platformu, müvekkillerin avukatlarla danışmanlık randevusu almasını sağlar. API entegrasyonu:
- Rezervasyonları dahili planlama sistemiyle senkronize eder
- Zoom toplantı bağlantıları oluşturur
- 24 saat önce başvuru anketi gönderir
- Toplantı tamamlandığında dava dosyası oluşturur
Mülakat planlaması. Bir işe alım platformu, aday mülakatları için Calendly kullanır. Webhook'lar:
- ATS'yi mülakat detaylarıyla günceller
- İşe alım yöneticisini e-posta ile bilgilendirir
- Tüm katılımcılara takvim davetiyeleri gönderir
- Takip için gelmeyenleri izler
Sonuç
İşte öğrendikleriniz:
- Calendly, API kimlik doğrulaması için OAuth 2.0 kullanır
- API aracılığıyla etkinlik türlerine ve planlanmış etkinliklere erişin
- Webhook'lar gerçek zamanlı rezervasyon bildirimleri sağlar
- Güvenlik için her zaman webhook imzalarını doğrulayın
- Gerçek takvimlere bağlanmadan önce Apidog ile test edin
Sonraki adımlarınız:
- Calendly'de bir OAuth uygulaması oluşturun
- OAuth akışını uygulayın
- Bir webhook aboneliği kurun
- Apidog'da taklit yüklerle test edin
- Üretime dağıtın
Calendly webhook'larını Apidog ile test edin - ücretsiz
Sıkça Sorulan Sorular
API'yi kullanmak için ücretli bir Calendly planına ihtiyacım var mı?Hayır. API, ücretsiz dahil tüm planlarda mevcuttur. Ancak, ücretsiz planların sınırlı özellikleri vardır. Webhook'lar tüm planlarda mevcuttur.
Kullanıcı düzeyinde ve kuruluş düzeyinde webhook'lar arasındaki fark nedir?Kullanıcı düzeyinde webhook'lar yalnızca tek bir kullanıcı için etkinlikleri yakalar. Kuruluş düzeyinde webhook'lar tüm ekip üyeleri için etkinlikleri yakalar. Çoğu entegrasyon kuruluş kapsamını kullanır.
Webhook imzalama sırrını (signing secret) nasıl alırım?API aracılığıyla bir webhook oluşturduğunuzda, yanıt bir signing_key içerir. Bunu güvenli bir şekilde saklayın. Webhook imzalarını doğrulamak için kullanılır.
API aracılığıyla rezervasyon oluşturabilir miyim?Hayır. Calendly'nin rezervasyon oluşturmak için bir API uç noktası yoktur. Rezervasyonlar Calendly'nin kullanıcı arayüzü veya gömülü widget'ları aracılığıyla yapılmalıdır. API, rezervasyonlar için salt okunurdur.
Saat dilimi dönüşümlerini nasıl yaparım?API'deki tüm zaman damgaları UTC'dir (ISO 8601). Uygulamanızda yerel saate dönüştürün. Kullanıcının saat dilimi kullanıcı kaynağında mevcuttur.
Oran sınırı nedir?Calendly, oran sınırlarını herkese açık olarak belgelememektedir. Makul istek kalıpları kullanın. Sınırlara ulaşırsanız, üstel geri çekilme (exponential backoff) uygulayın.
Geçmiş rezervasyonları alabilir miyim?Evet. Geçmiş etkinlikleri sorgulamak için min_start_time ve max_start_time kullanın. Ne kadar geriye dönük sorgulama yapabileceğinize dair bir sınırlama yoktur.
OAuth akışını yerel olarak nasıl test ederim?Yerel sunucunuzu açığa çıkarmak için ngrok gibi bir tünel hizmeti kullanın. Yönlendirme URI'sini ngrok URL'nize ayarlayın. Bir tarayıcıda OAuth akışını tamamlayın, ardından geri çağrıyı inceleyin.
