🚀 Fase beta. ERP en fase privada —solicita acceso
Guías de la API Guía 4 de 6

Leer el resultado: el documento v1, los avisos y los errores

Qué trae el documento v1, qué significa la dirección y el aviso TIPO_DISCREPANTE, cómo tratar un aviso que tu programa no conoce y los códigos de error estables.

El documento v1

Un trabajo terminado trae en documento la factura auditada. Su esquema completo es respuesta.schema.json; estos son sus apartados:

campoqué es
direccionRECIBIDA (una compra de la empresa de la llave) o EMITIDA (una venta): la que declaraste al subirla
proveedor, clientelas dos partes, con nombre, cif_nif y direccion
facturala cabecera: numero, fecha, divisa, base_total, iva_total, total_factura, recargo_total…
impuestos_y_retencioneslas retenciones (hoy, IRPF), con su porcentaje y su importe, negativos si son retención
lineaslas líneas de la factura
dictamen_auditorialos hallazgos de la auditoría
verificacion_identidadlo que dice la Agencia Tributaria del NIF de la otra parte
lectura_papelquién emite y quién recibe según el papel, leído a ciegas
trazabilidadlo que se comprobó del desglose al cerrar
avisoslos avisos de la API; lista vacía si no hay ninguno
⚠️
Proveedor es siempre quien emite

proveedor es siempre quien emite la factura y cliente siempre quien la recibe, en compras y en ventas. En una venta, tu empresa es el proveedor. Para saber quién es quién según el papel, mira lectura_papel.

Un trabajo terminado, tal como lo devuelve la API (una compra del banco de pruebas, con NIF reservados por la AEAT), recortado a lo principal:

{
  "trabajo": "trb_01J9ZQ3K4T7W2B5N8C6D0F1G2H",
  "estado": "terminado",
  "creado": "2026-10-02T16:18:24Z",
  "terminado": "2026-10-02T16:18:49Z",
  "caduca": "2026-10-03T16:18:49Z",
  "documento": {
    "cliente": {"nombre": "TEST SL", "cif_nif": "B00000018", "direccion": ""},
    "proveedor": {"nombre": "OPERACION NO IDENTIFICADA EN CONSTITUCIÓN", "cif_nif": "B99999997", "direccion": "Poligono Norte 5, 50014 Zaragoza"},
    "factura": {"numero": "P-2026-0925", "fecha": "2026-09-22", "divisa": "EUR", "base_total": 150.0, "total_factura": 181.5, "es_rectificativa": false, "tiene_recargo_equivalencia": false, "iva_total": 31.5, "recargo_total": null},
    "impuestos_y_retenciones": [],
    "verificacion_identidad": {"verificado_por": "Agencia Tributaria (censo de NIF)", "identificador": "B99999997", "situacion": "IDENTIFICADO", "fecha_verificacion": "2026-09-25"},
    "trazabilidad": {"desglose_cuadra": true, "errores_finales": 0},
    "direccion": "RECIBIDA",
    "avisos": []
  },
  "pool": {"estado": "activa", "disponibles": 2411, "aviso_80": false}
}

El ejemplo entero, con sus líneas y su lectura_papel, está en la referencia interactiva.

factura.recargo_total es el recargo de equivalencia tal como lo da el motor de lectura, y null si no lo ha dado: la API no lo calcula ni lo supone.

ℹ️
La regla del v1: ignora lo que no conozcas

En v1 se pueden añadir campos, nunca quitarlos ni renombrarlos. Tu programa debe ignorar los campos que no conozca.

Los avisos

Un aviso no rechaza la factura: el trabajo llega terminado, con su documento, y descuenta de la pool como cualquier otro; pero conviene revisarla antes de contabilizarla. Van en documento.avisos, cada uno con su codigo estable y un mensaje. Los de hoy (… es el dato de tu factura):

codigomensaje que recibes
LECTURA_INCOMPLETALa auditoría terminó sin que todas las comprobaciones cuadraran. Revise el documento antes de contabilizarlo.
DESCUADRELos importes del documento no cuadran entre sí (bases, cuotas y total) ni tras releerlo. Puede que la factura esté mal calculada en origen.
NIF_CONTRAPARTE_NO_LOCALIZADONo se pudo localizar el NIF de la otra parte de la factura (el emisor si es recibida, el receptor si es emitida).
CIERRE_DESCONOCIDONo se pudo determinar cómo terminó la auditoría. Revise el documento.
PAGINAS_NO_LEIDASEl documento tiene … páginas y solo se leen las … primeras.
EMPRESA_NO_APARECEEl NIF asociado a la llave (…) no aparece entre los identificadores leídos en el documento. Compruebe que la factura es de esa empresa.
TIPO_DISCREPANTESe ha leído como …, como se indicó al subirla, pero en el documento la empresa de la llave aparece como …. Compruebe si es una compra o una venta.

TIPO_DISCREPANTE: dijiste compra y el papel dice venta (o al revés)

La factura se lee como la declaraste al subirla, y direccion lo repite. Pero en el papel la empresa de la llave aparece en el lado contrario. Antes de contabilizarla, comprueba si es una compra o una venta, que es lo que te pide el mensaje del aviso.

Un aviso que tu programa no conoce

La lista crece: se añaden códigos, nunca se renombran. Un código que tu programa no conozca, trátalo como «revise el documento».

Los errores

Cada error lleva un codigo estable, que es el que debe mirar tu programa, y un mensaje para personas, que puede cambiar de redacción:

{
  "error": {
    "codigo": "RITMO_EXCEDIDO",
    "mensaje": "Demasiadas peticiones seguidas. Espera y reintenta.",
    "reintentar_en_s": 5
  }
}

En 429 y 503, reintentar_en_s es lo mismo que la cabecera Retry-After. En POOL_AGOTADA, recargar dice dónde se recarga la pool.

HTTPcodigoqué hace tu programa
401LLAVE_INVALIDA, LLAVE_ANULADA, IP_NO_PERMITIDA, LLAVE_SIN_PERMISOrevisar la llave: falta, no es válida, está anulada, la IP no está permitida o no sirve para esa ruta
402POOL_AGOTADA, POOL_CERRADAla pool no puede procesar (ver la guía de la pool)
410NO_ENCONTRADOno existe, es de otra llave o ya caducó
410RECOGIDA_NO_VALIDAel vale de recogida está usado, caducado o no existe
413, 415, 422DOCUMENTO_NO_VALIDOel fichero pasa de 15 MB, no es PDF, JPEG ni PNG, falta o está roto
422PETICION_NO_VALIDAla petición está mal formada
429RITMO_EXCEDIDOesperar Retry-After y reintentar
500ERROR_INTERNOun fallo nuestro; no se ha descontado nada y puedes reintentar
503ERROR_INTERNOel motor de lectura no está disponible ahora mismo: reintentar tras Retry-After

Y dentro de un trabajo rechazado (que contesta 200), error.codigo es NO_ES_FACTURA, MULTIFACTURA, DOCUMENTO_NO_VALIDO o ERROR_INTERNO. Un trabajo rechazado no descuenta de la pool.

🚫
Esta API no usa 400, 403 ni 404

Una ráfaga de ellos hace que el cortafuegos de entrada bloquee tu IP durante horas. Los fallos de llave son 401; los de la pool, 402; los de ritmo, 429; los del documento, 413, 415 o 422; y si el motor de lectura no está disponible, 503 con Retry-After. El guion de arranque rápido en Python solo vuelve a preguntar ante 429 y 503, esperando lo que dice Retry-After.

La tabla de todos los errores, con un ejemplo literal de cada uno, está en la documentación.