Spot Widget
Embebe el widget de onboarding de pacientes Spot en tu sitio — integración completa.
El widget es la integración Spot más común. Una clínica o plataforma de agendamiento mintea un token de un solo uso desde su backend, renderiza el widget Skip en un iframe, y escucha eventos de completitud.
Tu backend → POST /api/spot/widget → Skip retorna widget_token + url
Pestaña paciente → carga url con widget_token → el widget pide su estado a Skip
Skip retorna la pantalla correcta
↓
→ llena form en el iframe → Skip crea User + Beneficiary
↓
→ evento postMessage → Tu página gestiona el éxitoEsta página cubre la integración completa: generar el token (server-side), embeber el iframe, reaccionar a los eventos, y manejar los casos borde. El contrato del endpoint server-side está en Referencia → Generar widget token.
Vida útil de los tokens
| Tipo | TTL | Cuándo usar |
|---|---|---|
| Estándar | 1 hora | Por defecto. Se asume que el paciente termina en una sola sesión. |
| Long-term | 30 días | Pasa long_term_token=true al mintear. Útil cuando el paciente recibe el link por correo/WhatsApp y puede terminar después. |
Host del iframe
El iframe siempre carga desde https://spot.getskip.ai. Asegúrate de que tu CSP lo permita.
Embeber el iframe
Después de que tu backend mintee un widget_token, el navegador del paciente carga la URL retornada dentro de un iframe. El widget llama a Skip por su cuenta para obtener el estado de la sesión y renderiza la pantalla correcta.
Embed mínimo
<iframe
src="https://spot.getskip.ai?token=550e8400-..."
width="100%"
height="700"
style="border: 0;"
allow="clipboard-read; clipboard-write"
></iframe>Dimensiones recomendadas: al menos 480px de ancho y 640px de alto. El widget es responsivo dentro de esos límites.
Qué hace el widget al cargar
El iframe pide a Skip el estado de la sesión y renderiza la pantalla según lo que recibe: formulario de registro si el RUT es nuevo, pantalla de éxito si el paciente ya es Skip Pro, pantalla de suscripción si se le acabó la prueba, etc. No gestionas estas pantallas tú — el widget lo hace.
Tu responsabilidad
Tú solo gestionas el evento postMessage final que emite el widget cuando el paciente termina, cierra o falla (siguiente sección).
Eventos postMessage
El widget se comunica con su frame padre vía la API estándar postMessage. Tu página se suscribe una vez y reacciona a los eventos.
Suscribirse
window.addEventListener("message", (event) => {
if (event.origin !== "https://spot.getskip.ai") return;
const { type, payload } = event.data;
switch (type) {
case "SPOT_USER_CREATED":
// El paciente terminó el onboarding. payload.user_id es el ID nuevo.
break;
case "SPOT_WIDGET_CLOSED":
// El paciente cerró el widget sin terminar.
break;
case "SPOT_WIDGET_ERROR":
// Error irrecuperable. payload.code identifica la causa.
break;
}
});Verifica siempre event.origin antes de confiar en el payload — esto es higiene estándar de postMessage, no algo específico de Skip.
Vocabulario de eventos
| Tipo | Cuándo | Payload |
|---|---|---|
SPOT_USER_CREATED | Paciente terminó onboarding | { user_id, rut } |
SPOT_WIDGET_CLOSED | Paciente cerró el widget | sin payload |
SPOT_WIDGET_ERROR | Error irrecuperable dentro del widget | { code, message } |
El evento postMessage es la señal del frontend. Para UX (cerrar el modal, redirigir, confirmar) está perfecto; si tu lógica de negocio requiere certeza de que el usuario quedó creado, espera tu confirmación server-side habitual.
Medir adopción (onboarding iniciado y completado)
Los eventos postMessage son la interfaz pública para medir onboarding. No hay un webhook servidor→servidor ni un evento explícito de "onboarding iniciado":
- Iniciado — lo cuentas tú cuando montas el iframe (no hay evento para esto).
- Completado —
SPOT_USER_CREATED. - Abandonado —
SPOT_WIDGET_CLOSED. - Falló —
SPOT_WIDGET_ERROR.
SPOT_USER_CREATED es una señal de frontend. Si tu métrica de adopción necesita certeza server-side, confírmala con GET /api/spot/is_user_subscribed por RUT, o por el hecho de que POST /api/spot/gastos deje de responder 404 para ese paciente.
Casos borde
Colisiones de RUT: RUT_OTHER_EMAIL
Cuando un RUT ya está registrado en Skip bajo otro correo, el widget recibe un 409 con un payload de recuperación que incluye el correo enmascarado en archivo. Renderiza una pantalla "este RUT pertenece a otra cuenta" y le ofrece al paciente un flujo de recuperación (iniciar sesión con el correo original o contactar soporte). Tu página no necesita gestionar esto — aparece como SPOT_WIDGET_ERROR si el paciente no puede completar.
Para la matriz completa de combinaciones email/RUT — qué combinaciones permite Skip y cuáles bloquea — el documento autoritativo es interno. Pídele al equipo Skip la matriz email/RUT si estás diseñando un flujo que necesita gestionar estos casos explícitamente.
Tokens expirados
Los tokens estándar expiran 1 hora después del minteo. Si el paciente vuelve después (ej. desde un link guardado), el iframe recibe 410 Gone. Dos opciones:
- Mintear long-term token. Pasa
long_term_token=trueenPOST /api/spot/widget. El TTL pasa a 30 días. - Mintear on demand. Que la URL de recuperación que pongas en
metadata.retry_urlmintee un token nuevo.
Por qué el widget AAPD hace un POST /payment temprano
Si embebes Spot dentro de un flujo AAPD (con order_token seteado), notarás que el widget llama POST /orders/{order_hash}/payment antes de la pantalla de captura final. Es intencional: esa llamada también funciona como probe de readiness además de creación del pago.
Si vuelve un 400 con processor_customer_identity_not_validated o processor_payment_method_not_found, el widget interpreta la respuesta como señal de control de flujo y renderiza la pantalla apropiada (validación de identidad o setup de pago). Un 400 de esa llamada temprana no indica integración rota. No tienes que gestionarlo.