Cómo Usar las APIs de Calendly: Guía para Desarrolladores sobre Integración de Programación

Ashley Innocent

Ashley Innocent

24 March 2026

Cómo Usar las APIs de Calendly: Guía para Desarrolladores sobre Integración de Programación

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

TL;DR

Las APIs de Calendly te permiten automatizar los flujos de trabajo de programación. Te autenticas con OAuth 2.0, accedes a tipos de eventos y reservas a través de api.calendly.com, y recibes actualizaciones en tiempo real a través de webhooks. Para las pruebas, usa Apidog para validar las cargas útiles de los webhooks y probar tu integración sin crear reservas reales.

Introducción

Calendly procesa millones de reuniones mensualmente. La gente lo usa para llamadas de ventas, sesiones de soporte, consultas y entrevistas. La API te permite integrar esa capacidad de programación en tus propias aplicaciones.

El patrón común: quieres que las reservas de Calendly activen acciones en tu sistema. Un usuario reserva una demostración y tu CRM se actualiza. Se programa una consulta y envías un cuestionario. Se cancela una reunión y notificas a tu equipo.

La API de Calendly maneja esto a través de webhooks. Cuando ocurren eventos (reserva creada, cancelada, reprogramada), Calendly envía POST a tus endpoints. Tú procesas la carga útil y tomas acción.

💡
Si estás construyendo integraciones de programación, Apidog te ayuda a probar manejadores de webhooks y validar cargas útiles. Puedes simular las respuestas de Calendly durante el desarrollo y asegurarte de que tu integración maneje todos los tipos de eventos antes de conectarte a calendarios reales.
botón

Autenticación con OAuth 2.0

Calendly utiliza OAuth 2.0 para el acceso a la API. No puedes simplemente usar una clave de API.

Crear una aplicación OAuth

  1. Ve a Calendly → Integraciones → API y Webhooks
  2. Haz clic en "Crear Nueva Aplicación"
  3. Establece tu URI de redirección (por ejemplo, https://tuapp.com/auth/calendly/callback)
  4. Obtén tu ID de cliente y secreto de cliente

El flujo de OAuth

Paso 1: Redirigir al usuario para autorizar

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

Paso 2: El usuario autoriza y es redirigido de vuelta

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

Paso 3: Intercambiar el código por un token de acceso

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

Paso 4: Usar el token

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

Tokens de actualización

Los tokens de acceso expiran después de 2 horas. Usa tokens de actualización para obtener nuevos:

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

Obteniendo información del usuario

Obtener usuario actual

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

Respuesta:

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

Obtener membresía de la organización

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

Tipos de eventos

Los tipos de eventos son las plantillas de reunión que los usuarios crean (llamada de 30 minutos, consulta de 60 minutos, etc.).

Listar tipos de eventos

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

Respuesta:

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

Obtener un tipo de evento específico

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

Eventos programados (reservas)

Los eventos son las reservas reales realizadas a través de Calendly.

Listar eventos programados

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

Filtrar por rango de fechas:

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"

Respuesta:

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

Obtener detalles del evento

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

Obtener invitados para un evento

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

Respuesta:

{
  "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
    }
  ]
}

Webhooks para actualizaciones en tiempo real

Los webhooks notifican a tu aplicación sobre eventos de reserva en tiempo real.

Crear una suscripción de webhook

curl -X POST "https://api.calendly.com/webhook_subscriptions" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://tuapp.com/webhooks/calendly",
    "events": [
      "invitee.created",
      "invitee.canceled",
      "invitee.rescheduled"
    ],
    "organization": "https://api.calendly.com/organizations/ORG123",
    "scope": "organization"
  }'

Eventos disponibles:

Listar suscripciones de webhook

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

Eliminar un webhook

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

Manejo de cargas útiles de webhook

Verificar firmas de webhook

Calendly firma los webhooks con una firma en el encabezado 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')
  }
  
  // Procesar webhook
  handleWebhook(req.body)
  res.status(200).send('OK')
})

Procesar eventos de reserva

function handleWebhook(payload) {
  const { event, payload: data } = payload
  
  switch (event) {
    case 'invitee.created':
      console.log(`Nueva reserva: ${data.event.start_time}`)
      console.log(`Invitado: ${data.email}`)
      // Añadir a CRM, enviar correo de confirmación, etc.
      syncToCRM(data)
      break
      
    case 'invitee.canceled':
      console.log(`Reserva cancelada: ${data.event.uri}`)
      // Actualizar CRM, notificar al equipo, etc.
      removeFromCRM(data)
      break
      
    case 'invitee.rescheduled':
      console.log(`Reserva reprogramada: ${data.event.start_time}`)
      // Actualizar calendario, notificar al equipo, etc.
      updateCRM(data)
      break
  }
}

Pruebas con Apidog

La API de Calendly requiere OAuth, lo que complica las pruebas. Apidog simplifica esto.

1. Simular respuestas de OAuth

Durante el desarrollo, no realices el flujo completo de OAuth cada vez. Simula la respuesta del token:

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

2. Probar manejadores de webhooks

Crea cargas útiles de webhook simuladas:

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

Envía a tu endpoint de webhook y verifica el manejo.

3. Variables de entorno

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. Validar firmas de 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
})

Prueba webhooks de Calendly con Apidog - gratis

Errores comunes y soluciones

401 No autorizado

Causa: Token inválido o expirado.

Solución:

  1. Verifica que el token no haya expirado (expira en 2 horas)
  2. Usa el token de actualización para obtener un nuevo token de acceso
  3. Asegúrate de que el encabezado de Autorización sea Bearer {token}

403 Prohibido

Causa: Alcance de OAuth insuficiente.

Solución: El token de OAuth necesita los alcances apropiados. Al solicitar autorización, incluye los alcances necesarios. Los alcances de Calendly son implícitos según lo que el usuario autorice.

404 No encontrado

Causa: El recurso no existe o el usuario carece de acceso.

Solución:

  1. Verifica que el URI del recurso sea correcto
  2. Asegúrate de que el usuario autenticado tenga acceso al recurso
  3. Verifica que el tipo de evento o ID de evento sea válido

422 Entidad no procesable

Causa: Error de validación en la solicitud.

Solución: Revisa la respuesta para obtener detalles:

{
  "title": "Error de validación",
  "message": "Parámetro inválido: la URL debe ser una URL HTTPS válida"
}

Alternativas y comparaciones

Característica Calendly Acuity Cal.com Calendly
Nivel gratuito Limitado Limitado Auto-alojado gratis
Acceso API
Webhooks
OAuth Clave API Clave API OAuth
Programación en equipo
Código abierto No No No

Calendly tiene la documentación de API y el flujo de OAuth más pulidos. Cal.com es la alternativa de código abierto con una autenticación de clave de API más simple.

Casos de uso en el mundo real

Integración con CRM de ventas. Una empresa SaaS B2B integra Calendly en su página de precios. Cuando alguien reserva una demostración, el webhook activa:

  1. Crear un lead en Salesforce
  2. Enviar notificación de Slack al equipo de ventas
  3. Añadir a la secuencia de automatización de marketing
  4. Registrar actividad en la plataforma de éxito del cliente

Plataforma de consulta. Una plataforma de servicios legales permite a los clientes reservar consultas con abogados. La integración de la API:

  1. Sincroniza las reservas con el sistema de programación interno
  2. Genera enlaces de reunión de Zoom
  3. Envía un cuestionario de admisión 24 horas antes
  4. Crea un expediente cuando la reunión finaliza

Programación de entrevistas. Una plataforma de reclutamiento utiliza Calendly para entrevistas con candidatos. Los webhooks:

  1. Actualizan el ATS con los detalles de la entrevista
  2. Notifican al gerente de contratación por correo electrónico
  3. Envían invitaciones de calendario a todos los participantes
  4. Realizan un seguimiento de los ausentes para un seguimiento

Conclusión

Esto es lo que has aprendido:

Tus próximos pasos:

  1. Crea una aplicación OAuth en Calendly
  2. Implementa el flujo de OAuth
  3. Configura una suscripción de webhook
  4. Prueba con cargas útiles simuladas en Apidog
  5. Despliega en producción

Prueba webhooks de Calendly con Apidog - gratis

Preguntas frecuentes

¿Necesito un plan de pago de Calendly para usar la API?No. La API está disponible en todos los planes, incluyendo el gratuito. Sin embargo, los planes gratuitos tienen características limitadas. Los webhooks están disponibles en todos los planes.

¿Cuál es la diferencia entre los webhooks a nivel de usuario y a nivel de organización?Los webhooks a nivel de usuario solo capturan eventos para un usuario. Los webhooks a nivel de organización capturan eventos para todos los miembros del equipo. La mayoría de las integraciones usan el alcance de la organización.

¿Cómo obtengo el secreto de firma del webhook?Cuando creas un webhook a través de la API, la respuesta incluye una signing_key. Almacena esto de forma segura. Se utiliza para verificar las firmas de los webhooks.

¿Puedo crear reservas a través de la API?No. Calendly no tiene un endpoint de API para crear reservas. Las reservas deben realizarse a través de la interfaz de usuario de Calendly o widgets incrustados. La API es de solo lectura para las reservas.

¿Cómo manejo las conversiones de zona horaria?Todas las marcas de tiempo en la API están en UTC (ISO 8601). Convierte a la hora local en tu aplicación. La zona horaria del usuario está disponible en el recurso del usuario.

¿Cuál es el límite de velocidad?Calendly no documenta públicamente los límites de velocidad. Utiliza patrones de solicitud razonables. Si alcanzas los límites, implementa una retirada exponencial.

¿Puedo obtener reservas históricas?Sí. Usa min_start_time y max_start_time para consultar eventos históricos. No hay límite en cuanto a qué tan atrás puedes consultar.

¿Cómo pruebo el flujo de OAuth localmente?Usa un servicio de túnel como ngrok para exponer tu servidor local. Configura la URI de redirección a tu URL de ngrok. Completa el flujo de OAuth en un navegador y luego inspecciona la devolución de llamada.

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs