Si necesitas añadir capacidades de reservas o programación de citas a Webflow, probablemente hayas mirado herramientas como Calendly, SavvyCal o Acuity. Todas funcionan — pero todas comparten la misma limitación fundamental: están construidas para los usuarios finales, no para desarrolladores. Eso cambia completamente con Cal.com.
Por qué Cal.com destaca frente a la competencia

La mayoría de plataformas de reservas tratan a los desarrolladores como un objetivo secundario. Calendly te da un widget incrustable y una API limitada — pero en gran medida estás trabajando alrededor de la plataforma, no con ella. SavvyCal es elegante pero igualmente estricta en su enfoque. El modelo subyacente es siempre el mismo: la plataforma de programación está a cargo y tú solo la estás incrustando.
Cal.com adopta un enfoque completamente diferente. Está diseñada primero para desarrolladores: es de código abierto (open source), tiene una API REST bien documentada (v2), y está construida para ser profundamente extendida.
Tres Formas de Utilizar Cal.com en Webflow
Este artículo cubre tres herramientas complementarias que trabajan juntas: el Embed (para mostrar una UI de reservas), OAuth (para conectar la cuenta de Cal.com de un usuario a tu aplicación), y Webhooks (para sincronizar eventos de reservas con tu backend en tiempo real). Puedes utilizarlos de forma independiente o combinarlos dependiendo de tu caso de uso.
1. Embed — La forma más rápida de mostrar una interfaz de usuario de reservas
La forma más rápida de empezar es utilizando el embed nativo de Cal.com. Añades un script a tu página de Webflow y renderiza un calendario de reservas — ya sea en línea (inline) o como una ventana modal (popup). Tus visitantes interactuarán directamente con el flujo de reservas de Cal.com, que está pulido y optimizado para móviles por defecto.
Añade este script al código personalizado de tu página de Webflow (en Page Settings → Antes de la etiqueta </body>):
(function (C, A, L) {
let p = function (a, ar) {
a.q.push(ar);
};
let d = C.document;
C.Cal =
C.Cal ||
function () {
let cal = C.Cal;
let ar = arguments;
if (!cal.loaded) {
cal.ns = {};
cal.q = cal.q || [];
d.head.appendChild(d.createElement("script")).src = A;
cal.loaded = true;
}
if (ar[0] === L) {
const api = function () {
p(api, arguments);
};
const namespace = ar[1];
api.q = api.q || [];
typeof namespace === "string"
? (cal.ns[namespace] = api) && p(api, ar)
: p(cal, ar);
return;
}
p(cal, ar);
};
})(window, "https://app.cal.com/embed/embed.js", "init");
Cal("init", { origin: "https://app.cal.com" });
Cal("ui", {
styles: { branding: { brandColor: "#000000" } },
hideEventTypeDetails: false,
});A continuación, añade un botón desencadenante en tu lienzo de Webflow con estos atributos personalizados:
<button
data-cal-link="tu-nombre-de-usuario/tu-evento"
data-cal-config='{"layout":"month_view"}'
>
Reserva una llamada
</button>Este enfoque es ideal para casos de uso sencillos en los que tú eres el anfitrión — un freelance, un consultor o una empresa que ofrece un único tipo de cita. Los clientes reservan directamente en tu calendario de Cal.com. Puedes personalizar el color de la marca y el diseño, pero la experiencia principal de reserva es la de Cal.com.
2. OAuth — Conecta la cuenta de Cal.com de un usuario a tu aplicación
Si tu plataforma tiene múltiples proveedores (coaches, médicos, consultores…), querrás que cada uno de ellos conecte su propia cuenta de Cal.com para que puedan gestionar su propia disponibilidad, tipos de eventos y sincronización de calendario. OAuth hace esto posible.
Los usuarios hacen clic en "Connect Cal.com" en tu aplicación de Webflow y pasan por un flujo de autorización estándar:
https://app.cal.com/oauth/authorize
?client_id=YOUR_CLIENT_ID
&redirect_uri=https://tu-app.com/cal-callback
&response_type=code
&scope=READ_BOOKING,READ_PROFILEDespués de que el usuario apruebe, Cal.com redirige de vuelta a tu aplicación con un código de autorización. Lo intercambias por tokens en tu backend:
POST https://app.cal.com/api/auth/oauth/token
{
"code": "AUTHORIZATION_CODE",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://tu-app.com/cal-callback",
"grant_type": "authorization_code"
}Almacena el access_token y el refresh_token junto al registro del usuario. Ahora puedes hacer llamadas a la API de Cal.com en nombre de ese usuario — obteniendo sus tipos de eventos, leyendo reservas o mostrando su disponibilidad en tu UI.
Como cada usuario gestiona su calendario directamente en Cal.com, obtienen acceso a todas las herramientas integradas de Cal.com: reglas de disponibilidad, sincronización con Google Calendar (para evitar dobles reservas), formularios personalizados de admisión y pagos con Stripe. Tu aplicación simplemente coordina el flujo — los usuarios son totalmente conscientes de que tienen una cuenta en Cal.com.
3. Webhooks — Sincroniza Eventos de Reservas en tu Backend en Tiempo Real
En lugar de hacer polling (consultar repetidamente) la API de Cal.com, puedes registrar webhooks para recibir notificaciones en tiempo real cuando ocurra algo en el calendario. Cal.com envía una solicitud POST a tu endpoint (punto de destino) para cada evento.
Cal.com soporta un extenso conjunto de eventos webhook:
| Evento | Cuándo se activa |
|---|---|
BOOKING_CREATED | Se confirma una nueva reserva |
BOOKING_REQUESTED | Solicitud de reserva pendiente |
BOOKING_CANCELLED | Se cancela una reserva |
BOOKING_RESCHEDULED | La reserva se mueve a otra hora |
BOOKING_REJECTED | Petición de reserva declinada |
BOOKING_PAID | Al completar el pago de reserva |
BOOKING_PAYMENT_INITIATED | El proceso de pago comienza |
BOOKING_NO_SHOW_UPDATED | Se actualiza si el invitado no asiste |
MEETING_STARTED | Comienza una reunión en vídeo |
MEETING_ENDED | Termina una reunión en vídeo |
RECORDING_READY | Ya hay grabación de la reunión |
RECORDING_TRANSCRIPTION_GENERATED | La transcripción está lista |
INSTANT_MEETING | Se inicia una reunión instantánea |
FORM_SUBMITTED | Un formulario de reserva enviado |
FORM_SUBMITTED_NO_EVENT | Formulario independiente enviado |
OOO_CREATED | Periodo ausente de la oficina creado |
AFTER_HOSTS_CAL_VIDEO_NO_SHOW | El anfitrión no se unió a la llamada |
AFTER_GUESTS_CAL_VIDEO_NO_SHOW | El invitado no se unió a la llamada |
Escucha estos eventos en tu backend para persistir datos, desencadenar automatizaciones, enviar correos electrónicos o actualizar tu CRM:
// Ejemplo de escuchador webhook (Node.js / Express)
app.post("/webhooks/cal", express.json(), async (req, res) => {
const { triggerEvent, payload } = req.body;
switch (triggerEvent) {
case "BOOKING_CREATED":
await db.bookings.create({
calBookingId: payload.bookingId,
userId: getUserByCalEmail(payload.organizer.email),
startTime: payload.startTime,
endTime: payload.endTime,
attendee: payload.attendees[0],
status: "confirmed",
});
break;
case "BOOKING_CANCELLED":
await db.bookings.update(
{ status: "cancelled" },
{ where: { calBookingId: payload.bookingId } },
);
break;
case "RECORDING_READY":
await db.sessions.update(
{ recordingUrl: payload.recordingUrl },
{ where: { calBookingId: payload.bookingId } },
);
break;
}
res.sendStatus(200);
});Juntándolo TODO: Webflow, Wized, y Xano
Para desarrolladores no-code y low-code, un entorno de trabajo práctico para combinar estas tres herramientas es Webflow + Wized + Xano.
Webflow maneja tu interfaz de usuario o UI — las páginas de reserva, los paneles de proveedores y los flujos de conexión. Wized añade la lógica JavaScript del front-end para comunicarse entre Webflow y tu backend sin escribir código complejo en el cliente. Xano actúa como tu backend: maneja el intercambio de tokens OAuth, almacena credenciales de usuario y registros de reservas, y expone el punto de destino (endpoint) del webhook donde Cal.com envía eventos.
Un flujo típico multiproveedor se vería así:
- El proveedor hace clic en "Connect your Cal.com account" en tu UI de Webflow
- Wized inicia la redirección OAuth a Cal.com
- El proveedor autoriza el acceso; Cal.com redirige de vuelta con un código
- Xano intercambia el código por tokens y los almacena
- Los clientes visitan la página de reservas del proveedor y utilizan el embed de Cal.com para reservar
- Cal.com dispara eventos de webhook a Xano, que los guarda en tu base de datos
- Wized recupera los datos de reservas desde Xano y Webflow los muestra en el panel del proveedor
Casos de Uso del Mundo Real
Marketplaces de Coaching — Cada coach conecta su cuenta de Cal.com mediante OAuth. Los clientes encuentran un coach y reservan una sesión a través del embed en su página de perfil. BOOKING_PAID activa la lógica de comisiones en Xano. RECORDING_READY hace que las repeticiones de la sesión estén disponibles en el panel del cliente.
Plataformas de Telemedicina — Los médicos establecen su disponibilidad directamente en Cal.com y sincronizan su calendario de Google. Los pacientes reservan citas a través del embed. El webhook BOOKING_CREATED actualiza los historiales médicos y hace una cola de recordatorios de citas.
Plataformas legales o de consultoría — Los consultores utilizan los formularios integrados de Cal.com para recopilar información antes de la cita. FORM_SUBMITTED envía esos datos a Xano incluso antes de que la reunión tenga lugar.
Por qué esto supera construir el tuyo propio
La programación de agendas y citas online es de esos sectores que parecen simples hasta que estás involucrado con husos horarios, tiempos entre reuniones (buffer times), conflictos de sincronización, flujos de pagos y lógica en las notificaciones. Todo esto lo resolvió Cal.com y ya gestiona millones de reservas de este modo.
Combinando su embed, OAuth y webhooks, obtienes una infraestructura de programación completa para tu plataforma sin construir en cero ninguna de sus partes. Cal.com maneja toda la complejidad dejándote foco sobre tu producto principal.
