Crear factura (VeriFactu)
Alta de un registro de facturación VeriFactu ante la AEAT, campo a campo.
Da de alta un registro de facturación VeriFactu con una petición a:
POST /v1/verifactu/crear
En VeriFactu, los datos de identificación de la factura (serie, numero, fechaExpedicion) viajan dentro del bloque cabecera.
Petición
curl -X POST https://sandbox.veribai.com/v1/verifactu/crear \
-H "x-api-key: TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{
"version": "1.0",
"cabecera": {
"serie": "A",
"numero": "12345",
"fechaExpedicion": "03-04-2026",
"tipoFactura": "F1",
"descripcion": "Descripcion de la factura"
},
"emisor": {
"nif": "B76116342",
"nombre": "Prueba 1 SL"
},
"destinatario": {
"nif": "B17195595",
"nombre": "Nombre cliente, SL"
},
"detalleDesglose": [
{
"impuesto": "01",
"claveRegimen": "01",
"calificacionOperacion": "S1",
"baseImponible": "100.00",
"tipoImpositivo": "21.00",
"cuotaRepercutida": "21.00"
}
],
"totales": {
"cuotaTotal": "21.00",
"importeTotal": "121.00"
}
}'
from datetime import date
from decimal import Decimal
import veribai
client = veribai.Client(api_key="TU_CLAVE", environment="test")
respuesta = client.verifactu.crear({
"version": "1.0",
"cabecera": {
"serie": "A",
"numero": "12345",
"fechaExpedicion": date(2026, 4, 3),
"tipoFactura": "F1",
"descripcion": "Descripcion de la factura",
},
"emisor": {
"nif": "B76116342",
"nombre": "Prueba 1 SL",
},
"destinatario": {
"nif": "B17195595",
"nombre": "Nombre cliente, SL",
},
"detalleDesglose": [
{
"impuesto": "01",
"claveRegimen": "01",
"calificacionOperacion": "S1",
"baseImponible": Decimal("100.00"),
"tipoImpositivo": Decimal("21.00"),
"cuotaRepercutida": Decimal("21.00"),
},
],
"totales": {
"cuotaTotal": Decimal("21.00"),
"importeTotal": Decimal("121.00"),
},
})
print(respuesta["idFactura"], respuesta["estado"])
const respuesta = await fetch("https://sandbox.veribai.com/v1/verifactu/crear", {
method: "POST",
headers: {
"x-api-key": "TU_CLAVE",
"Content-Type": "application/json",
},
body: JSON.stringify({
"version": "1.0",
"cabecera": {
"serie": "A",
"numero": "12345",
"fechaExpedicion": "03-04-2026",
"tipoFactura": "F1",
"descripcion": "Descripcion de la factura"
},
"emisor": {
"nif": "B76116342",
"nombre": "Prueba 1 SL"
},
"destinatario": {
"nif": "B17195595",
"nombre": "Nombre cliente, SL"
},
"detalleDesglose": [
{
"impuesto": "01",
"claveRegimen": "01",
"calificacionOperacion": "S1",
"baseImponible": "100.00",
"tipoImpositivo": "21.00",
"cuotaRepercutida": "21.00"
}
],
"totales": {
"cuotaTotal": "21.00",
"importeTotal": "121.00"
}
}),
});
if (!respuesta.ok) throw new Error(`VeriBai ${respuesta.status}`);
const datos = await respuesta.json();
Campos
| Campo | Notas |
|---|---|
version |
Versión del contrato. Actualmente "1.0". |
cabecera.serie / cabecera.numero |
Identifican la factura. La numeración debe ser correlativa por serie. |
cabecera.fechaExpedicion |
Formato dd-mm-aaaa; no puede ser posterior a hoy. Reglas completas en Fechas de la factura. |
cabecera.tipoFactura |
F1 completa · F2 simplificada · F3 emitida en sustitución · R1–R5 rectificativas. |
cabecera.descripcion |
Descripción de la operación. |
emisor |
nif y nombre del emisor. Obligatorio. |
destinatario |
Obligatorio en F1, F3 y R1–R4. No se admite en F2 ni R5. |
detalleDesglose |
Entre 1 y 12 líneas de desglose fiscal. Importes como cadenas decimales. |
totales |
cuotaTotal e importeTotal. Deben cuadrar con el desglose. |
Respuesta
200 OK. El registro está validado, firmado y encolado para su remisión:
{
"nifEmisor": "B76116342",
"idFactura": "…",
"estado": "pendiente_proceso",
"serieNumero": "A12345",
"tipoFactura": "F1",
"importeTotal": "121.00",
"cuotaTotal": "21.00",
"creadoEn": "2026-04-03T10:00:00Z",
"urlValidacion": "https://…",
"qrBase64": "…"
}
qrBase64: el código QR como PNG en base64, listo para incrustar en tu plantilla de factura.urlValidacion: la URL de verificación que codifica el QR.estado:pendiente_procesoen el momento del alta. La remisión a la AEAT se completa en segundo plano; consulta el estado final conGET /v1/facturas/{idFactura}/estado.avisos: presente solo si la validación detectó avisos no bloqueantes.
El QR debe imprimirse en la factura acompañado de la leyenda correspondiente. La factura que entrega tu software a su cliente y el registro remitido a la AEAT son documentos distintos. Ver El registro de facturación.