5.9 KiB
API Reference
Endpoints
Health
GET /api/v1/health
Verifica que la API está funcionando.
Response:
{"status": "ok"}
Obtener Clave Pública
GET /api/v1/auth/public-key
Obtiene la clave pública RSA para cifrar contraseñas.
Response:
{"public_key": "base64_encoded_key"}
Registrar Certificado
POST /api/v1/auth/register
Registra y valida un certificado digital. El certificado se envía como base64 en el body (no como ruta de fichero).
Request (snake_case):
{
"cert_name": "mi-certificado",
"cert_file": "BASE64_CONTENT_OF_P12_FILE",
"password_encrypted": "base64_encoded_encrypted_password"
}
Request (PascalCase — compatibilidad con frontend):
{
"CertName": "mi-certificado",
"CertFile": "BASE64_CONTENT_OF_P12_FILE",
"PasswordEncrypted": "base64_encoded_encrypted_password"
}
Nota:
password_encrypteddebe ser la contraseña del certificado cifrada con la clave pública RSA obtenida en/api/v1/auth/public-key. No se envía en texto plano.
**Response (éxito):**
```json
{
"success": true,
"cert": {
"subject": "...",
"issuer": "...",
"expired": false,
"expiring_soon": false,
"days_until_expiry": 365
},
"token": "A1B2C3D4..."
}
Response (error):
{
"success": false,
"error": "certificate_expired",
"cert": {
"subject": "...",
"issuer": "...",
"expired": true
}
}
Formatos Disponibles
GET /api/v1/formats
Lista los formatos de entrada soportados. La API detecta automáticamente el formato del JSON recibido.
Response:
{
"formats": ["dolibarr", "native"]
}
Alta de Factura
POST /api/v1/facturas
Registra una factura en VeriFactu. El formato de entrada se detecta automáticamente (no requiere parámetro).
Formato nativo (por defecto):
{
"tipo": "alta",
"factura": {
"emisor_nif": "53950250R",
"emisor_nombre": "EMPRESA EJEMPLO SL",
"num_serie": "FV2026/001",
"fecha_expedicion": "17-04-2026",
"tipo_factura": "F1",
"descripcion": "Factura de prueba",
"destinatario": {
"nombre": "CLIENTE SL",
"nif": "B98765432"
},
"iva": [
{"base": 100.00, "cuota": 21.00, "tipo": 21.0}
],
"importe_total": 121.00
},
"sistema": {
"nombre": "Mi Sistema",
"nif_proveedor": "53950250R",
"version": "1.0"
}
}
Formato Dolibarr BFF:
{
"invoice": {
"number": "FA2024/001",
"date": "2024-09-13T00:00:00Z",
"notePublic": "Factura de prueba",
"lines": [
{"description": "Servicio", "quantity": 1, "unitPrice": 100, "taxRate": 21}
]
},
"client": {
"name": "CLIENTE SL",
"vatNumber": "B98765432"
},
"emisor": {
"nif": "53950250R",
"nombre": "EMPRESA EJEMPLO SL"
},
"sistema": {
"nombre": "Mi Sistema",
"nif_proveedor": "53950250R",
"version": "1.0"
}
}
Ver formatos.md para detalles de cada formato y cómo añadir nuevos.
Response (AEAT disponible):
{
"success": true,
"csv": "A-FSZKDA8UG7WD9U",
"estado": "Correcto"
}
Response (fallback local):
{
"success": true,
"csv": "0CE5F940CEA...",
"estado": "Correcto (local)"
}
Nota: El campo
sistema.nombredebe coincidir con el nombre registrado en la AEAT para el NIF del emisor. Si no coincide, la AEAT rechazará la factura con error de censo (código 1110 o 1239).
---
### Anular Factura
POST /api/v1/facturas/anular
Anula una factura previamente registrada. Usa el mismo formato que el alta pero con `tipo: "anulacion"` y `tipo_factura: "R1"` (u otro tipo de rectificativa).
**Request:**
```json
{
"tipo": "anulacion",
"factura": {
"emisor_nif": "53950250R",
"emisor_nombre": "JOSEP VICENT MESTRE LLOBELL",
"num_serie": "FV2026/001",
"fecha_expedicion": "21-05-2026",
"tipo_factura": "R1",
"descripcion": "Anulacion de factura de prueba",
"iva": [
{"base": 1000.00, "cuota": 210.00, "tipo": 21.0}
],
"importe_total": 1210.00
},
"sistema": {
"nombre": "JOSEP VICENT MESTRE LLOBELL",
"nif_proveedor": "53950250R",
"version": "1.0"
}
}
Response (éxito):
{
"success": true,
"estado": "Anulada"
}
Nota: El campo
sistema.nombredebe coincidir con el nombre registrado en la AEAT para el NIF del emisor. Si no coincide, la AEAT rechazará la factura con error de censo.
## Códigos de Error
| Código | Descripción |
|--------|------------|
| `certificate_expired` | El certificado ha expirado |
| `certificate_not_yet_valid` | El certificado aún no es válido |
| `certificate_expiring_soon` | El certificado caduca en menos de 30 días |
| `invalid_password_or_format` | Contraseña incorrecta o formato inválido |
| `file_not_found` | El archivo de certificado no existe |
| `validation_failed` | Los datos de la factura no son válidos |
| `aeat_error` | Error comunicando con la AEAT |
| `aeat_fault` | Error SOAP de la AEAT |
| `hash_save_error` | Error guardando el hash local |
| `hash_storage_error` | Error leyendo el hash anterior |
| `missing_fields` | Faltan campos obligatorios en el registro |
| `invalid_json` | El JSON enviado no es válido |
| `decrypt_failed` | No se pudo descifrar la contraseña con la clave privada |
| `emisor_nif_required` | Falta el NIF del emisor en la anulación |
| `num_serie_required` | Falta el número de serie en la anulación |
| `fecha_expedicion_required` | Falta la fecha de expedición en la anulación |
## Errores de la AEAT más comunes
| Código | Descripción | Solución |
|--------|------------|----------|
| 1110 | NIF no identificado en el censo | Verificar que `sistema.nombre` coincide con el nombre del NIF |
| 1189 | Bloque Destinatarios obligatorio para tipo F1/F3/R1-R4 | Incluir `destinatario` con nombre y NIF |
| 1239 | Error en bloque Destinatario | Verificar formato del NIF del destinatario |