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.
Esta página recorre la factura completa. Un cuerpo por cada tipo de factura (simplificada, exenta, intracomunitaria, con recargo, rectificativa) está en Ejemplos (VeriFactu).
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": "B00000000",
"nombre": "Prueba 1 SL"
},
"destinatario": {
"nif": "B11111119",
"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": "B00000000",
"nombre": "Prueba 1 SL",
},
"destinatario": {
"nif": "B11111119",
"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": "B00000000",
"nombre": "Prueba 1 SL"
},
"destinatario": {
"nif": "B11111119",
"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, exactamente como figuran en la factura, recargo de equivalencia incluido. Se validan contra el desglose (±10 €) y se transmiten tal como se declaran. |
Respuesta
200 OK. El registro está validado y encolado para su remisión:
{
"nifEmisor": "B00000000",
"idFactura": "…",
"estado": "pendiente_proceso",
"numSerieFactura": "A12345",
"serie": "A",
"numero": "12345",
"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.