Spain B2B e-invoice (SPFE, UBL 2.5)
Spanish B2B e-invoice for the AEAT's public solution (SPFE, UBL 2.5)
A Spanish B2B e-invoice in the format of the AEAT's public e-invoicing solution (SPFE), checked against the UBL 2.5 schema the AEAT validates with.
About
Real Decreto 238/2026 makes e-invoices between Spanish businesses and professionals mandatory. Orden HAC/1028/2026, in force since 6 October 2026, sets up the AEAT's public solution (Solución Pública de Facturación Electrónica, SPFE) and starts the clock: twelve months for companies with a turnover over 8 million euros, twenty-four for the rest.
Invoices sent to the SPFE are UBL invoices that follow EN 16931 with the Spanish fields of Anexo I of the Order: CustomizationID urn:cen.eu:en16931:2026#conformant#urn:aeat.es:spfe:1.0.0:extended, the regime key of each line (REGI) and the NIF with schemeID "FC".
E-invoicing in Spain: the rules in short and how to check an invoice →
Good to know
- This entry checks the UBL 2.5 schema, the first of the three checks the AEAT lists in its validations document (version 0.1.0, October 2026). The AEAT accepts Invoice documents only, never a CreditNote or another document type in their place; it also accepts older UBL 2 versions when the invoice meets Anexo I.
- The second check, the EN 16931 rules in their 2026 edition, is not run here: CEN has not yet published the 2026 validation artefacts, and the current ones (1.3.17) reject the NIF written with schemeID "FC" that Anexo I asks for (BR-CL-11). The third, the AEAT's own business rules, will be published by the AEAT step by step.
- Anexo I gives the business process (BT-23) as urn:aeat:names:specification:ubl:schema:profile:B2B, while the AEAT's example invoice uses urn:aeat:names:specification:schema:profile:B2B. The schema accepts both.
- Anexo I uses CopyIndicator (BT-ES-1), which UBL 2.5 deprecates: the AEAT checks against the normative schemas, which still allow it, so this entry does too.
- The example is by xmlvalid.com, with made-up companies, after the AEAT's example invoice; it also passes the current EN 16931 rules, with one warning for the line's ValueQualifier.
Files
16 files · 870 KB-
maindoc/UBL-Invoice-2.5.xsd main
-
common/UBL-CommonAggregateComponents-2.5.xsd
-
common/UBL-CommonBasicComponents-2.5.xsd
-
common/UBL-CommonExtensionComponents-2.5.xsd
-
common/UBL-QualifiedDataTypes-2.5.xsd
-
common/BDNDR-UnqualifiedDataTypes-1.1.xsd
-
common/UBL-ExtensionContentDataType-2.5.xsd
-
common/BDNDR-CCTS_CCT_SchemaModule-1.1.xsd
-
common/UBL-CommonSignatureComponents-2.5.xsd
-
common/UBL-XAdES01903v132-201601-2.5.xsd
-
common/UBL-XAdES01903v141-201601-2.5.xsd
-
common/UBL-SignatureAggregateComponents-2.5.xsd
-
common/UBL-xmldsig-core-schema-2.5.xsd
-
common/UBL-SignatureBasicComponents-2.5.xsd
-
common/UBL-xmldsig1-schema-2.5.xsd
-
common/UBL-xmldsig11-schema-2.5.xsd
The validator loads all of these with their folder structure, so includes and imports resolve as published.
Example document
es-spfe-invoice.xml · 4.6 KB · valid against this schema
In CI and from code
The same schema by its name, es-spfe-invoice, through the API.
npx @xmlvalid/cli validate "**/*.xml" --schema es-spfe-invoice
- uses: xmlvalid/validate-action@v1
with:
files: "**/*.xml"
schema: es-spfe-invoice
api-key: ${{ secrets.XMLVALID_API_KEY }}
curl https://xmlvalid.com/api/v1/validations \
-H "Authorization: Bearer $XMLVALID_API_KEY" \
-F document={{ $schema->example ?? 'document.xml' }} -F schema=es-spfe-invoice
Free accounts get 100 API validations a month. On Pro, a URL monitor can check a published document against this schema every hour and email you when it breaks. More CI setups