Subsanación de registros VeriFactu
Corrige y reenvía registros de facturación VeriFactu rechazados por la AEAT — 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), la normativa VeriFactu (Real
Decreto 1007/2023, art. 11) te permite subsanar el registro: reenviar el
mismo registro con el contenido corregido. No es una factura nueva, ni una
rectificativa, ni una anulación — el propio registro rechazado se repara y se
transmite de nuevo.
POST /v1/verifactu/records/{record}/subsanar- Scope:
verifactu:write - Body de la request: ninguno — el contenido subsanable se regenera en el servidor desde la factura origen y los datos maestros actuales.
- Respuesta:
202 Accepted— el reenvío se encola y se envía a la AEAT en unos segundos.
La subsanación nunca recalcula la huella original, el eslabón de encadenamiento con el registro anterior ni el sello de generación original: la AEAT casa el reenvío con el registro rechazado precisamente porque se conservan. No hay tope de intentos de subsanación — el límite de reintentos técnico aplica solo a los reintentos ciegos de fallos de transmisión.
Cuándo usarla — y cuándo no
| Situación | Qué hacer |
|---|---|
Registro rejected por la AEAT por un error de datos — NIF del destinatario no identificado en el censo, razón social incorrecta, problemas en la descripción… | Subsanación. Corrige los datos en su origen y llama a POST …/subsanar. |
Registro en error (fallo técnico de transmisión: timeout, AEAT caída). | Nada — la transmisión se reintenta automáticamente (reintento manual disponible). La subsanación responde record_not_rejected. |
Registro accepted pero la factura lleva datos incorrectos. | Una factura rectificativa (R1–R5). Un registro aceptado es inmutable — la subsanación responde record_not_rejected. |
| La corrección cambia un campo de la huella: NIF del emisor, serie + número, fecha de expedición, tipo de factura, cuota total o importe total. | Anulación + registro nuevo (factura nueva o rectificativa). La subsanación responde requires_annulment sin modificar nada. |
El flujo
Detecta el rechazo. Suscríbete al evento de webhook
invoice.verifactu_failed, o consulta el
listado de registros
buscando status: rejected. El registro lleva el detalle del rechazo de la
AEAT.
Corrige los datos en su origen. El contenido reenviado se regenera desde la factura origen y los datos maestros actuales — p. ej. corrige el NIF o la razón social del cliente y los valores nuevos se recogen automáticamente. El snapshot legal congelado de la factura se refresca deliberadamente para que el PDF coincida con lo que recibe la AEAT.
Llama al endpoint. El registro vuelve a entrar en la cola de transmisión con una ronda de intentos nueva:
curl -X POST https://api.factuarea.com/v1/verifactu/records/0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42/subsanar \
-H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW"Respuesta (202):
{
"data": {
"id": "0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42",
"message": "Subsanación encolada. El registro se reenviará a la AEAT en unos segundos."
}
}Vigila el resultado. El registro se transmite de nuevo y termina en
accepted — o en rejected otra vez si los datos siguen mal, en cuyo caso
puedes volver 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 concreta la causa:
{
"error": {
"type": "invalid_request_error",
"code": "business_rule_violation",
"subcode": "record_not_rejected",
"message": "El registro #842 no está rechazado por la AEAT (estado actual: accepted). Solo los registros rechazados admiten subsanación; para fallos técnicos usa el reintento."
}
}| HTTP | code / subcode | Cuándo |
|---|---|---|
| 404 | resource_not_found | El registro no existe o pertenece a otra empresa. |
| 422 | business_rule_violation / record_not_rejected | El registro no está en rejected (está aceptado, pendiente, enviado — o en error técnico, que ya cubre el reintento automático). |
| 422 | business_rule_violation / requires_annulment | La corrección toca campos de la huella. Anula el registro y emite una factura nueva o una rectificativa. |
| 422 | business_rule_violation / record_not_subsanable | El registro no es de alta, o no tiene factura origen desde la que regenerar. |
| 403 | insufficient_scope | La key no tiene el scope verifactu:write. |
Evita el rechazo antes de que ocurra
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/clients/census-verification
antes de emitirle facturas VeriFactu — así la subsanación se queda en lo
que debe ser: una red de seguridad, no una rutina.
Verificación censal AEAT
Contrasta el par razón social + NIF de tu empresa — y el de tus clientes — contra el censo de la AEAT antes de emitir facturas VeriFactu — estados deterministas, NIFs mágicos del sandbox y comportamiento fail-open.
Facturación FACe (B2G)
Envía facturas FacturaE 3.2.2 a FACe — códigos DIR3, XML firmado XAdES-EPES, estados de tramitación, anulación, simulación en sandbox y el scope facturae:write.