ZATCA XML Format Explained: UBL 2.1 Invoice Structure Guide

Atif Mehmood March 25, 2026 10 min read Technical Guide

Every ZATCA-compliant e-invoice is an XML document built on the UBL 2.1 standard. Understanding this format is essential for developers building ZATCA integrations, IT teams evaluating invoicing solutions, and business owners who want to understand what their systems are generating behind the scenes.

This guide breaks down the ZATCA XML structure section by section, covering mandatory fields, namespaces, Saudi-specific extensions, and the most common validation errors.

What Is UBL 2.1?

Universal Business Language (UBL) is an open standard maintained by OASIS (Organization for the Advancement of Structured Information Standards). Version 2.1 is the specific version ZATCA adopted for Saudi Arabia's e-invoicing mandate. UBL defines a library of XML document types for business transactions including invoices, credit notes, and debit notes.

ZATCA selected UBL 2.1 because it is widely used internationally, well-documented, and flexible enough to accommodate Saudi-specific requirements through extensions. Every invoice your system generates must conform to the UBL 2.1 schema with ZATCA's additional rules applied.

ZATCA XML Namespaces

ZATCA XML format and A3 invoice layout download

ZATCA invoice layout and XML download options

The XML document starts with namespace declarations that tell parsers which schemas to validate against. ZATCA invoices use these primary namespaces:

<!-- Root element with namespaces --> <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" >

Invoice Header Structure

The invoice header contains identification and classification data:

<!-- Extensions block (for digital signature) --> <ext:UBLExtensions> <ext:UBLExtension> <ext:ExtensionContent> <!-- Digital signature goes here --> </ext:ExtensionContent> </ext:UBLExtension> </ext:UBLExtensions> <!-- Profile and customization IDs --> <cbc:ProfileID>reporting:1.0</cbc:ProfileID> <cbc:ID>INV-2026-0001</cbc:ID> <cbc:UUID>6f4d20e0-6bfe-4a80-9389-7dabe6620f12</cbc:UUID> <cbc:IssueDate>2026-03-25</cbc:IssueDate> <cbc:IssueTime>14:30:00</cbc:IssueTime> <cbc:InvoiceTypeCode name="0100000">388</cbc:InvoiceTypeCode> <cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode>

Key Header Fields

Field Description Example
ProfileID"reporting:1.0" for B2C, "clearance:1.0" for B2Breporting:1.0
IDYour internal invoice numberINV-2026-0001
UUIDUniversally unique identifier (v4)6f4d20e0-6bfe-...
IssueDateInvoice date in YYYY-MM-DD format2026-03-25
IssueTimeInvoice time in HH:MM:SS format14:30:00
InvoiceTypeCode388 = Invoice, 381 = Credit Note, 383 = Debit Note388
InvoiceTypeCode @name7-digit binary code encoding invoice subtypes0100000
DocumentCurrencyCodeISO 4217 currency codeSAR

The InvoiceTypeCode Name Attribute

The 7-digit binary name attribute encodes invoice characteristics. Position 1: third-party invoice. Position 2: nominal supply. Position 3: exports. Position 4: summary invoice. Position 5: self-billed. Position 6–7: reserved. For a standard tax invoice, the value is "0100000".

Seller and Buyer Information

Both parties are represented using the AccountingSupplierParty and AccountingCustomerParty elements:

<!-- Seller (Supplier) --> <cac:AccountingSupplierParty> <cac:Party> <cac:PartyIdentification> <cbc:ID schemeID="CRN">1234567890</cbc:ID> </cac:PartyIdentification> <cac:PostalAddress> <cbc:StreetName>King Fahd Road</cbc:StreetName> <cbc:CityName>Riyadh</cbc:CityName> <cbc:PostalZone>12345</cbc:PostalZone> <cac:Country> <cbc:IdentificationCode>SA</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID>300012345600003</cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName>شركة المثال التجارية</cbc:RegistrationName> </cac:PartyLegalEntity> </cac:Party> </cac:AccountingSupplierParty>

Arabic Registration Name

The RegistrationName for the seller MUST be in Arabic. Using the English company name here is one of the most common XML validation errors. Ensure your system stores and uses the Arabic business name for the supplier party element.

Invoice Line Items

Each product or service on the invoice is represented as an InvoiceLine element. Every line must have a sequential numeric ID starting from 1:

<cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode="PCE">2</cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID="SAR">200.00</cbc:LineExtensionAmount> <cac:TaxTotal> <cbc:TaxAmount currencyID="SAR">30.00</cbc:TaxAmount> <cbc:RoundingAmount currencyID="SAR">230.00</cbc:RoundingAmount> </cac:TaxTotal> <cac:Item> <cbc:Name>Wireless Mouse</cbc:Name> <cac:ClassifiedTaxCategory> <cbc:ID>S</cbc:ID> <cbc:Percent>15</cbc:Percent> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:ClassifiedTaxCategory> </cac:Item> <cac:Price> <cbc:PriceAmount currencyID="SAR">100.00</cbc:PriceAmount> </cac:Price> </cac:InvoiceLine>

VAT Category Codes

CodeDescriptionVAT Rate
SStandard rate15%
ZZero-rated0%
EExempt from VAT0%
OOut of scope (not subject to VAT)0%

Tax Total and Legal Monetary Total

ZATCA invoice PDF with tax totals

ZATCA-compliant invoice showing tax breakdown

The invoice must contain a tax total section that breaks down VAT by category, and a legal monetary total summarizing all amounts:

<!-- Tax Total --> <cac:TaxTotal> <cbc:TaxAmount currencyID="SAR">30.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="SAR">200.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="SAR">30.00</cbc:TaxAmount> <cac:TaxCategory> <cbc:ID>S</cbc:ID> <cbc:Percent>15</cbc:Percent> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> </cac:TaxTotal> <!-- Legal Monetary Total --> <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID="SAR">200.00</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID="SAR">200.00</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID="SAR">230.00</cbc:TaxInclusiveAmount> <cbc:PayableAmount currencyID="SAR">230.00</cbc:PayableAmount> </cac:LegalMonetaryTotal>

Digital Signature Block

Phase 2 invoices must contain a digital signature embedded in the UBLExtensions section. The signature uses XMLDsig (XML Digital Signature) standard and includes:

The digital signature proves the invoice was created by the certificate holder and has not been modified since signing. This is crucial for maintaining the integrity chain that ZATCA validates. A ZATCA-compliant POS system handles this signing process automatically for every transaction.

Previous Invoice Hash

ZATCA requires a hash chain linking each invoice to its predecessor. The AdditionalDocumentReference section includes a SHA-256 hash of the previous invoice's XML:

<cac:AdditionalDocumentReference> <cbc:ID>PIH</cbc:ID> <cac:Attachment> <cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain"> NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNz... </cbc:EmbeddedDocumentBinaryObject> </cac:Attachment> </cac:AdditionalDocumentReference>

For the very first invoice in the chain, use a Base64-encoded SHA-256 hash of "0" as the previous invoice hash. Every subsequent invoice hashes the previous invoice's XML to create an unbreakable chain.

Common XML Validation Errors

Based on real-world implementations, these are the most frequent errors developers encounter:

  1. Missing or incorrect namespace declarations — ensure all four namespaces are present on the root element
  2. InvoiceLine ID not starting from 1 — ZATCA requires sequential line IDs beginning at 1, not 0
  3. Missing currencyID attribute — every monetary amount element must include currencyID="SAR"
  4. English-only RegistrationName — seller name must be in Arabic
  5. Invalid UUID format — must be a valid UUID v4 string
  6. Mismatched totals — line extension amounts must sum to the tax-exclusive total, and VAT calculations must be mathematically correct
  7. Missing Previous Invoice Hash — the PIH reference is mandatory even on the first invoice
  8. Wrong ProfileID — using "clearance:1.0" when reporting or vice versa

For a complete guide to error codes and their solutions, see our ZATCA error codes guide.

Let Your POS Handle the XML Complexity

LookPOS generates fully compliant UBL 2.1 XML for every transaction — invoices, credit notes, debit notes. Digital signatures, hash chains, and QR codes are all automated.

Start Free Trial Ask a Developer

Frequently Asked Questions

What XML format does ZATCA use for e-invoices? +

ZATCA uses Universal Business Language (UBL) version 2.1 XML format. This is an international OASIS standard for electronic business documents, with Saudi-specific extensions and mandatory fields defined by ZATCA's e-invoicing regulations.

What are the mandatory fields in a ZATCA XML invoice? +

Mandatory fields include UUID, invoice number (ID), issue date and time, invoice type code with subtype name, document currency, seller information (name in Arabic, VAT number, address), buyer information (for B2B), line items with tax categories, tax totals, legal monetary totals, previous invoice hash, and the digital signature block.

Can I create ZATCA XML invoices manually? +

While technically possible for a single invoice, it is completely impractical for production. The XML includes complex namespaces, digital signatures with X.509 certificates, SHA-256 hash chains, and TLV QR code data that require automated software. Use a compliant e-invoicing solution instead.

AM

Atif Mehmood

Founder of LookPOS — Building ZATCA-compliant POS and e-invoicing solutions for businesses across Saudi Arabia since 2018.