Si tu app pide hoy a los usuarios una foto de su pasaporte o documento de identidad, seguramente has oído que las carteras europeas de identidad digital (EUDI Wallet) llegan “a finales de 2026”. La fecha es real y es exacta: el 24 de diciembre de 2026. Pero es un plazo para los Estados miembros, no para ti, y no apaga los escaneos de documentos.

Este artículo hace tres cosas. Muestra de dónde sale la fecha, con las cuentas. Enumera lo que una cartera entrega realmente, a partir de las tablas de atributos de las normas. Y esboza un diseño que acepta una cartera cuando el usuario la tiene y recurre al escaneo del documento cuando no. Lo publica doc.cheap, una API OCR de pasaportes y documentos de identidad, así que lee las partes de producto teniéndolo en cuenta. doc.cheap lee imágenes de documentos; no lee carteras.

De dónde sale el 24 de diciembre de 2026

La obligación es el art. 5a(1) del Reglamento (UE) n.º 910/2014, introducido por el Reglamento (UE) 2024/1183, la modificación de eIDAS. Dice que cada Estado miembro “proporcionará al menos una cartera europea de identidad digital en un plazo de 24 meses a partir de la fecha de entrada en vigor de los actos de ejecución a que se refieren el apartado 23 del presente artículo y el artículo 5c(6)”.

Así que el reloj no empieza con la propia modificación de eIDAS. Empieza con los actos de ejecución de la Comisión. Los actos del art. 5a(23) son cuatro actos de ejecución de la Comisión fechados el 28 de noviembre de 2024, entre ellos el Reglamento de Ejecución (UE) 2024/2979 sobre la integridad y las funcionalidades básicas de las carteras. Se publicó en el Diario Oficial (DO L, 2024/2979) el 4 de diciembre de 2024. Su art. 15 dice que “entrará en vigor el vigésimo día siguiente al de su publicación en el Diario Oficial de la Unión Europea”.

Las cuentas:

Paso Fecha
Publicado en el Diario Oficial 4 de diciembre de 2024
Día 1 tras la publicación 5 de diciembre de 2024
Día 20 tras la publicación: entrada en vigor 24 de diciembre de 2024
Más 24 meses (art. 5a(1)): plazo de las carteras 24 de diciembre de 2026
Más 36 meses (art. 5f(2)): ciertas partes usuarias privadas deben aceptar carteras 24 de diciembre de 2027

El “vigésimo día siguiente” se cuenta desde el día posterior a la publicación, así que el 4 de diciembre más 20 días cae en el 24, no en el 23. La misma fecha de entrada en vigor determina la segunda fecha de la tabla, que es la que de verdad interesa a la mayoría de los equipos de producto (más abajo).

Qué entrega una cartera

Una cartera no envía la foto de un pasaporte. Presenta datos firmados. El conjunto de datos de una persona física está fijado en el anexo del Reglamento de Ejecución (UE) 2024/2977: los “datos de identificación de la persona” (PID, person identification data). El anexo dice que los PID se expiden en dos formatos: ISO/IEC 18013-5:2021 y el “Verifiable Credentials Data Model 1.1” del W3C.

Estos son los atributos, con el carácter que el texto asigna a cada uno (tablas 1, 2 y 5 del anexo, tal como se publicaron el 4 de diciembre de 2024). La última columna es el campo más cercano en una respuesta de escaneo de doc.cheap, para que veas dónde coinciden los dos mundos y dónde no.

Atributo PID Carácter Campo más cercano en un escaneo de documento
family_name obligatorio holder.surname
given_name obligatorio holder.given_names
birth_date obligatorio holder.birth_date (ISO 8601)
birth_place obligatorio una entrada birth_place en fields[], cuando el documento lo imprime
nationality obligatorio (alfa-2, uno o varios) holder.nationality (alfa-3, uno)
resident_address, resident_country, resident_state, resident_city, resident_postal_code, resident_street, resident_house_number opcional ninguno en la página de datos de un pasaporte
personal_administrative_number opcional no es lo mismo; fields[] puede traer un personal_number que imprime el documento
portrait opcional images.main_photo
family_name_birth, given_name_birth opcional sin campo normalizado
sex opcional (códigos 0, 1, 2, 3, 4, 5, 6, 9) holder.sex (M, F, X)
email_address, mobile_phone_number opcional no figuran en un documento
expiry_date (metadatos) obligatorio document.expiry_date, pero del documento, no de los PID
issuing_authority (metadatos) obligatorio una entrada authority en fields[], cuando está impresa
issuing_country (metadatos) obligatorio (alfa-2) document.issuing_state (alfa-3)
document_number (metadatos) opcional no es lo mismo: el número de los PID lo asigna el proveedor de PID, document.number es el del pasaporte
issuing_jurisdiction, location_status (metadatos) opcional ninguno

Tres cosas de esa tabla importan cuando escribes el código de mapeo.

  • Los códigos de país difieren. Los PID usan ISO 3166-1 alfa-2 (DE). Los pasaportes y la zona de lectura mecánica usan alfa-3 (DEU). Mantén una sola forma interna y convierte en el borde.
  • “Obligatorio” no significa “siempre conocido”. Bajo la tabla 1 el texto añade: “Cuando no se conozca el valor de un atributo para la persona o no pueda expedirse de otro modo como parte del conjunto de datos de identificación de la persona, los Estados miembros utilizarán en su lugar un valor de atributo adecuado a la situación.” Espera valores de relleno, no claves ausentes.
  • Solo cinco atributos sobre la persona son obligatorios. Dirección, retrato, sexo y apellidos o nombres de nacimiento son todos opcionales. Si tu flujo necesita alguno de ellos, puede que la cartera sencillamente no lo lleve para un usuario concreto.

Quién seguirá llegando con un documento

El plazo obliga a cada Estado miembro a proporcionar una cartera. No obliga a nadie a usarla. El art. 5a(15) es tajante: “El uso de las carteras europeas de identidad digital será voluntario.” Y sigue: “Seguirá siendo posible acceder a servicios públicos y privados mediante otros medios de identificación y autenticación existentes.”

Así que después del 24 de diciembre de 2026 seguirás viendo:

  • Viajeros y clientes de fuera de la UE. Los considerandos vinculan la cartera a “la identidad jurídica de los ciudadanos de la Unión, de los residentes en la Unión o de las personas jurídicas”. Un visitante con un pasaporte de otro lugar no tiene una cartera de la UE que presentar.
  • Personas que no la han instalado, o no pueden, o prefieren no hacerlo. El texto protege esa elección.
  • Flujos que necesitan el propio documento. Algunos procesos quieren la imagen del documento, el número del documento o la zona de lectura mecánica del documento físico, no una atestación sobre la persona. Los PID de una cartera llevan su propio document_number, asignado por el proveedor de PID, que no es el número del pasaporte.
  • El periodo antes de que la cartera de un país concreto esté operativa. El 24 de diciembre de 2026 es el plazo legal. Cuándo llega de verdad cada cartera nacional a los usuarios es otra cuestión, y la única respuesta fiable para un país es el anuncio de ese propio país o el de la Comisión.

Un diseño que acepta ambos

La forma que sobrevive a todo esto es sencilla: pide la presentación de una cartera cuando el usuario la tiene y recurre al escaneo del documento cuando no. Ambos caminos terminan en el mismo registro interno.

user starts verification
        |
        v
  offers a wallet? --yes--> wallet presentation --> verify signature --> map PID
        |                                                               |
        no                                                              v
        |                                                      internal identity
        v                                                          record
  document photo --> POST /v1/scans --> map scan fields ----------------^

Unas pocas pautas hacen que los dos caminos sean intercambiables:

  1. Mapea ambos a un solo registro con tus propios nombres de campo. Usa la tabla de arriba como mapeo.
  2. Guarda el origen. Anota si un registro vino de una cartera o de un escaneo. Aportan pruebas distintas, y quien revise querrá saber cuál.
  3. Trata los nulos como honestos. En una respuesta de doc.cheap todas las claves están siempre presentes y un valor desconocido es null. Una cartera puede enviar en su lugar un valor de relleno. Normaliza ambos a una sola convención.
  4. Guarda lo mínimo que necesite el flujo. Un escaneo puede ejecutarse de forma que no quede nada escrito del lado de la API (ver abajo).

Esta es la llamada alternativa con fetch a secas. La clave pública de sandbox sk_sandbox_public figura en la documentación y no requiere registro; tiene un límite de peticiones por dirección de cliente.

import { readFileSync } from "node:fs";
import { randomUUID } from "node:crypto";

async function scanDocument(path, apiKey = "sk_sandbox_public") {
  const response = await fetch("https://api.doc.cheap/v1/scans", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      "Idempotency-Key": randomUUID(), // un reintento devuelve el primer resultado
    },
    body: JSON.stringify({
      image: readFileSync(path).toString("base64"),
      options: { retain_hours: 0, return_portrait: false }, // no se guarda nada
    }),
  });
  if (!response.ok) throw new Error(`scan failed: HTTP ${response.status}`);
  return response.json();
}

// Mapea un escaneo al mismo registro que llenaría la presentación de una cartera.
function fromScan(scan) {
  if (scan.meta.status !== "recognized") return null;
  const field = (name) => scan.fields.find((f) => f.id === `${name}@0`)?.value ?? null;
  return {
    source: "document_scan",
    family_name: scan.holder?.surname ?? null,
    given_name: scan.holder?.given_names ?? null,
    birth_date: scan.holder?.birth_date ?? null,
    birth_place: field("birth_place"),
    nationality_alpha3: scan.holder?.nationality ?? null,
    issuing_country_alpha3: scan.document?.issuing_state ?? null,
    document_number: scan.document?.number ?? null,
    mrz_status: scan.mrz.status, // "passed", "failed" o "absent"
  };
}

meta.status es una de cinco cadenas: recognized, no_document_found, unreadable, unsupported_document o rejected. Solo la primera debería llenar un registro; las demás deberían devolver al usuario a repetir la foto. Con una clave de pago, el saldo solo se cobra cuando el escaneo es facturable.

Ejecutamos una llamada de este tipo contra sk_sandbox_public el 24 de septiembre de 2026 a las 21:17 UTC, con el documento de prueba del propio producto, un pasaporte. La respuesta volvió con HTTP 200. Todos los valores del documento están enmascarados, y fields, images y mrz.lines están recortados:

{
  "meta": {
    "schema_version": "1.0",
    "id": "<SCAN_ID>",
    "status": "recognized",
    "billed": true,
    "confidence": "medium",
    "timing": { "upload_ms": 255, "processing_ms": 409, "total_ms": 678 },
    "created_at": "<RUN_TIMESTAMP>",
    "reference": null
  },
  "document": {
    "kind": "passport", "country": "<ISO3>", "country_name": "<COUNTRY>",
    "issuing_state": "<ISO3>", "number": "<DOCUMENT_NUMBER>", "series": null,
    "issue_date": "<DATE>", "expiry_date": "<DATE>", "is_expired": false, "days_remaining": "<N>"
  },
  "holder": {
    "given_names": "<GIVEN_NAMES>", "surname": "<SURNAME>", "full_name": "<FULL_NAME>",
    "birth_date": "<DATE>", "sex": "<SEX>", "nationality": "<ISO3>"
  },
  "mrz": { "status": "passed", "reason": null, "lines": ["<LINE_1>", "<LINE_2>"], "text": "<MRZ>" },
  "quality": { "overall": "pass" },
  "authenticity": { "overall": "not_checked", "checks": [] }
}

billed: true significa aquí que el escaneo era facturable y se descontó de la cuota gratuita del sandbox; a la clave de sandbox nunca se le cobra. El array fields de esa ejecución incluía entradas birth_place, authority y personal_number, que es adonde apunta la tabla de arriba para esos atributos PID. La página de datos de un pasaporte lleva su MRZ en dos líneas con el formato TD3; la página de formatos TD1, TD2 y TD3 muestra los formatos uno al lado del otro.

Fíjate en authenticity.overall: "not_checked". Un escaneo así es reconocimiento: lee lo impreso y comprueba los dígitos de control de la MRZ. No es detección de falsificaciones, y no ofrece la misma garantía que la presentación firmada de una cartera. Si tu proceso necesita un nivel de garantía más alto en el camino del escaneo, tiene que venir de otra parte de tu flujo. Si estás eligiendo proveedor para la alternativa, nuestra comparativa de API OCR de pasaportes expone las opciones, incluidas algunas que hacen algo más que reconocimiento.

Qué vigilar a continuación

  • 24 de diciembre de 2026 – plazo de las carteras. Art. 5a(1) del Reglamento (UE) 2024/1183, contado desde la entrada en vigor de los actos de ejecución como se muestra arriba.
  • 24 de diciembre de 2027 – partes usuarias privadas. El art. 5f(2) dice que las partes usuarias privadas que deban usar la autenticación reforzada de usuario para la identificación en línea, por ley o por contrato, “aceptarán también, a más tardar 36 meses después de la fecha de entrada en vigor de los actos de ejecución a que se refieren el artículo 5a(23) y el artículo 5c(6), y solo a petición voluntaria del usuario, las carteras europeas de identidad digital”. El texto nombra el transporte, la energía, la banca, los servicios financieros, la seguridad social, la sanidad, el agua potable, los servicios postales, la infraestructura digital, la educación y las telecomunicaciones, y excluye a las microempresas y pequeñas empresas.
  • Plataformas en línea de muy gran tamaño. El art. 5f(3) las obliga a aceptar carteras para la autenticación de usuarios, de nuevo solo a petición voluntaria del usuario y para los datos mínimos necesarios.
  • Cambios en los actos de ejecución. El considerando 4 del Reglamento de Ejecución (UE) 2024/2979 dice que la Comisión “debe revisarlo y actualizarlo” cuando sea necesario. Revisa las tablas de atributos del 2024/2977 antes de congelar un mapeo.

La conclusión práctica: construye el camino de la cartera cuando los países de tus usuarios lancen sus carteras, mantén el camino del documento y mapea ambos a un solo registro desde el primer día. La documentación de la API OCR de pasaportes y documentos de identidad cubre por completo la parte del escaneo.

Esto es un resumen técnico, no asesoramiento jurídico.