Crear, redirigir, confirmar

Crear el recorrido (aquí, un control de mayoría de edad):

curl -X POST https://verify.todis.eu/hosted/sessions \
  -H "Authorization: Bearer TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "check": "age_over_18",
    "country_code": "FR",
    "locale": "es",
    "success_url": "https://tu-tienda.example/retorno-verificacion",
    "reference": "pedido-1042"
  }'

Respuesta: la URL a la que redirigir, y el identificador que conservar.

{
  "session_id": "…",
  "hosted_url": "https://verify.todis.eu/v/…",
  "expires_at": "2026-08-19T12:34:56Z"
}

Redirige el navegador de tu usuario a hosted_url: Todis muestra el código QR (cartera en otro dispositivo), el botón de apertura (cartera en el mismo dispositivo), y gestiona la espera en el idioma pedido. success_url significa verificación superada, nunca que el usuario sea mayor de edad: una prueba de edad que vale false también llega allí, como cualquier resultado verificado. Lee el resultado en el servidor (claims.age_over_18 con el atajo age_over_18) y aplícale tu propia regla. Cuando el usuario vuelve a tu success_url, tu backend confirma (nunca sobre la sola base de los parámetros de la URL, que el usuario puede falsificar):

curl https://verify.todis.eu/verify/sessions/SESSION_ID \
  -H "Authorization: Bearer TU_TOKEN"

{ "status": "verified", "claims": { "age_over_18": true } }

El atajo "check": "identity" solicita en su lugar apellidos, nombre, fecha de nacimiento y nacionalidad (la base de un alta KYC), y todos los campos avanzados de la API de sesión siguen disponibles. cancel_url (opcional) recibe al usuario en caso de fallo. La página lleva la marca Todis; una versión en marca blanca está en estudio para el plan Premium.

El webhook, tu cinturón de seguridad

Si el usuario cierra la página antes de la redirección, sigues enterándote: añade webhook_url al crear el recorrido y tu backend recibe un POST JSON {"event": "session.verified", "session_id": "…", "reference": "…"} al concluir (reintentos automáticos mientras no respondas 2xx). Cada envío va firmado HMAC-SHA256 en la cabecera X-Todis-Signature con el webhook_secret entregado en la creación:

// Node.js: verificar la firma t=<marca>,v1=<hex>
const crypto = require("node:crypto");
function firmaValida(cuerpo, cabecera, secreto) {
  const [t, v1] = cabecera.split(",").map((p) => p.split("=")[1]);
  const esperado = crypto.createHmac("sha256", secreto)
    .update(t + "." + cuerpo).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(esperado));
}

El webhook nunca contiene los datos verificados: solo te dice que el recorrido ha terminado, y el resultado se lee con la llamada autenticada de arriba.

El QR en tu propia página: el componente web

Si prefieres mantener al usuario en tu página en lugar de redirigirlo, un componente web incrusta la página alojada y te comunica los cambios de estado:

<script src="https://todis.eu/js/todis-verify.js"></script>

<todis-verify hosted-url="HOSTED_URL_GENERADA_POR_TU_BACKEND"></todis-verify>

<script>
  document.querySelector("todis-verify")
    .addEventListener("todis:verified", () => {
      // Desbloquear el siguiente paso de TU interfaz,
      // y confirmar en el servidor como siempre.
    });
</script>

Eventos emitidos: todis:status en cada cambio, y luego todis:verified, todis:failed o todis:expired. La hosted_url la genera siempre tu backend: tu token de licencia nunca sale de tu servidor.

Las tres reglas que nunca cambian. El token de licencia se queda en el servidor. El resultado se confirma con un GET /verify/sessions/{id} autenticado, nunca sobre la base de un parámetro de URL o un evento del navegador. Y no hay nada que almacenar: ni copia del documento, ni foto, solo la respuesta verificada que pediste, como se explica en la FAQ.