A Number That Is Not Your Own: What a Document Series Actually Is
Sequential invoice numbering is the most universally implemented feature in business software and one of the least examined. We went looking at our own, because a jurisdiction we were writing about treats a document series as a legal object, and found something we would rather publish than sit on.
Nobody asks a vendor whether its invoice numbers go up. They obviously go up. It is the sort of requirement that gets a tick in the first column of an evaluation and no further thought, and the tick is usually deserved — the numbers do go up, they do not repeat, and the finance team can find any document by its reference. Then you read a rule written by somebody who has thought about this harder than either of you, and you notice that "goes up" was doing an enormous amount of unexamined work.
The rule that prompted this was Portuguese, and we will come back to it, but the question underneath is not about any one country. It is this: is the sequence on your invoices actually yours? Most people would answer yes without pausing, because the question sounds like it cannot mean anything else. It can, and we found out that on our own product the answer is no.
A number, a sequence, and a series are three different things
A number is an identifier on a document. Any string that is not already in use will do, and a great deal of software stops here — a reference that is unique, findable, and otherwise meaningless.
A sequence adds an order. Documents are numbered in the order they were created, so the reference tells you something about when the document was raised relative to its neighbours. This is what most systems implement and most buyers imagine when they see the tick.
A series is a stronger claim than either, and it is the one that carries legal weight in a number of jurisdictions. A series is declared in advance, belongs to one issuer, and runs unbroken. The unbroken part is the whole point: if the documents in a series run from one to four hundred and seventeen with nothing missing, then the absence of a document is visible, and the presence of one that was later removed is visible too. A series is an audit control that happens to look like a numbering scheme. That is why authorities that care about it want the series registered before it is used rather than described afterwards.
A sequence tells you what order things happened in. A series tells you whether anything is missing. Only one of those is a control, and almost every implementation ships the other one.
Three ways software does this, and what each one breaks
It is worth knowing which of these you are buying, because from the outside they are indistinguishable — all three produce tidy ascending references.
| How the next number is worked out | What it costs you |
|---|---|
| Take the highest existing number and add one | Two people saving at the same moment can be handed the same number, and the loser of that race either fails or overwrites. Deleting a document leaves a gap that reappears as a duplicate later, because the highest number went down. |
| Build it from the date and time, or from a random reference | No gaps, because there is no sequence. Also no order, no completeness check, and nothing that could ever satisfy a rule about an unbroken series. |
| Keep a counter in its own row and lock it while it moves | The right shape. Two people cannot be handed the same number, and a deleted document does not pull the counter back. This is what we do, and it is where the interesting part starts. |
What we found in our own code
Our sales documents draw their reference from a counter held per organization and per year, locked while it moves. By the table above that is the good answer, and we would have said so confidently a week ago. The number takes the shape of a prefix, the year and a zero-padded position — the shape a series would take if it were one.
The part we had not looked at closely is what happens next. Before returning a number, the counter is compared against the highest number already in use for that document type, and the larger of the two is taken. That is a sensible safeguard on its face: it stops the counter falling behind records that arrived some other way. For most document types the comparison is made within one organization, which is exactly right.
For five document types it is not
Sales invoices, credit notes, purchase orders and point-of-sale sales and returns are flagged in our own code as globally unique, and for those the comparison scans every organization on the deployment rather than one. This is not an oversight in the numbering — it is the numbering accommodating the database, where the invoice reference carries a unique index across the whole table instead of a composite one paired with the organization. The consequence follows directly: two organizations on one deployment draw from a single ascending number space for those document types. Your counter is your own; the number you are handed is the larger of your counter and everybody else's highest. So your sequence is not private to you, and it is not guaranteed to be unbroken.
We should be exact about what we are claiming, because there is a version of this paragraph that overstates it. This is a fact about the code and the database schema, both of which anyone can read. It is not a report of gaps observed in a customer ledger — our own local database had a single organization in it when this was written, so no jump was witnessed, and inventing one would be precisely the kind of thing this blog exists not to do. What we are saying is that the mechanism that produces the jump is present by construction, and that nothing in the product would explain the jump to the person looking at it.
That last clause is the part that bothers us most. A missing number in a finance ledger is not a cosmetic irregularity; it is a question. Somebody eventually asks where document four hundred and twelve went, and the honest answer — another organization on the same platform took it — is both true and impossible to arrive at from inside the product.
Why a jurisdiction makes this concrete
In most markets this sits somewhere between a tidiness problem and a credibility problem: your records are complete, and they do not look complete, and explaining that costs you an afternoon in an audit. In a jurisdiction that treats the series as a registered object, it stops being a matter of appearance. If the series is declared to the authority in advance and each document carries a code built from that declaration and its own place in the sequence, then the place in the sequence is not decoration. It is part of the document's identity, and a system that cannot promise the sequence belongs to one issuer cannot produce that identity honestly.
Portugal is the example we happened to be working on — the authority there issues a code for each registered series and documents carry a unique code built from it — and it is not the only jurisdiction where completeness of a document series is a live obligation rather than a preference. Which of them applies to any particular business is a question for that business's accountant, and this post is not answering it. The point is narrower and it holds everywhere: a control that only works if the sequence is private to you is not a control if the sequence is shared.
Four questions worth asking, and almost nobody asks the second
How is the next document number worked out?
What a good answer sounds like
A counter in its own record, locked while it moves. The engineer answering will know immediately.
What a bad answer is telling you
If the answer is "we take the highest and add one", ask what happens when two people save at once. If it is a timestamp, there is no sequence at all and no completeness check is possible.
Is my sequence private to my company, or shared with your other customers?
What a good answer sounds like
Private, with the uniqueness enforced per company rather than across the database. Ours is not, for five document types, and we would rather you heard it here.
What a bad answer is telling you
Hesitation here usually means nobody has looked. It is a five-minute check in the schema and the answer determines whether your numbers can skip for reasons outside your business.
Can I run more than one series at a time, and can I declare them in advance?
What a good answer sounds like
Yes, with a name per series and the ability to register them before use. Ours runs one per document type per year.
What a bad answer is telling you
One counter per document type is very common and is not the same as a series you declared. In markets that register series, the difference is the whole requirement.
What happens to the sequence when a document is deleted?
What a good answer sounds like
Deletion is not possible; corrections run through cancellation or a credit note, and the number stays spent. That is our behaviour and it is the behaviour to want.
What a bad answer is telling you
If documents can be deleted and the counter follows, you have a system that can be made to forget, and no numbering scheme on top of it means anything.
What we would build, and where we stop on purpose
Making the sequence genuinely private to each organization is a schema change and a narrow one — a composite uniqueness constraint paired with the organization rather than a global one, and the comparison scoped to match. We would treat that as a correction rather than a feature, which is a distinction we try to be honest about: features get quoted, corrections get fixed. Multiple named series that can be declared in advance is the next piece and is a genuine build. Beyond that sits the market-specific work — registering a series with an authority and carrying the code it returns — which we would scope and price like anything else.
Where we stop is worth naming too, because a post about record integrity invites a claim we are not going to make. Our product refuses to delete an issued invoice, and corrections run through cancellation or a credit note. That is true, it is checkable in ten minutes, and it is a weaker property than the non-alterability that certification requirements test for. We have never been assessed against those requirements by anybody, and we are not going to describe ourselves as meeting them on the strength of a deletion guard.
What AWRA OpsHub does today
- A counter in its own record, locked while it moves, held per organization and per year. No two saves can be handed the same number, and a cancelled document does not pull the counter back.
- A reference shaped like a series — prefix, year and zero-padded position — rather than a timestamp or a random string.
- Refusal to delete an issued invoice. Corrections go through cancellation or a credit note, which is the behaviour a reviewer expects and a surprisingly uncommon default.
What it does not do
- A sequence that is private to your organization, for sales invoices, credit notes, purchase orders and point-of-sale documents. The counter is yours; the comparison behind it is not, because the reference carries a unique index across the whole table. This is a defect and we would treat it as a correction rather than a feature.
- More than one series per document type, and no way to declare a series in advance or name it.
- Registration of a series with any tax authority, and no code returned from one on any document.
- Any assessed claim of non-alterable records. Deletion is refused; that is the only record-integrity property we will assert.
Not ours, by choice
- We will not describe our records as non-alterable in the sense certification requirements mean. Those requirements test properties we have never been assessed against, and a vendor asserting the outcome without an assessment behind it is telling you something they do not know.
- We will not tell you whether a series obligation applies to your business. It turns on where you are established and how you are required to issue documents, and that determination belongs to your accountant.
The private-sequence fix is small, well understood and ours to carry rather than yours to fund — a composite uniqueness constraint and a scoped comparison. Named series declarable in advance is a real build and a modest one, and it is the prerequisite for every market-specific version of this, so it is the right thing to do first if a jurisdiction is driving the requirement. Registration against a particular authority is the piece we would scope and price separately, on the usual terms: a written specification, a timeline and a price agreed before anything starts, and no dates on a public page. The precedent that we finish work of this kind is Kenya, where a live authority integration puts a receipt number, a signature and a machine-readable code on the document today.
Worth stating plainly: we found this by auditing our own code against another country's rules, not because a customer reported it, and nobody would have noticed it from inside the product. That is the actual argument for reading obligations from markets you are not in — they ask questions about your system that your own market never thought to ask.
What is not built for Portugal today can still be built for you
Anything described above as not built is a statement about what ships in the standard product today — not a limit on what AWRA OpsHub can do in Portugal. Kenya's eTIMS integration and its maintained payroll engine exist because Kenyan clients needed them and commissioned them; neither appeared by itself. The same door is open here. If the engineering behind a certification submission, scoped honestly, a bank or mobile money feed, a statutory return format, a rule your own operation needs that the standard one does not have, or a link to a system you already run is what stands between you and a decision, tell us and we will scope it as a build — written spec, timeline and price — before you commit to anything.
Three builds we would quote, and one thing we would not pretend to schedule
Start with the work that is specified and portable. Put both tax identification numbers and the customer's address on the printed document — all three are stored today and none of them prints. Make the document counter genuinely private to each organization, because for sales invoices, credit notes, purchase orders and point-of-sale documents it is currently reconciled against a number unique across the whole platform, so a sequence can skip for reasons that have nothing to do with the business reading it; that one we would treat as a correction rather than a feature. Then a ledger export that carries documents, lines, customers, products and tax codes, instead of the seven header columns the invoice export emits today. All three improve every European market in the product rather than only this one. The Portuguese-specific engineering is a separate and larger piece — document series registered with the authority in advance, the unique document code that comes back, the authority's own QR payload rendered on the document, the prescribed export schema, and the record-integrity properties the requirements test for — and we would scope and price it like any other build. What we would not do is put a date on the certification itself. That is granted by the Portuguese tax authority against its own requirements, and finishing the engineering is the beginning of an application rather than the end of one. Every other paragraph in this section of the site ends with terms we would agree with you; this one ends by saying which part is not ours to agree.
Banks and payments
SEPA credit transfers and direct debits, Multibanco references and bank statement feeds wired into the Payments Register, so money in and out reconciles against the documents that authorised it rather than being re-keyed from a bank screen.
The operational work, which is what most commissions actually are
An extra approval stage in a chain that does not match the standard one, a custom field set on employees or assets that only your sector needs, an expiry that has to block an order rather than send an email, a report your board asks for in a shape nothing produces, or a scanner or weighbridge feeding the goods-in door. These are the commissions we are asked for most often and the smallest ones we quote — and unlike a revenue-authority pipeline, none of them waits on a regulator.
Payroll and statutory returns
A Portuguese payroll engine with statutory withholding and social security contributions computed on live employee records, and the monthly schedules produced in the layout the filing body expects. None of it exists today; labour cost attribution to projects and cost centres does.
Systems you already run
The accounting package, CRM, online store or custom database you intend to keep — connected through our API so a fact is entered once and appears everywhere it is needed.
How it works: you describe the requirement, we return a written scope, timeline and cost, and once agreed it is built into your environment and maintained as part of the product. No roadmap slide, and no pretending in a demo that something exists when it does not.
Tell us what you need integratedThe one-line version
Ask your vendor whether the sequence on your invoices is private to your company. It is a five-minute check in their schema, almost nobody asks it, and the answer decides whether a missing number in your ledger is a question you can answer.
Where this came from
We found this auditing our own code against the Portuguese obligations, which treat a document series as something you register rather than something you choose. That page sets out all four of those obligations against what we actually do.
Read the Portugal page