Skip to content

Verifactu Direct API ​

Verifactu Direct API is the Bilteo product for registering invoices already issued by another system —an ERP, POS, or management application— with Veri*Factu and submitting them to the Spanish Tax Agency (AEAT). Bilteo is the compliance gateway, not the issuer. You provide the completed invoice, including its series, number, date, type, and already-classified tax breakdown, through a flat model. Bilteo fingerprints, chains, and submits it. There are no drafts, Bilteo series, or catalogs. Amounts are strings and dates use ISO format, such as 2026-06-13.

Is this the product you need?

Use Verifactu Direct API if your software already generates and numbers invoices and you only need Veri*Factu compliance. If you want Bilteo to issue and number the invoice and provide PDF/Facturae output, use the Bilteo Public API. See the introduction for a comparison.

Requirements

  • An API key or OAuth2 token with the verifactu:write scope.
  • The vf_direct_api.enabled account gate enabled. Bilteo enables it after verifying your integration. The endpoint returns 403 while it is disabled.

Example data

The tax IDs, VAT-IES numbers, passports, names, and amounts on this page are fictional. Replace them with the values from your real invoice.

Creating a record, field by field ​

A Verifactu Direct API invoice is flat: it contains its identity, type, total, recipient, and lines. The issuer is not sent, because it comes from your tenant.

FieldDescription
serie / numeroInvoice identity. You provide it and it is unique per tenant. serie may be empty.
fecha_expedicionISO date in YYYY-MM-DD format.
fecha_operacionOptional when it differs from the issue date.
tipo_facturaF1, F2, F3, or R1–R5.
descripcionDescription of the transaction.
importe_totalInvoice total as a string; negative for credit notes.
nif + nombreSpanish recipient. Use id_otro for foreign recipients. Optional for F2/R5.
lineas[]The already-classified tax breakdown.

Classifying each line ​

Each line states how it is taxed. Bilteo does not derive this from a catalog; your system provides it.

Line fieldPurpose
impuesto01 VAT, the default · 02 IPSI · 03 IGIC
base_imponibleTaxable base or non-taxable amount. Negative for credit notes.
tipo_impositivo + cuota_repercutidaTaxable transaction: percentage and tax amount.
operacion_exentaExempt transaction: E1–E6, instead of rate and tax amount.
calificacion_operacionS1 taxable · S2 reverse charge · N1 non-taxable · N2 non-taxable due to location
clave_regimenRegime: 01 general · 02 export · 03 used goods · 17 OSS · 18 equivalence surcharge…
tipo_recargo_equivalencia + cuota_recargo_equivalenciaEquivalence surcharge.

Practical rule: a line contains either tipo_impositivo and cuota_repercutida (taxable), or operacion_exenta (exempt), or an N1/N2calificacion_operacion (non-taxable).

Step-by-step creation: domestic F1 ​

The basic case: a standard invoice for a Spanish customer with one line taxed at 21%.

bash
curl -X POST https://api.test.bilteo.com/api/v1/external-invoices \
  -H "Authorization: Bearer bk_live_xxx" -H "Content-Type: application/json" \
  -d '{
    "serie": "FV", "numero": "1042", "fecha_expedicion": "2026-02-10",
    "tipo_factura": "F1", "descripcion": "Monthly maintenance",
    "nif": "B72648193", "nombre": "Marverde Workshops Ltd",
    "lineas": [
      { "base_imponible": "350", "tipo_impositivo": "21", "cuota_repercutida": "73.50" }
    ],
    "importe_total": "423.50"
  }'
# → 201
# { "id": "EXT…", "serie": "FV", "numero": "1042", "state": "pending",
#   "verifactu_record_id": "VF…" }

The invoice enters the same Veri*Factu chain as native invoices and is submitted to the AEAT. It starts in pending; use verifactu_record_id to track the outcome.

Validate the customer against the AEAT registry ​

If the recipient has a Spanish tax ID and you want to check the registry before creating the record, add "validar_cliente": true:

json
{ "serie": "FV", "numero": "1060", "fecha_expedicion": "2026-04-10",
  "tipo_factura": "F1", "descripcion": "Services",
  "nif": "B72648193", "nombre": "Marverde Workshops Ltd",
  "validar_cliente": true,
  "lineas": [ { "base_imponible": "350", "tipo_impositivo": "21", "cuota_repercutida": "73.50" } ],
  "importe_total": "423.50" }
// If the tax ID is not identified in the registry → 422 and nothing is registered

Bilteo queries the AEAT registry and rejects the request with 422 without registering anything if the tax ID cannot be identified. The flag defaults to false. It does not apply to foreign recipients (id_otro) or simplified invoices without a recipient.

See the full contract in the API reference.

Bilteo · Documentation