The Invoice Counter Value (ICV) is one of the pillars of technical integrity in Phase 2 e-invoicing. It is a sequential integer that increases by one with every invoice issued by the same device, and it is written inside the XML file under the element AdditionalDocumentReference with the identifier ICV. The field looks simple, but it carries a heavy burden: it is what guarantees that the invoice series is linked and consecutive without gaps or repetition, and that no invoice can be deleted from the middle without the tampering being exposed.
Many developers confuse the invoice counter with the commercial Invoice Number, and with the unique identifier UUID. The three are separate fields, each with a completely different role. This technical guide focuses on the invoice counter alone: what it is, where it sits in the XML, how it works with the Previous Invoice Hash (PIH) to build the hash chain, and why it must be strictly sequential at the level of each issuing device (EGS).
The official reference is the Zakat, Tax and Customs Authority (ZATCA) requirements for e-invoicing. In case of any conflict between what is here and the official schema, the Authority’s official schema prevails.
What exactly is the Invoice Counter Value (ICV)?
The invoice counter is a positive whole numeric value that starts from 1 and increases one by one. The first invoice issued by the device has the value 1, the second 2, the third 3, and so on without exception. There are no decimals, no leading zeros, and no spaces. The format is an integer only.
The key word here is “device”. The counter is not computed at the level of the enterprise as a whole, but at the level of the issuing unit (EGS Unit) registered with the Authority. If a store has three cashier devices, each device carries its own counter that starts from 1 and increments independently of the other two. This separation is essential because each device builds an independent hash chain, and two devices cannot share the same counter without breaking the chain.
The purpose of the counter is not commercial numbering for display to the customer. Its purpose is purely regulatory: it proves to the Authority that invoices were issued in a continuous chronological order, and that the device did not skip an invoice or issue two invoices with the same number. Any flaw in the sequence is a sign of possible tampering or a system error, both of which require verification.
Where does the invoice counter sit in the XML file?
The invoice counter lives inside an element cac:AdditionalDocumentReference that carries the identifier cbc:ID with a fixed text value of ICV. The numeric value of the counter is written inside cbc:UUID within the same element. This structure is part of the invoice layout built on the UBL 2.1 standard adopted by the Authority.
Full XML example of the ICV block
In this example, the value 3 inside cbc:UUID means that this is the third invoice issued by the device. Note that the element is named UUID here, yet it does not carry the invoice’s unique identifier UUID. This is a common point of confusion: the element name in the schema is cbc:UUID by virtue of the UBL structure, but its content at the identifier ICV is the numeric counter value, not the hexadecimal UUID string. The invoice’s true unique identifier sits in a completely separate element at the top of the document.
The position of ICV among the other AdditionalDocumentReference blocks
A Phase 2 invoice is not limited to a single ICV block. There are several consecutive AdditionalDocumentReference blocks, each with a different identifier. The usual order places the counter block before the Previous Invoice Hash (PIH) block:
The first block carries the counter value (3), and the second carries the previous invoice hash encoded in Base64. This adjacency is no coincidence: the counter and PIH together define the invoice’s position in the chain. The counter says “I am invoice number 3”, and PIH says “and invoice number 2 had this hash”. Verifying the two together proves the integrity of the sequence.
Inside the AdditionalDocumentReference block
Identifier ID = ICV
The sequential numeric value in cbc:UUID
Increases by one for every invoice
Sits next to the PIH block
How does the invoice counter work with PIH to build the hash chain?
The hash chain is the mechanism that makes any modification to an old invoice detectable. It works on a simple principle: each invoice’s hash depends partly on the hash of the invoice that preceded it. If someone changes the content of an old invoice, its hash changes, so the hash stored in the following invoice breaks, and the entire chain after it collapses.
This is where the counter comes in. The counter determines the order in which the chain is built. Invoice number 3 must point via PIH to the hash of invoice number 2 exactly, not invoice number 1 nor number 4. If the counter is disordered or repeated, the verification system will not know which previous invoice’s hash it should match, and the chain logic collapses.
The relationship between ICV and PIH step by step
To illustrate the sequence, here is what happens when invoice number 3 is issued:
- The device reads the current counter value and increments it by one, making it 3.
- The device retrieves the hash of invoice number 2 stored locally.
- The device writes the hash of invoice number 2 inside the PIH block of invoice number 3.
- The device computes the full hash of invoice number 3, which includes the PIH value among its inputs.
- The hash of invoice number 3 is stored to be used in turn in the PIH of invoice number 4.
In short: the counter numbers the node in the chain, and PIH links the node to its predecessor. Without both together there is no verifiable chain. The details of the hashing mechanism itself and the SHA algorithm used belong to a separate reference from this guide, since here we focus on the role of the counter.
The very first invoice in a device’s life is a special case: its counter is 1, and there is no previous invoice, so an initial PIH value agreed upon by the Authority is written instead of a real hash. From the second invoice onward, the actual linkage to the previous hash begins.
Invoice 1 (ICV=1)
Invoice 2 (ICV=2 + PIH of hash 1)
Invoice 3 (ICV=3 + PIH of hash 2)
Why must the counter be strictly sequential?
Strict sequencing is not a technical preference, but a regulatory requirement. The Authority expects to receive from each device invoices with a continuous counter and no gaps: 1, 2, 3, 4 without jumping to 6. A gap means an invoice was issued and not reported, or was deleted after issuance. Both are violations.
Likewise, the counter must not repeat. Issuing two invoices with the value 3 on the same device breaks the uniqueness of the node in the chain, and makes it impossible to determine which of the two invoices is the correct reference for the next invoice. Repetition is a fatal logical error in building the chain.
Common mistakes that break the counter sequence
- Resetting the counter: Zeroing the counter at the start of every day, month, or year is a mistake. The counter accumulates throughout the device’s lifetime and is never reset.
- Sharing across devices: Using one counter across multiple devices mixes the hash chains. Each device has its own counter.
- Skipping on failure: If issuing an invoice fails, the counter must not jump over the wasted value in a way that leaves a gap with no actual invoice.
- Faulty concurrency: In multi-threaded systems, issuing two invoices in parallel may give them the same counter. Counter generation must be an atomic, sequential operation.
- Restoring from an old backup: Restoring the device state to an earlier point may roll the counter back, causing values to repeat. Restoration requires precise synchronization of the counter state.
A compliant accounting system manages the counter automatically, so the user does not need to track the numbers manually. This is one of the reasons to rely on a certified platform instead of building the integration from scratch.
Let Qoyod manage the invoice counter and the hash chain on your behalf
Qoyod generates the sequential counter value for each device automatically, and builds the Phase 2 compliant hash chain, without you writing a single line of XML or tracking the numbers manually.
How does the invoice counter differ from UUID?
This is the most common developer confusion. The invoice counter and UUID are two radically different fields in form, purpose, and storage location.
The unique identifier UUID is a 36-character string in hexadecimal format such as 3cf5ee9b-1391-4f5c-9a3b-2d1c0e4f9a77, generated randomly and globally unique. It has nothing to do with order: from a UUID value you cannot tell whether the invoice is the first or the hundredth. Its function is the absolute unique identification of the invoice, not the sequence.
The counter, on the other hand, is a small sequential integer from which you directly know the invoice’s rank in the device’s chain. The value 47 means the forty-seventh invoice. The counter is predictable and ordered, while the UUID is random and intentionally unordered.
A direct comparison
| Property | Invoice Counter Value (ICV) | Unique identifier UUID |
|---|---|---|
| Format | Sequential integer (1, 2, 3) | 36-character hexadecimal string |
| Order | Strictly consecutive | Random, no order |
| Scope | Unique at the device level | Globally unique |
| Purpose | Determine the invoice’s rank in the chain | Absolute unique identification of the invoice |
| Position in XML | AdditionalDocumentReference with the identifier ICV | A standalone cbc:UUID element at the top of the document |
| Can it repeat? | Must not repeat on the same device | Must not repeat globally |
The details of UUID generation and its uniqueness rules belong to the separate unique-identifier reference. What matters here is that you distinguish it from the counter, so you do not write a UUID value inside the ICV block by mistake, nor the other way around.
How does the invoice counter differ from the commercial invoice number?
The commercial Invoice Number is the number the customer sees on the printed invoice, such as INV-2026-00045. It sits in the element cbc:ID at the document level, and it follows the commercial enterprise’s rules: it may contain letters, prefixes, a year, or a branch code.
The counter is different: a pure integer, no letters and no symbols, and its purpose is internal and regulatory, not for display. The commercial invoice number may be issued in any format the enterprise chooses, whereas the counter is bound by strict numeric rules that do not accept customization.
| Property | Invoice Counter Value (ICV) | Commercial invoice number |
|---|---|---|
| Content | Integer only | Letters, digits, and symbols allowed |
| Who sets it | The device, automatically | The enterprise, per its policy |
| Visibility to the customer | Usually internal, in the XML | Visible on the invoice |
| Customizability | No customization at all | Customizable |
| Purpose | Chain integrity and regulatory control | Commercial and accounting reference |
The counter and the invoice number may incidentally match in a new enterprise that started its numbering from 1 without prefixes, but this is a superficial match. They are two logically separate fields, and they diverge the moment any prefix is added or the commercial numbering is reset.
The three fields at a glance
| Standard | Invoice Counter Value (ICV) | Unique identifier UUID |
|---|---|---|
| Format | Sequential integer | 128-bit identifier |
| Order | Mandatory sequential | Random unique |
| Purpose | Builds the hash chain | Globally distinguishes the invoice |
The fine details of the ICV block in the official schema
The Authority’s schema imposes specific rules on the counter block; violating them leads to the invoice being rejected at the verification stage. The first rule is that the value of cbc:ID must be the literal text ICV in uppercase with no extra spaces. Any difference in letter case or an added space makes the verification system fail to recognize the block as the counter block.
The second rule is that the value inside cbc:UUID must be a positive integer represented textually without leading zeros. Writing 003 instead of 3 may be accepted by some parsers and rejected by others, so the safest approach is to adhere to a clean numeric representation. Likewise, the value must not be negative, decimal, or non-numeric text.
The third rule concerns the position within the document. The counter block comes within the group of AdditionalDocumentReference blocks that precede the body of the invoice line items. The internal order between the counter block and the PIH block matters: the counter first, then PIH, because the verification logic reads them in that sequence to reconstruct the invoice’s position in the chain.
An example of a first invoice in a device’s life
The first invoice is a special case that deserves a standalone example. Its counter is 1, and its PIH value is a fixed initial value specified by the Authority because there is no previous invoice to hash:
The value encoded in PIH here is not the hash of a real invoice, but the agreed-upon initial value that is used only once for the first invoice. From the second invoice onward, PIH carries the actual previous invoice hash. The common mistake here is that the developer writes an empty or zero hash instead of the correct initial value, so the Authority rejects the first invoice.
The role of the counter in the issuance and integration phases
E-invoicing is divided into two phases. The Generation Phase, which began on 4 December 2021, and the Integration Phase, which began on 1 January 2023 in waves based on the enterprise’s revenue. Technical integrity fields such as the counter, PIH, and the cryptographic stamp belong to Phase 2, the Integration Phase.
In Phase 2, every invoice is sent to the Authority’s Fatoora platform. Tax invoices between businesses (B2B) are subject to instant clearance before being delivered to the buyer, while simplified consumer invoices (B2C) are reported within 24 hours. In both cases, the counter is examined as part of the invoice integrity check.
This makes the counter not just an internal field, but part of what the Authority verifies when it receives the invoice. If a counter arrives outside the device’s expected sequence, it becomes an indicator of a problem in the issuing system, and may delay acceptance of the invoice. Therefore counter generation must be an integral part of the issuance logic, not an extra step that is easy to skip.
A multi-device scenario in a single enterprise
Take a restaurant with three cashier devices, each registered as an independent issuing unit with the Authority. Each device starts its counter from 1 and increments in complete isolation. If the first device issued a hundred invoices, the second fifty, and the third twenty, then the counters would be: the first at 100, the second at 50, the third at 20, with no overlap.
The catastrophic mistake here is for the system to try to unify the counter across the three devices into a single sequential number. This breaks three hash chains at once, because each chain expects an internal sequence for its own device, not a shared sequence. Strict separation between device counters is a condition that admits no leniency.
In practice, a compliant accounting system links each counter to its device identifier and its own cryptographic stamp identifier, so no mixing occurs even if the three devices operate at the same time on the same network.
Practical considerations for developers when implementing the counter
When building an integration with the Fatoora platform, treat the counter as persistent state for the device, not a transient value. Store it in a reliable database, and update it within the same transaction that issues the invoice, so that no invoice is issued without incrementing the counter or vice versa.
In distributed or multi-threaded environments, make counter generation a sequential operation protected by a lock or an atomic counter at the database level. Any race on the value may produce two identical counters, which breaks the chain as we explained.
Keep a clear link between the device identifier (EGS) and the counter value, especially in enterprises with multiple branches and devices. Each device is an independent record with its own counter, and any mixing between records corrupts multiple chains at once.
Finally, treat backup and restore with caution. Restoring an old device state may roll the counter back and generate duplicate values when issuance resumes. Any restore strategy must preserve the last counter value actually issued and resume from it, not from the backup point.
Counter-related verification errors and how to handle them
When an invoice is sent to the Fatoora platform, the counter passes through verification checks. Understanding the common rejection patterns saves the development team hours of tracing. The four most frequent patterns.
The first pattern is rejection due to a duplicate counter. It happens when the device issues two invoices with the same value, usually because of a concurrency race or resending a failed invoice without incrementing the counter. The remedy is to make incrementing the counter part of the atomic issuance transaction, so that no invoice is issued without a unique counter reserved for it beforehand.
The second pattern is rejection due to a gap in the sequence. It happens when the counter jumps from one value to a higher one with no invoices in between, such as jumping from 40 to 43. The remedy is to ensure that every increment of the counter corresponds to an actual invoice issued and stored, and that counter values are not wasted on a transient failure.
The third pattern is rejection due to a mismatch between PIH and the counter. It happens when invoice number 5 points via PIH to a hash that does not belong to invoice number 4. The remedy is to make sure that retrieving the previous invoice hash relies on the last invoice actually issued for the same device, not an invoice from another device or from an old state.
The fourth pattern is rejection of the first invoice due to a wrong initial PIH value. We addressed it above: use the initial value specified by the Authority, not an empty or zero hash.
A quick checklist before sending
- The value of
cbc:IDisICVliterally, with no spaces. - The counter value is a positive integer with no leading zeros.
- The counter is greater by exactly one than the counter of the last invoice on the same device.
- The counter block precedes the PIH block in the document order.
- The PIH hash belongs to the last actual invoice of the device, or the initial value for the first invoice.
- No sharing of the counter between different issuing devices.
Counter storage and the long-term audit trail
Because the counter is never reset throughout the device’s lifetime, its value grows gradually as invoices accumulate. This is natural and expected: a device active for years may reach a counter in the hundreds of thousands. There is no practical upper limit to worry about as long as the representation is a valid integer, since the numeric range accommodates any realistic issuance volume.
From an audit-trail perspective, the counter allows both the Authority and the enterprise to confirm the completeness of the invoice record. If an auditor asks to verify that all of a given device’s invoices exist, it is enough to trace the counter sequence: any value missing between two existing values means a missing invoice that requires an explanation. This property makes the counter an effective auditing tool, not just a technical field.
Therefore the counter must be stored securely within the device record, linked to its corresponding invoice, and must survive backup and restore operations without rolling backward. Any system that loses the last counter value on a restart or restore risks breaking the chain on the first invoice after the incident.
A certified accounting platform handles this persistent storage on behalf of the user, and ensures the counter’s continuity across updates and restarts, so the audit trail remains intact without manual intervention.
How does Qoyod handle the invoice counter?
Qoyod manages the counter value for each issuing device automatically. When each invoice is issued, Qoyod increments the counter by one, writes it in its correct position inside the ICV block in the XML file built on the UBL 2.1 standard, then links it to the previous invoice hash via PIH to build a Phase 2 compliant hash chain.
This means you do not write XML manually nor track the counter numbers yourself. The system takes care of strict sequencing, of separating counters between devices, and of correctly handling the first invoice and the initial PIH value. All of that within an integration certified by the Zakat, Tax and Customs Authority.
For a broader picture of the invoice structure, see the guide The e-invoice XML file and the guide The e-invoice structure. And to understand the aspect related to identity and certification, see the guide The Cryptographic Stamp Identifier (CSID). And for a comprehensive look at the product, browse the page E-invoicing from Qoyod.
Frequently asked questions
Does the invoice counter start from zero or from one?
It starts from 1 for the first invoice issued by the device, then increases by one with every subsequent invoice. There is no invoice with a counter of 0.
Is the counter reset at the beginning of each year?
No. The counter accumulates throughout the issuing device’s lifetime and is never reset, unlike commercial numbering, which the enterprise may choose to reset annually.
Can two devices in the same enterprise use a shared counter?
No. Each issuing device (EGS) carries its own independent counter that starts from 1, because each device builds a separate hash chain.
Where is the counter value written inside the XML?
Inside the element cac:AdditionalDocumentReference whose identifier cbc:ID equals ICV, and the numeric value is placed in cbc:UUID within the same element.
What is the fundamental difference between the counter and UUID?
The counter is a sequential integer that indicates the invoice’s rank, while the UUID is a random 36-character string that is globally unique and does not indicate order. They are two separate fields, and one is not written in place of the other.
What happens if the counter sequence breaks?
A gap or a repetition breaks the hash chain logic and becomes a sign of a system error or possible tampering, which requires verification from the Authority.