Guía de Integración SSO JWT

Integración por SSO: la empresa firma un JWT con el secreto compartido, redirige al usuario al endpoint de Nume, y Nume crea o reactiva la cuenta, inicia sesión en Nume.

Flujo

  1. El usuario está autenticado en el portal de la empresa.
  2. La empresa firma un JWT con los datos del usuario y el secreto compartido.
  3. Redirige el browser a Nume con ese JWT en la query.
  4. Nume valida el JWT, crea el usuario si no existe (o lo reactiva si estaba desactivado), inicia sesión y redirige a la app.

Requisitos previos

Antes de usar este flujo, Nume les entrega:

  • API host — base URL de la API de Nume (prod o testing)
  • Integration UUID — identifica la integración en la URL
  • JWT secret — clave compartida para firmar el JWT (algoritmo HS256)

Endpoint

Método GET. La empresa debe redirigir el browser del usuario a esta URL (no es una llamada server-to-server).

URL:

GET /integrations/sso/{integrationUuid}?token={jwt}

Claims del JWT

Algoritmo HS256. El secret es el valor entregado por Nume.

Campos requeridos

CampoTipoDescripción
email o external_idstringExactamente uno de los dos. No enviar email y external_id juntos.
iatnumberUnix timestamp (segundos) de emisión. El token se rechaza si tiene más de 5 minutos de antigüedad.

Campos opcionales

CampoTipoDescripción
full_namestringNombre completo del usuario
data.first_namestringNombre
data.last_namestringApellido
data.dnistringDocumento
data.date_of_birthstringFecha ISO 8601 UTC, ej. "1995-07-21T00:00:00.000Z"
data.countrystringPaís, ej. "Argentina"
data.genderstring"M" o "F"
data.dial_codestringCódigo de país, ej. "+54"
data.phone_numberstringTeléfono sin código de país
expnumberOpcional. Si se envía, Nume lo ignora.

Ejemplo de payload

Con email y datos de perfil:

{
  "email": "usuario@ejemplo.com",
  "full_name": "Juan Pérez",
  "iat": 1710000000,
  "data": {
    "first_name": "Juan",
    "last_name": "Pérez",
    "dni": "12345678",
    "date_of_birth": "1995-07-21T00:00:00.000Z",
    "country": "Argentina",
    "gender": "M",
    "dial_code": "+54",
    "phone_number": "1123456789"
  }
}

Mínimo con external_id:

{
  "external_id": "USR-12345-ABC",
  "iat": 1710000000
}

Ejemplo de código (Node.js)

Importante

Firmá el JWT siempre en tu backend. No expongas el secret en el frontend ni en la app.
const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();

const secret = process.env.NUME_SSO_JWT_SECRET; // secreto entregado por Nume
const integrationUuid = process.env.NUME_INTEGRATION_UUID; // integration UUID entregado por Nume
const apiBaseUrl = process.env.NUME_API_BASE_URL; // host de la API de Nume

app.get('/entrar-a-nume', (req, res) => {
  const token = jwt.sign(
    {
      email: 'usuario@ejemplo.com',
      full_name: 'Juan Pérez',
      // iat lo agrega jsonwebtoken automáticamente
    },
    secret,
    { algorithm: 'HS256' },
  );

  const url =
    `${apiBaseUrl}/integrations/sso/${integrationUuid}` +
    `?token=${encodeURIComponent(token)}`;

  res.redirect(url);
});

app.listen(3000);

Errores comunes

Si el acceso falla, Nume redirige al usuario a una pantalla de error genérica (código en la URL). Códigos posibles:

CódigoCausa típica
invalid_requestFalta identidad, o se enviaron email y external_id juntos
invalid_tokenJWT inválido, firma incorrecta o sin iat
token_expirediat con más de 5 minutos de antigüedad
forbiddenIntegración inactiva, empresa no habilitada para SSO, o empresa eliminada
not_foundIntegration UUID inexistente
unexpectedError inesperado al procesar el acceso

Notas

  • Si el usuario no existe, Nume lo crea.
  • Si existía pero estaba desactivado, Nume lo reactiva al entrar por SSO.
  • Si solo envían external_id, Nume usa un email sintético interno basado en ese id.
  • Este flujo es independiente de POST /integrations/token (API key).

Implementación con iframe (flujo embebido / nativo)

Si preferís no sacar al usuario de tu portal (o lo mostrás dentro de una app nativa con WebView), podés apuntar un iframe / WebView al mismo endpoint de tu backend que firma el JWT y hace el redirect (por ejemplo /entrar-a-nume).

Importante

Firmá el JWT siempre en tu backend. No expongas el secret en el frontend ni en la app.

Sin el atributo allow correcto no funcionan las llamadas con los médicos (cámara, micrófono y captura de pantalla).

El iframe carga tu endpoint; ese endpoint redirige a Nume

<iframe
  title="Nume"
  src="/entrar-a-nume"
  style="width: 100%; height: 100%; border: 0;"
  allow="camera *; microphone *; autoplay *; display-capture *; clipboard-read *; clipboard-write *"
  allowfullscreen
></iframe>
Copyright © 2026, Nuevo Método