JS SDK Reference
Referencia completa de @allsign/embedded — inspirado en Plaid Link moderno y Typeform Embed. Modelo client_secret-only: una sola credencial pública, efímera, scoped a una session.
Instalación
npm install @allsign/embedded
O vía CDN para proyectos sin bundler:
<script src="https://js.allsign.io/v1/embed.js" async></script>
El SDK se carga en 2 fases: un stub ligero (~3KB) que expone la API inmediatamente, y el runtime completo que carga bajo demanda cuando montas el widget. Tu página no se ralentiza.
Inicialización
import { AllSign } from '@allsign/embedded';
const session = AllSign.init({
clientSecret: 'as_sess_xxx_secret_yyy',
// callbacks y opciones (ver tabla más abajo)
});
El clientSecret es la única credencial que el frontend maneja. Es efímero (15 min), single-use y scoped a una sola firma — lo genera tu backend con POST /v2/signing-sessions usando tu secret key, y lo pasas al frontend. Tu secret key nunca sale del backend.
¿Por qué no hay publishable key? Porque no aporta nada: el clientSecret ya encoda el session_id y el tenant, y el env (live vs test) se infiere del bundle del SDK y del test_mode que devuelve el init. Seguimos el modelo Plaid moderno (post-2020) que deprecó su publicKey por la misma razón, no el modelo Stripe que requiere pk para tokenización originada en el browser — nuestro browser nunca crea nada antes de que exista una session.
Modos de embedding
Todas las funciones de montaje son métodos del objeto session devuelto por AllSign.init(). Las opciones visuales (locale, theme, values) se pasan en init; los métodos de montaje solo reciben el contenedor o config de posicionamiento.
session.modal()
Abre un overlay fullscreen sobre tu aplicación. El más fácil de integrar — no necesitas un contenedor.
const session = AllSign.init({
clientSecret: 'as_sess_xxx_secret_yyy',
locale: 'es-MX',
theme: { primaryColor: '#1a73e8' },
onSuccess: (result) => { /* firmado */ },
onExit: (metadata) => { /* cerró */ },
onEvent: (event) => { /* progreso */ },
});
session.modal();
session.inline(container)
Monta el widget dentro de un elemento DOM que tú controlas. Ideal cuando la firma es parte de tu layout.
const session = AllSign.init({
clientSecret: 'as_sess_xxx_secret_yyy',
locale: 'es-MX',
values: { nombre: 'Juan', rfc: 'ABC123' },
onSuccess: (result) => { /* firmado */ },
});
session.inline('#firma-container');
<div id="firma-container" style="width: 100%; height: 600px;"></div>
El widget comunica su altura al parent y se auto-redimensiona para evitar doble scroll.
Para la mejor experiencia, el contenedor debe tener al menos 500px de ancho y 500px de alto. El widget es responsive y se adapta, pero contenedores muy pequeños degradan la experiencia.
session.slider(options)
Abre un panel lateral (drawer). El firmante firma sin perder contexto de lo que estaba haciendo en tu app.
const session = AllSign.init({
clientSecret: 'as_sess_xxx_secret_yyy',
onSuccess: (result) => { /* firmado */ },
});
session.slider({
position: 'right', // 'left' o 'right'
width: 600, // ancho en px (default: 500)
});
Opciones de AllSign.init()
Estas son todas las opciones que puedes pasar al crear la session:
| Parámetro | Tipo | Requerido | Default | Descripción |
|---|---|---|---|---|
clientSecret | string | ✅ | — | El client_secret de tu Signing Session (creado en tu backend con POST /v2/signing-sessions) |
locale | 'es-MX' | 'en-US' | — | 'es-MX' | Idioma de la interfaz |
theme | ThemeOptions | — | — | Personalización visual |
values | Record<string, string> | — | — | Pre-fill de variables del template desde el frontend |
allowCancel | boolean | — | true | Permite al firmante cerrar/cancelar |
onSuccess | (result: SigningResult) => void | — | — | Se dispara cuando el firmante completó |
onExit | (metadata: ExitMetadata) => void | — | — | Se dispara cuando la sesión termina (por cualquier razón) |
onEvent | (event: SigningEvent) => void | — | — | Se dispara en cada paso del flujo (OTP, IDV, firma) |
onReady | () => void | — | — | Se dispara cuando el widget terminó de cargar |
ThemeOptions
| Propiedad | Tipo | Descripción |
|---|---|---|
primaryColor | string | Color principal — botones, links, acentos (hex) |
backgroundColor | string | Color de fondo del widget |
buttonText | string | Texto del botón principal (default: "Firmar documento") |
logo | string | URL de tu logo (se muestra en el header) |
React Hook: useAllSignLink
El hook para React elimina todo el boilerplate. Inspirado en usePlaidLink.
npm install @allsign/embedded
import { useAllSignLink } from '@allsign/embedded/react';
function SignButton({ clientSecret }) {
const { open, ready, error } = useAllSignLink({
clientSecret,
mode: 'modal', // 'modal' | 'inline' | 'slider'
onSuccess: (result) => {
// result.signatureId — UUID de la firma
// result.documentId — UUID del documento
// result.signedAt — timestamp ISO-8601
console.log('Firmado:', result.signatureId);
},
onExit: (metadata) => {
// metadata.reason — 'completed' | 'cancelled' | 'expired' | 'error'
// metadata.lastStep — último paso completado ('otp', 'id_scan', 'signature')
console.log('Salió en:', metadata.lastStep);
},
onEvent: (event) => {
// Eventos granulares para analytics y UI
// event.name — 'OTP_SENT', 'OTP_VERIFIED', 'ID_SCAN_STARTED',
// 'ID_SCAN_COMPLETED', 'DOCUMENT_VIEWED',
// 'SIGNATURE_DRAWN', 'SIGNATURE_SUBMITTED'
// event.timestamp — ISO-8601
// event.metadata — datos adicionales del paso
console.log('Evento:', event.name);
},
});
if (error) return <p>Error: {error.message}</p>;
return (
<button onClick={open} disabled={!ready}>
Firmar documento
</button>
);
}
Hook API
| Propiedad | Tipo | Descripción |
|---|---|---|
open | () => void | Abre la sesión de firma |
ready | boolean | true cuando el SDK cargó y el clientSecret es válido |
error | Error | null | Error de inicialización (secret inválido, expirado, etc.) |
Callbacks detallados
onSuccess(result)
Se dispara cuando el firmante completó su firma. Úsalo para feedback instantáneo en tu UI.
interface SigningResult {
signatureId: string; // UUID de la firma
documentId: string; // UUID del documento
signerEmail: string; // Email del firmante
signedAt: string; // Timestamp ISO-8601
}
onExit(metadata)
Se dispara siempre que la sesión termina, sin importar la razón. Es tu "catch-all" para cleanup.
interface ExitMetadata {
reason: 'completed' | 'cancelled' | 'expired' | 'error';
lastStep: 'otp' | 'id_scan' | 'variables' | 'document_view' | 'signature' | null;
sessionId: string;
documentId: string;
error?: {
code: string;
message: string;
};
}
lastStep te dice exactamente dónde abandonó el firmante — útil para analytics y para mostrar el paso correcto si vuelve a intentar.
onEvent(event)
Se dispara en cada paso del flujo. Granular, ideal para analytics y para mostrar progreso en tu UI.
interface SigningEvent {
name: string; // Nombre del evento
timestamp: string; // ISO-8601
metadata: Record<string, any>;
}
Eventos disponibles:
| Evento | Cuándo se dispara |
|---|---|
SESSION_STARTED | El widget se montó y cargó |
OTP_SENT | Se envió el código OTP (si está configurado) |
OTP_VERIFIED | El firmante verificó su OTP |
ID_SCAN_STARTED | Inició escaneo de identificación |
ID_SCAN_COMPLETED | Escaneo de INE completado |
SELFIE_CAPTURED | Selfie capturada para face match |
BIOMETRIC_VERIFIED | Face match exitoso (INE vs selfie) |
VARIABLES_FILLED | El firmante completó las variables del formulario |
DOCUMENT_VIEWED | El firmante vio el documento |
SIGNATURE_DRAWN | El firmante dibujó su firma |
SIGNATURE_SUBMITTED | La firma se envió al servidor |
SESSION_COMPLETED | Todo el flujo terminó exitosamente |
Métodos de instancia
session.close()
Cierra la sesión de firma y destruye el iFrame.
const session = AllSign.init({ clientSecret: '...' });
session.inline('#container');
// Después...
session.close();
session.unmount()
Desmonta el widget del DOM sin cerrar la sesión. Útil para cleanup en React.
useEffect(() => {
const session = AllSign.init({ clientSecret });
session.inline('#container');
return () => session.unmount();
}, [clientSecret]);
HTML Data Attributes (no-code)
Para integraciones sin JavaScript (WordPress, Webflow, sitios estáticos):
<div
data-allsign-session="as_sess_xxx_secret_yyy"
data-allsign-mode="inline"
data-allsign-locale="es-MX"
data-allsign-theme-primary="#1a73e8"
data-allsign-theme-button-text="Firmar contrato"
style="width: 100%; height: 600px;">
</div>
<script src="https://js.allsign.io/v1/embed.js" async></script>
El script detecta los atributos data-allsign-* y monta automáticamente. Para escuchar eventos, usa custom events del DOM:
document.addEventListener('allsign:success', (e) => {
console.log('Firmado:', e.detail.signatureId);
});
document.addEventListener('allsign:exit', (e) => {
console.log('Razón:', e.detail.reason);
});
TypeScript
El SDK incluye tipos completos:
import type {
AllSignSession,
AllSignInitOptions,
SigningResult,
ExitMetadata,
SigningEvent,
ThemeOptions,
} from '@allsign/embedded';
import type {
UseAllSignLinkOptions,
UseAllSignLinkReturn,
} from '@allsign/embedded/react';
Manejo de errores
const session = AllSign.init({
clientSecret: '...',
onExit: (metadata) => {
if (metadata.reason === 'error') {
switch (metadata.error?.code) {
case 'SESSION_EXPIRED':
// El client_secret expiró — genera uno nuevo en tu backend
refreshSession();
break;
case 'SESSION_INVALID':
// Token inválido o ya consumido
showError('Esta sesión de firma ya no es válida.');
break;
case 'NETWORK_ERROR':
// Error de red
showError('Error de conexión. Intenta de nuevo.');
break;
case 'DOCUMENT_NOT_FOUND':
showError('El documento ya no está disponible.');
break;
case 'DOCUMENT_COMPLETED':
showInfo('Este documento ya fue firmado.');
break;
case 'DOCUMENT_CANCELLED':
showError('Este documento fue anulado.');
break;
}
}
},
});
Códigos de error
| Código | Descripción |
|---|---|
SESSION_EXPIRED | El client_secret expiró (>15 min). Genera uno nuevo. |
SESSION_INVALID | Token inválido o ya consumido. |
NETWORK_ERROR | No se pudo cargar el widget (red, CORS, CSP). |
DOCUMENT_NOT_FOUND | El documento no existe o fue eliminado. |
DOCUMENT_COMPLETED | El documento ya fue firmado por todos. |
DOCUMENT_CANCELLED | El documento fue anulado por el creador. |
SIGNER_NOT_FOUND | El firmante no está asociado al documento. |
CAMERA_DENIED | El usuario no permitió acceso a la cámara (necesario para IDV). |
Compatibilidad
| Browser | Versión mínima |
|---|---|
| Chrome | 80+ |
| Firefox | 78+ |
| Safari | 14+ |
| Edge | 80+ |
| Mobile Safari (iOS) | 14+ |
| Chrome Android | 80+ |
Siguiente paso
- Personalización — Branding, temas y locale
- Eventos y Callbacks — Eventos client-side + webhooks server-side
- Seguridad — Sessions, CSP y validación

