An invoice that conforms perfectly to EN 16931 can be rejected in a way that reads, to the person receiving the rejection, like nonsense: the field the receiver is complaining about is optional in the standard, and they left it out because it is optional.
Both parties are right. The receiver is validating against a profile, and profiles are where the European standard stops being one thing.
What a profile does
A core invoice usage specification is a published restriction of the standard for a particular context. Three operations are available to it, and only three:
- Make optional mandatory. The standard permits a buyer reference; a profile requires it.
- Forbid what the standard permits. The standard allows a delivery address; a profile excludes it.
- Narrow a code list or a value range. The standard permits any code from a list; a profile permits four of them.
What a profile cannot do is add. If a profile appears to add a field, it is either using an element of the standard in a specific way, or it is not a profile — it is a profile plus an extension.
That restriction is the reason the whole arrangement works. A receiver that can process the standard can process any conforming profile of it, because a profile only ever produces documents that are already valid against the standard. The converse is not true, which is exactly the asymmetry that surprises people.
The specification identifier
Every conforming document carries an identifier saying which specification it claims to follow. It is a small element and it does a large job: it tells the receiver which rule set to run.
Two failure modes are worth knowing.
The wrong identifier. The document declares one profile and is built to another. Validation then applies rules the document was never designed to satisfy, and the resulting error list is long, confusing and unrelated to the actual problem.
A default identifier. A system that emits the same identifier for every document, regardless of destination, will pass in the country it was configured for and fail elsewhere. This is common in first implementations and is one of the more satisfying bugs to find, because the fix is a single field.
The specification identifier. Before the mapping, before the code lists, before the totals. It is the cheapest thing to verify and it explains a surprising share of cross-border rejections.
Layered profiles
In practice more than one profile applies at once. A document exchanged over a European network into a country with a national profile has to satisfy both: the network's specification and the national restrictions.
| Layer | Set by | Typical restriction |
|---|---|---|
| European standard | The standard itself | Totals must reconcile; VAT breakdown must be complete |
| Network profile | The network's governing body | A defined identifier scheme; mandatory buyer reference |
| National profile | A national body or tax administration | National identifiers; mandatory payment terms |
| Receiver rules | The buying organisation | Purchase order reference; approved cost centre |
The union of those restrictions is the target. Building to the European standard alone, and expecting the layers above to be forgiving, is how a pilot that worked becomes a rollout that does not. The full picture is in testing against a real validation stack.
Extensions, and why to avoid them
An extension carries information the core model has no term for: a sector-specific product classification, a complex rebate structure, a logistics reference nobody outside your industry uses.
Extensions are legitimate, and they are the correct answer when the information genuinely does not fit. They also have a property that makes them a poor default: a conforming receiver is not obliged to understand them. Anything you put in an extension may be silently ignored by the party you sent it to, and you will not be told.
Three consequences follow.
- Never put commercially essential information in an extension unless you have a bilateral agreement that the receiver reads it. A payment condition in an extension is a payment condition that does not exist.
- Extensions do not convert. If you also produce the other syntax, or if a provider converts on your behalf, extension content is where conversion loses things.
- Extensions complicate archiving. The instance you keep must be the instance you sent, extensions and all, which rules out storing a normalised core-only version for convenience. See archiving a structured invoice.
Before reaching for an extension, check whether the standard already has a term that fits. It has more of them than most implementations use, and the exercise of reading through the model looking for a home for a piece of data is the fastest way to learn what is in it. The mechanics are in business terms and business groups.
How to work with profiles rather than against them
Treat each profile as a target with a test suite. Not a variant of a shared target. Each has its own mandatory elements, its own code list restrictions and its own rules.
Keep a matrix. Which profiles you must satisfy, which of your document shapes each has been tested with, and when. Nobody keeps this by accident and everybody needs it at the second country.
Read the release notes. Profiles are versioned and they change, typically once or twice a year. A version that was mandatory becomes deprecated and then unacceptable, and the transition window is not generous. This is an operational subscription, not a project task, and it belongs with whoever owns exception handling.
Do not build a profile of your own. If you are a large buyer, the temptation to publish your own restrictions is strong and the cost falls on your suppliers, several of whom will simply keep sending PDFs and dare you to reject them. Where you genuinely need extra data, ask for it in an element the standard already provides.