Cumplimiento por API (VeriFactu y SII)
Configura y consulta el envío de tus facturas a la AEAT por VeriFactu y por el SII. Esta página cubre lo operativo. Qué obliga la normativa, a quién y desde cuándo no se explica aquí.
Todas las rutas cuelgan de https://app.faxtal.com/api/v1.1 y se autentican con la cabecera X-API-Key (ver Autenticación).
Permisos
| Operación | Permiso de la clave |
|---|---|
| Consultas (configuración, registros, envíos, incidencias, eventos, estados) | compliance:read |
PUT /api/v1.1/verifactu/config, POST /api/v1.1/verifactu/sif, PUT /api/v1.1/sii/config | Acceso total (*) |
Sin el permiso, la API responde 403 scope_missing.
VeriFactu
Cómo funciona
- Periodos de activación. El modo y el entorno se fijan por periodos. El modo es
verifactu(remite los registros a la AEAT) ono_verifactu. El entorno es el de pruebas de la AEAT o producción. Los periodos se gestionan en la aplicación: la API solo abre el primero (ver Activar VeriFactu). - Envío automático. Al emitir una factura se genera su registro. En modo
verifactu, los registros se envían a la AEAT sin que hagas nada más. - Registros inmutables. Un registro no se modifica: una corrección genera un registro nuevo y los anteriores se conservan.
- Territorio foral. Las empresas con domicilio fiscal en País Vasco o Navarra no pueden activar VeriFactu.
Consultar la configuración
GET /api/v1.1/verifactu/config
curl -s "https://app.faxtal.com/api/v1.1/verifactu/config" \
-H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY"
{
"configured": true,
"applicable": true,
"mode": "verifactu",
"regime_state": "habilitado",
"operated_by_partner": false,
"sandbox": false,
"updated_at": "2026-09-01T10:00:00Z",
"active_certificate": {
"name": "EMPRESA DEMO SL",
"fingerprint": "AB:CD:EF:..."
}
}
| Campo | Descripción |
|---|---|
configured | La empresa ya tiene configuración VeriFactu. |
applicable | false si la empresa está en territorio foral. |
mode | Modo del periodo vigente: verifactu o no_verifactu. |
regime_state | Estado de la activación: no_activado (sin periodo vigente), pendiente_mandato (sin certificado ni firma delegada), habilitado, suspendido o revocado. |
operated_by_partner | La empresa la opera un partner. |
sandbox | true si el periodo vigente usa el entorno de pruebas de la AEAT. |
active_certificate | Certificado con el que se firmarán los registros (propio o de firma delegada), o null. |
Activar VeriFactu
PUT /api/v1.1/verifactu/config
Permiso de la clave: acceso total (*).
| Campo | Tipo | Por defecto | Descripción |
|---|---|---|---|
mode | "verifactu" | "no_verifactu" | "no_verifactu" | Modo del periodo inicial. |
sandbox | boolean | true | true para el entorno de pruebas de la AEAT; false para producción. |
curl -s -X PUT "https://app.faxtal.com/api/v1.1/verifactu/config" \
-H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
-H "Content-Type: application/json" \
-d '{"mode": "verifactu", "sandbox": true}'
- Necesita un certificado VeriFactu activo en la empresa o una firma delegada vigente.
- Si la empresa no tiene ningún periodo abierto, abre uno desde hoy con ese modo y entorno.
- Si ya hay un periodo abierto, no lo cambia. Para cambiar de modo o de entorno, usa la aplicación.
La respuesta devuelve, entre otros, configured, enabled (hay periodo vigente y certificado), mode, sandbox, certificate_id y certificate_name.
| HTTP | code | Causa |
|---|---|---|
409 | verifactu_not_applicable_foral | La empresa tiene domicilio fiscal en territorio foral. |
409 | active_verifactu_certificate_or_delegation_required | La empresa no tiene con qué firmar: ni certificado activo (de propósito VeriFactu o general), ni el de la asesoría que la gestiona, ni firma delegada vigente. |
Registros de una factura
GET /api/v1.1/invoices/{invoice_id}/verifactu/records
Devuelve todos los registros de la factura (altas, subsanaciones y anulaciones), del más antiguo al más reciente.
[
{
"tipo": "alta",
"mode": "verifactu",
"environment": "production",
"estado": "accepted",
"huella": "3C464DAF61ACB827...",
"huella_anterior": "8A1F0C2E9B7D4A60...",
"qr_url": "https://...",
"aeat_csv": "A-XXXXXXXXXXXXXX",
"ts_gen": "2026-09-01T10:00:05Z",
"submitted_at": "2026-09-01T10:00:07Z",
"created_at": "2026-09-01T10:00:05Z",
"updated_at": "2026-09-01T10:00:08Z",
"has_xml_enviado": true,
"has_xml_respuesta": true
}
]
tipo:altaoanulacion.qr_url: URL del QR de la factura.huellayhuella_anterior: encadenamiento del registro.
Si la factura no existe, responde 404 invoice_not_found.
XML de una factura
GET /api/v1.1/invoices/{invoice_id}/verifactu/xml
Devuelve, como adjunto application/xml, el XML enviado del registro de alta vigente: si hay subsanaciones, el de la última.
curl -s "https://app.faxtal.com/api/v1.1/invoices/00000000-0000-0000-0000-000000000001/verifactu/xml" \
-H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
-o registro.xml
Si la factura no tiene registro de alta con XML, responde 404 verifactu_xml_not_found. La respuesta de la AEAT no se descarga por API: has_xml_respuesta solo indica si existe.
Envíos a la AEAT
GET /api/v1.1/verifactu/submissions?offset=0&limit=50
limit va de 1 a 200. Los envíos salen del más reciente al más antiguo.
| Campo de cada envío | Descripción |
|---|---|
id | Identificador del envío. |
environment | Entorno del envío. |
submission_type | Tipo de envío. |
ref_requerimiento | Referencia del requerimiento, si el envío responde a uno. |
record_count | Registros incluidos. |
estado_envio | Resultado global del envío. |
aeat_csv | CSV devuelto por la AEAT. |
error_code / error_message | Error del envío completo, si lo hubo. |
lineas[] | Resultado por registro: num_serie, fecha_expedicion, estado_registro, codigo_error, descripcion_error. |
submitted_at / created_at | Fechas del envío. |
La respuesta trae además total, offset y limit.
Incidencias
GET /api/v1.1/verifactu/incidents?limit=200
Reúne los registros rechazados de los limit envíos más recientes (1 a 500). Cada incidencia trae submission_id, num_serie, estado_registro, codigo_error, descripcion_error y submitted_at. total cuenta las incidencias encontradas.
{
"items": [
{
"submission_id": "sub_ABC123",
"num_serie": "A-2026-0042",
"estado_registro": "Incorrecto",
"codigo_error": "4104",
"descripcion_error": "...",
"submitted_at": "2026-09-01T10:00:07Z"
}
],
"total": 1
}
Consultar la AEAT por periodo
GET /api/v1.1/verifactu/aeat-records?period=2026-09
Consulta en ese momento a la AEAT los registros de la empresa del mes indicado (period con formato YYYY-MM).
La respuesta trae periodo, resultado_consulta, indicador_paginacion, clave_paginacion y records[]. Cada registro incluye num_serie, fecha_expedicion, estado_registro, codigo_error, descripcion_error, tipo_factura e importe_total.
La API devuelve solo la primera página de la consulta: no admite pedir las siguientes. Si la consulta falla, responde 422 verifactu_aeat_query_error con el detalle en errors.
Eventos SIF
Solo tienen efecto con un periodo no_verifactu vigente.
Registrar un evento: POST /api/v1.1/verifactu/sif. Permiso de la clave: acceso total (*).
| Campo | Valores |
|---|---|
tipo_evento | "01" (inicio) | "02" (fin) |
curl -s -X POST "https://app.faxtal.com/api/v1.1/verifactu/sif" \
-H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
-H "Content-Type: application/json" \
-d '{"tipo_evento": "01"}'
Responde 201 con el evento: tipo_evento, mode, environment, fecha_hora_huso_gen_evento, huella_evento, huella_evento_anterior y created_at. Si la empresa no está en modalidad No VERI*FACTU, responde 409 verifactu_sif_not_applicable. Si el evento no se puede generar, responde 422 verifactu_sif_emit_error con el detalle en errors.
Listar eventos: GET /api/v1.1/verifactu/sif?limit=50 (1 a 200). Devuelve un array de eventos con los mismos campos.
SII
Cómo funciona
- Periodos de inscripción. La inscripción se fija por periodos:
mandatory,voluntary_opted_inoceased, cada uno con su entorno. Se gestionan en la aplicación. La API los consulta. - Envío automático. Con
auto_submitactivo, las facturas pendientes se envían a la AEAT automáticamente. La API no lanza envíos manuales.
Configuración
GET /api/v1.1/sii/config
{
"enrollment_status": "mandatory",
"tax_authority": "aeat",
"auto_submit": true,
"certificate_id": null,
"environment": "production",
"enrollment_periods": [
{
"id": 12,
"enrollment_status": "mandatory",
"environment": "production",
"start_date": "2026-01-01",
"end_date": null,
"notes": null
}
],
"updated_at": "2026-01-02T09:00:00Z"
}
| Campo | Descripción |
|---|---|
enrollment_status | not_applicable, mandatory, voluntary_opted_in o ceased. Sin configuración, not_applicable. |
tax_authority | aeat o atc. |
auto_submit | Envío automático de pendientes. |
environment | Entorno del periodo vigente. |
enrollment_periods[] | Periodos de inscripción. |
PUT /api/v1.1/sii/config. Permiso de la clave: acceso total (*).
| Campo | Tipo | Descripción |
|---|---|---|
auto_submit | boolean | null | Activa o desactiva el envío automático. |
certificate_id | integer | null | Identificador de un certificado de la empresa (ver GET /api/v1.1/certificates). |
Solo cambia los campos que envías. Responde con la configuración completa.
curl -s -X PUT "https://app.faxtal.com/api/v1.1/sii/config" \
-H "X-API-Key: fctXXXXXXXX_YYYYYYYYYYYYYYYY" \
-H "Content-Type: application/json" \
-d '{"auto_submit": true}'
Pendientes y plazos
GET /api/v1.1/sii/pending?limit=500
Facturas pendientes de enviar, de la de plazo más cercano a la más lejana. limit va de 1 a 1000.
{
"items": [
{
"invoice_public_id": "00000000-0000-0000-0000-000000000001",
"invoice_id": 81234,
"book_type": "ISSUED",
"deadline": "2026-09-18",
"days_remaining": 3
}
],
"total": 1
}
- Usa
invoice_public_idpara identificar la factura en el resto de la API. book_type:ISSUED(emitidas) oRECEIVED(recibidas).days_remaininges negativo si el plazo ya ha vencido.totales el número de elementos devueltos.- El plazo es de 4 días sin contar sábados, domingos ni festivos nacionales, y como mucho el día 16 del mes siguiente.
GET /api/v1.1/sii/deadlines?limit=200 devuelve la misma lista, con 200 como límite por defecto.
Envíos
Historial: GET /api/v1.1/sii/submissions?offset=0&limit=50, con limit de 1 a 200. Filtros opcionales: global_status, book_type, date_from y date_to (fechas de envío, ambas incluidas).
Cada envío trae public_id, book_type, operation_type, global_status, submitted_at, csv, record_count, error_code y error_description. La respuesta trae además total, offset y limit.
Detalle: GET /api/v1.1/sii/submissions/{submission_id}, con el public_id del envío.
Devuelve submission (los mismos campos) e items[], una línea por factura. Cada línea trae invoice_public_id, invoice_number, item_status, error_code, error_description y aeat_record_state. Si el envío no existe, responde 404 sii_submission_not_found.
Cobros y pagos en criterio de caja
Si la empresa está en el criterio de caja, o recibe facturas con la clave 07, el SII pide además cada cobro (libro de emitidas) y cada pago (libro de recibidas). Faxtal los comunica a partir de los cobros y pagos registrados:
- Primero la factura con la
07; el cobro o pago, cuando la factura ya está registrada en la AEAT. - Plazo: 4 días desde el cobro o pago, sin contar sábados, domingos ni festivos nacionales.
- Una corrección se comunica como un importe negativo (el SII no admite modificar un cobro).
- Lo que siga sin cobrar el 31 de diciembre del año siguiente al de la operación se comunica con esa fecha y el medio
03. - Con
auto_submitactivo se envían solos. La API pública no los consulta todavía: se ven en la aplicación, en SII › Cobros y pagos.
Estado SII de una factura
GET /api/v1.1/invoices/{invoice_id}/sii/status
Devuelve un array con el estado de la factura en cada libro: book_type, tax_authority, status, deadline, submitted_at, accepted_at, error_code y error_description.
invoice_id y last_submission_id de la respuesta son identificadores numéricos internos: no sirven como {submission_id} en el detalle de envíos. Si la factura no existe, responde 404 invoice_not_found.
Errores
Los errores llegan con el formato {"detail": {"code": "...", "message": "...", "request_id": "..."}} (ver Errores).
| HTTP | code | Causa |
|---|---|---|
403 | scope_missing | La clave no tiene el permiso de la operación. |
404 | invoice_not_found | La factura no existe en la empresa de la clave. |
404 | verifactu_xml_not_found | La factura no tiene registro de alta con XML. |
404 | sii_submission_not_found | El envío SII no existe. |
409 | verifactu_not_applicable_foral | Empresa en territorio foral. |
409 | active_verifactu_certificate_or_delegation_required | Falta un certificado activo (VeriFactu o general), el de la asesoría o la firma delegada. |
409 | verifactu_sif_not_applicable | El evento SIF solo se registra en modalidad No VERI*FACTU. |
422 | verifactu_aeat_query_error | La consulta a la AEAT ha fallado. |
422 | verifactu_sif_emit_error | No se ha podido registrar el evento SIF. |
422 | request_validation_error | Parámetros o cuerpo no válidos (p. ej. limit fuera de rango). |