Comment utiliser les APIs Calendly : Guide du développeur pour l'intégration de la planification

Ashley Innocent

Ashley Innocent

24 March 2026

Comment utiliser les APIs Calendly : Guide du développeur pour l'intégration de la planification

enterprise.banner.title

enterprise.banner.feature1

enterprise.banner.feature2

enterprise.banner.feature3

enterprise.banner.ctaB

En bref

Les API Calendly vous permettent d'automatiser les flux de travail de planification. Vous vous authentifiez avec OAuth 2.0, accédez aux types d'événements et aux réservations via api.calendly.com, et recevez des mises à jour en temps réel via des webhooks. Pour les tests, utilisez Apidog pour valider les charges utiles des webhooks et tester votre intégration sans créer de réservations réelles.

Introduction

Calendly traite des millions de réunions chaque mois. Les gens l'utilisent pour les appels de vente, les sessions de support, les consultations et les entretiens. L'API vous permet d'intégrer cette puissance de planification dans vos propres applications.

Le schéma courant : vous souhaitez que les réservations Calendly déclenchent des actions dans votre système. Un utilisateur réserve une démo, et votre CRM est mis à jour. Une consultation est planifiée, et vous envoyez un questionnaire. Une réunion est annulée, et vous informez votre équipe.

L'API de Calendly gère cela via des webhooks. Lorsque des événements se produisent (réservation créée, annulée, reprogrammée), Calendly effectue une requête POST vers vos points d'extrémité. Vous traitez la charge utile et agissez en conséquence.

💡
Si vous créez des intégrations de planification, Apidog vous aide à tester les gestionnaires de webhooks et à valider les charges utiles. Vous pouvez simuler les réponses de Calendly pendant le développement et vous assurer que votre intégration gère tous les types d'événements avant de vous connecter à de vrais calendriers.
bouton

Authentification avec OAuth 2.0

Calendly utilise OAuth 2.0 pour l'accès à l'API. Vous ne pouvez pas simplement utiliser une clé API.

Créer une application OAuth

  1. Allez dans Calendly → Intégrations → API & Webhooks
  2. Cliquez sur "Créer une nouvelle application"
  3. Définissez votre URI de redirection (par exemple, https://yourapp.com/auth/calendly/callback)
  4. Obtenez votre ID client et votre secret client

Le flux OAuth

Étape 1 : Rediriger l'utilisateur pour l'autorisation

https://auth.calendly.com/oauth/authorize?
  client_id=VOTRE_ID_CLIENT&
  response_type=code&
  redirect_uri=https://yourapp.com/auth/calendly/callback

Étape 2 : L'utilisateur autorise et est redirigé

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

Étape 3 : Échanger le code contre un jeton d'accès

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()

Étape 4 : Utiliser le jeton

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

Jetons d'actualisation

Les jetons d'accès expirent après 2 heures. Utilisez les jetons d'actualisation pour en obtenir de nouveaux :

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
  })
})

Obtention des informations utilisateur

Obtenir l'utilisateur actuel

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

Réponse :

{
  "resource": {
    "avatar_url": "https://calendly.com/avatar.jpg",
    "created_at": "2024-01-15T10:00:00Z",
    "current_organization": "https://api.calendly.com/organizations/ABC123",
    "email": "vous@exemple.com",
    "name": "Jean Dupont",
    "scheduling_url": "https://calendly.com/jeandupont",
    "slug": "jeandupont",
    "timezone": "America/New_York",
    "uri": "https://api.calendly.com/users/ABC123"
  }
}

Obtenir l'adhésion à l'organisation

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

Types d'événements

Les types d'événements sont les modèles de réunion que les utilisateurs créent (appel de 30 min, consultation de 60 min, etc.).

Lister les types d'événements

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

Réponse :

{
  "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>Consultation de 30 minutes</p>",
    "duration": 30,
    "internal_note": "Utiliser le lien Zoom",
    "kind": "solo",
    "name": "Consultation de 30 min",
    "pooling_type": null,
    "profile": {
      "name": "Jean Dupont",
      "type": "User",
      "owner": "https://api.calendly.com/users/ABC123"
    },
    "scheduling_url": "https://calendly.com/jeandupont/30min",
    "slug": "30min",
    "type": "StandardEventType"
  },
  "pagination": {
    "count": 1,
    "next_page": null
  }
}

Obtenir un type d'événement spécifique

curl -X GET "https://api.calendly.com/event_types/ETC123" \
  -H "Authorization: Bearer JETON_D_ACCES"

Événements planifiés (réservations)

Les événements sont les réservations réelles effectuées via Calendly.

Lister les événements planifiés

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

Filtrer par plage de dates :

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 JETON_D_ACCES"

Réponse :

{
  "resource": {
    "uri": "https://api.calendly.com/scheduled_events/ABC123",
    "status": "active",
    "tracking": {
      "utm_campaign": "vente_printemps",
      "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"
  }
}

Obtenir les détails de l'événement

curl -X GET "https://api.calendly.com/scheduled_events/ID_EVENEMENT" \
  -H "Authorization: Bearer JETON_D_ACCES"

Obtenir les invités pour un événement

curl -X GET "https://api.calendly.com/scheduled_events/ID_EVENEMENT/invitees" \
  -H "Authorization: Bearer JETON_D_ACCES"

Réponse :

{
  "resource": [
    {
      "cancel_url": "https://calendly.com/cancellations/ABC123",
      "created_at": "2026-03-24T10:00:00Z",
      "email": "jane@exemple.com",
      "event": "https://api.calendly.com/scheduled_events/ABC123",
      "name": "Jeanne 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
    }
  ]
}

Webhooks pour les mises à jour en temps réel

Les webhooks notifient votre application des événements de réservation en temps réel.

Créer un abonnement webhook

curl -X POST "https://api.calendly.com/webhook_subscriptions" \
  -H "Authorization: Bearer JETON_D_ACCES" \
  -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"
  }'

Événements disponibles :

Lister les abonnements webhook

curl -X GET "https://api.calendly.com/webhook_subscriptions?organization=https://api.calendly.com/organizations/ORG123" \
  -H "Authorization: Bearer JETON_D_ACCES"

Supprimer un webhook

curl -X DELETE "https://api.calendly.com/webhook_subscriptions/ID_WEBHOOK" \
  -H "Authorization: Bearer JETON_D_ACCES"

Gestion des charges utiles de webhook

Vérifier les signatures de webhook

Calendly signe les webhooks avec une signature dans l'en-tête 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('Signature invalide')
  }
  
  // Traiter le webhook
  handleWebhook(req.body)
  res.status(200).send('OK')
})

Traiter les événements de réservation

function handleWebhook(payload) {
  const { event, payload: data } = payload
  
  switch (event) {
    case 'invitee.created':
      console.log(`Nouvelle réservation : ${data.event.start_time}`)
      console.log(`Invité : ${data.email}`)
      // Ajouter au CRM, envoyer un e-mail de confirmation, etc.
      syncToCRM(data)
      break
      
    case 'invitee.canceled':
      console.log(`Réservation annulée : ${data.event.uri}`)
      // Mettre à jour le CRM, notifier l'équipe, etc.
      removeFromCRM(data)
      break
      
    case 'invitee.rescheduled':
      console.log(`Réservation reprogrammée : ${data.event.start_time}`)
      // Mettre à jour le calendrier, notifier l'équipe, etc.
      updateCRM(data)
      break
  }
}

Tester avec Apidog

L'API de Calendly nécessite OAuth, ce qui complique les tests. Apidog simplifie cela.

1. Simuler les réponses OAuth

Pendant le développement, ne passez pas par le flux OAuth complet à chaque fois. Simulez la réponse du jeton :

{
  "access_token": "jeton_d_acces_simule",
  "refresh_token": "jeton_d_actualisation_simule",
  "expires_in": 7200,
  "created_at": 1700000000
}

2. Tester les gestionnaires de webhook

Créez des charges utiles de webhook simulées :

{
  "created_at": "2026-03-24T10:00:00Z",
  "event": "invitee.created",
  "payload": {
    "email": "test@exemple.com",
    "name": "Utilisateur de test",
    "event": {
      "start_time": "2026-03-25T10:30:00Z",
      "end_time": "2026-03-25T11:00:00Z",
      "event_type": {
        "name": "Consultation de 30 min"
      }
    }
  }
}

Envoyez-les à votre point d'extrémité webhook et vérifiez leur traitement.

3. Variables d'environnement

CALENDLY_CLIENT_ID: abc123
CALENDLY_CLIENT_SECRET: xyz789
CALENDLY_ACCESS_TOKEN: jeton_enregistre
CALENDLY_REFRESH_TOKEN: actualisation_enregistree
CALENDLY_WEBHOOK_SECRET: secret_signature_webhook

4. Valider les signatures de webhook

pm.test('La signature du webhook est valide', () => {
  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')
  
  // Vérifier la signature
  const valid = verifySignature(payload, signature, secret)
  pm.expect(valid).to.be.true
})

Testez les webhooks Calendly avec Apidog - gratuit

Erreurs courantes et correctifs

401 Non autorisé

Cause : Jeton invalide ou expiré.

Correctif :

  1. Vérifiez que le jeton n'a pas expiré (expiration de 2 heures)
  2. Utilisez le jeton d'actualisation pour obtenir un nouveau jeton d'accès
  3. Assurez-vous que l'en-tête Authorization est Bearer {token}

403 Interdit

Cause : Portée OAuth insuffisante.

Correctif : Le jeton OAuth a besoin des portées appropriées. Lors de la demande d'autorisation, incluez les portées nécessaires. Les portées de Calendly sont implicites en fonction de ce que l'utilisateur autorise.

404 Introuvable

Cause : La ressource n'existe pas ou l'utilisateur n'y a pas accès.

Correctif :

  1. Vérifiez que l'URI de la ressource est correcte
  2. Assurez-vous que l'utilisateur authentifié a accès à la ressource
  3. Vérifiez que le type d'événement ou l'ID d'événement est valide

422 Entité non traitable

Cause : Erreur de validation dans la requête.

Correctif : Vérifiez la réponse pour les détails :

{
  "title": "Erreur de validation",
  "message": "Paramètre invalide : l'URL doit être une URL HTTPS valide"
}

Alternatives et comparaisons

Fonctionnalité Calendly Acuity Cal.com Calendly
Tier gratuit Limité Limité Auto-hébergé gratuit
Accès API
Webhooks
OAuth Clé API Clé API OAuth
Planification d'équipe
Open source Non Non Oui Non

Calendly possède la documentation API et le flux OAuth les plus raffinés. Cal.com est l'alternative open-source avec une authentification par clé API plus simple.

Cas d'utilisation réels

Intégration CRM de vente. Une entreprise SaaS B2B intègre Calendly sur sa page de tarifs. Lorsqu'une personne réserve une démo, le webhook déclenche :

  1. Création d'un prospect dans Salesforce
  2. Envoi d'une notification Slack à l'équipe de vente
  3. Ajout à la séquence d'automatisation marketing
  4. Enregistrement de l'activité dans la plateforme de succès client

Plateforme de consultation. Une plateforme de services juridiques permet aux clients de réserver des consultations avec des avocats. L'intégration API :

  1. Synchronise les réservations avec le système de planification interne
  2. Génère des liens de réunion Zoom
  3. Envoie un questionnaire d'admission 24 heures avant
  4. Crée un dossier client une fois la réunion terminée

Planification d'entretiens. Une plateforme de recrutement utilise Calendly pour les entretiens avec les candidats. Les webhooks :

  1. Mettent à jour l'ATS avec les détails de l'entretien
  2. Notifient le responsable du recrutement par e-mail
  3. Envoient des invitations de calendrier à tous les participants
  4. Suivent les non-présentations pour le suivi

Conclusion

Voici ce que vous avez appris :

Vos prochaines étapes :

  1. Créez une application OAuth dans Calendly
  2. Implémentez le flux OAuth
  3. Configurez un abonnement webhook
  4. Testez avec des charges utiles simulées dans Apidog
  5. Déployez en production

Testez les webhooks Calendly avec Apidog - gratuit

FAQ

Ai-je besoin d'un forfait Calendly payant pour utiliser l'API ?Non. L'API est disponible sur tous les forfaits, y compris le gratuit. Cependant, les forfaits gratuits ont des fonctionnalités limitées. Les webhooks sont disponibles sur tous les forfaits.

Quelle est la différence entre les webhooks au niveau de l'utilisateur et au niveau de l'organisation ?Les webhooks au niveau de l'utilisateur ne capturent les événements que pour un seul utilisateur. Les webhooks au niveau de l'organisation capturent les événements pour tous les membres de l'équipe. La plupart des intégrations utilisent la portée de l'organisation.

Comment obtenir le secret de signature du webhook ?Lorsque vous créez un webhook via l'API, la réponse inclut une signing_key. Stockez-la en toute sécurité. Elle est utilisée pour vérifier les signatures de webhook.

Puis-je créer des réservations via l'API ?Non. Calendly ne dispose pas de point d'extrémité API pour créer des réservations. Les réservations doivent être effectuées via l'interface utilisateur de Calendly ou des widgets intégrés. L'API est en lecture seule pour les réservations.

Comment gérer les conversions de fuseaux horaires ?Tous les horodatages dans l'API sont en UTC (ISO 8601). Convertissez-les en heure locale dans votre application. Le fuseau horaire de l'utilisateur est disponible dans la ressource utilisateur.

Quelle est la limite de débit ?Calendly ne documente pas publiquement les limites de débit. Utilisez des modèles de requête raisonnables. Si vous atteignez les limites, implémentez un backoff exponentiel.

Puis-je obtenir des réservations historiques ?Oui. Utilisez min_start_time et max_start_time pour interroger les événements historiques. Il n'y a pas de limite sur la durée de la période que vous pouvez interroger.

Comment tester le flux OAuth localement ?Utilisez un service de tunneling comme ngrok pour exposer votre serveur local. Définissez l'URI de redirection sur votre URL ngrok. Complétez le flux OAuth dans un navigateur, puis inspectez le rappel.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API