Factuarea APIDevelopers

Subsanación de registros VeriFactu

Corrige un registro de facturación VeriFactu —rechazado o aceptado por la AEAT— con un registro NUEVO que lo sucede. Cuándo aplica la subsanación, cuándo necesitas una anulación o una rectificativa y el flujo exacto de la API.

Cuando la AEAT rechaza un registro de facturación VeriFactu por un error de datos (registro con status: rejected), o cuando un registro aceptado resulta llevar datos erróneos para los que las reglas de facturación no exigen una factura rectificativa, la normativa VeriFactu (Real Decreto 1007/2023, art. 11) te permite subsanarlo. La AEAT no admite una edición en su sitio: la corrección es siempre un registro nuevo, y el original permanece intacto (descripción de los servicios web de la AEAT, §9.1.2 y §9.1.3). No es una factura nueva, ni una rectificativa, ni una anulación.

POST /v1/companies/{company}/verifactu/records/{record}/subsanar
  • Scope: verifactu:write
  • Cuerpo de la petición: ninguno — el contenido se regenera en el servidor a partir de la factura de origen y de los datos maestros actuales.
  • Respuesta: 202 Accepted con data.id, el id del registro nuevo, que es el que se transmite. El registro nuevo empieza en pending; léelo con GET /v1/companies/{company}/verifactu/records/{id}.

El registro nuevo tiene la misma clave de factura (NIF del emisor, serie, número y fecha) que el que corrige, su propia huella (huella) y su propia posición en la cadena, después del último registro de la empresa: la cadena nunca se reescribe. Siempre declara Subsanacion=S, y su RechazoPrevio depende del caso: ninguno para un registro aceptado (§9.1.2); X para un registro rechazado cuya factura la AEAT no tiene, porque el registro rechazado nunca existió allí (§9.1.3); S para una subsanación rechazada de una factura que la AEAT sí tiene. No hay tope de intentos de subsanación.

Cuándo usarla — y cuándo no

El propio registro te dice si admite subsanación: can_subsanar en el objeto registro es true cuando el registro es un alta, está aceptado, aceptado con errores o rechazado, es la última alta de su factura y la factura no está anulada.

SituaciónQué hacer
Registro rejected por la AEAT por un error de datos — NIF del destinatario no identificado en el censo, nombre del destinatario erróneo, problemas de descripción…Subsanación. Corrige el dato en su origen y llama a POST …/subsanar.
Registro rejected con aeat_error_code: SCHEMA_INVALID: no cumplía el esquema de la AEAT y nunca se envió.Subsanación, tras corregir el dato culpable. No detiene el resto de la cadena.
Registro accepted (o aceptado con errores) con un error de datos interno para el que las reglas de facturación no exigen una rectificativa.Subsanación: un alta nueva sucede a la aceptada.
Registro accepted y las reglas de facturación exigen una rectificativa (un error que debe corregirse con una factura rectificativa, una devolución, un importe distinto…).Una factura rectificativa (R1–R5).
Registro en error (fallo técnico: timeout, AEAT caída) o pending.Nada — la transmisión se reintenta sola (reintento manual disponible). La subsanación responde record_not_rejected.
La corrección cambia un campo de la huella: NIF del emisor, serie + número, fecha de emisión, tipo de factura, cuota total o importe total.Anulación + registro nuevo (factura nueva o rectificativa). La subsanación responde requires_annulment sin crear nada.

El flujo

Detéctalo. Para un rechazo, suscríbete al evento de webhook invoice.verifactu_failed, o consulta el listado de registros buscando status: rejected (o usa el filtro «requiere atención» de la aplicación). El registro lleva el detalle del rechazo de la AEAT en aeat_error_code.

Corrige el dato en su origen. El registro nuevo se regenera a partir de la factura de origen y de los datos maestros actuales — por ejemplo, corrige el NIF o el nombre registrado del cliente y los valores nuevos se recogen automáticamente. El snapshot legal congelado de la factura se refresca a propósito para que el PDF coincida con lo que recibe la AEAT.

Llama al endpoint. Un registro nuevo se incorpora a la cola de transmisión de la empresa:

curl -X POST https://api.factuarea.com/v1/companies/{company}/verifactu/records/0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42/subsanar \
  -H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW"

Respuesta (202):

{
  "data": {
    "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8d11",
    "message": "Subsanación encolada. El registro se reenviará a la AEAT en unos segundos."
  }
}

data.id es el registro nuevo, nunca el que enviaste.

Observa el resultado. El registro nuevo se transmite y acaba accepted — o rejected otra vez si los datos siguen mal, en cuyo caso vuelves a subsanar (no hay límite de intentos).

Errores

Las violaciones de regla de negocio devuelven 422 con code: business_rule_violation y un subcode que señala la causa:

{
  "error": {
    "type": "invalid_request_error",
    "code": "business_rule_violation",
    "subcode": "record_not_rejected",
    "message": "El registro no está rechazado ni aceptado por la AEAT (estado actual: pending). Solo los registros rechazados o aceptados admiten subsanación; para fallos técnicos usa el reintento."
  }
}
HTTPcode / subcodeCuándo
404resource_not_foundEl registro no existe o pertenece a otra empresa.
422business_rule_violation / record_not_rejectedEl registro no está ni aceptado ni rechazado: está pendiente, enviado — o en error técnico, que cubre el reintento automático.
422business_rule_violation / requires_annulmentLa corrección toca campos de la huella. Anula el registro y emite una factura nueva o una rectificativa.
422business_rule_violation / record_not_subsanableEl registro no es un alta; no es la última alta de su factura (una subsanación posterior ya la sustituye); la factura está anulada; o no tiene factura de origen desde la que regenerar.
403insufficient_scopeLa clave no tiene el scope verifactu:write.

Evita el rechazo desde el principio

El rechazo de datos más frecuente es un destinatario que el censo de la AEAT no identifica (rechazo 1239). Verifica el par nombre + NIF de un cliente con POST /v1/companies/{company}/contacts/census-verification antes de emitirle facturas VeriFactu — así la subsanación sigue siendo lo que debe ser: una red de seguridad, no una rutina.

Un campo de datos que no cabe en el esquema de la AEAT ni siquiera llega tan lejos: la factura no se emite (422 verifactu_not_eligible, consulta Alta automática en VeriFactu).

En esta página

¿Te echamos una mano?Contactar con soporte