What BR-01 checks
BR-01 requires that an invoice carry a specification identifier, BT-24. This is the URN that declares which specification the document claims to follow, and every downstream decision hangs on it: which Schematron overlay a validator loads, which conformance level a hybrid PDF advertises, whether a receiver's intake accepts the file at all. In UBL the value lives in cbc:CustomizationID directly under the root; in CII it is ram:GuidelineSpecifiedDocumentContextParameter/ram:ID inside the document context.
Layer and formats
BR-01 is a core rule, so the finding carries "layer": "en16931" and applies to every format: plain UBL and CII, XRechnung, Peppol BIS, and the XML inside Factur-X / ZUGFeRD hybrids. There is no profile that switches it off, which is what makes a missing BT-24 one of the few failures you can hit identically in every European e-invoicing scenario.
Why it fails in practice
- Hand-built XML without a template. The serializer maps the business data faithfully and nobody knew a profile declaration was required.
- An empty placeholder survives. The element exists in the template as
<cbc:CustomizationID/>, waiting for a value that is never set. - The identifier is placed at the wrong path. Especially in CII, the value ends up outside
ExchangedDocumentContext, where no rule can see it.
How to fix it
Declare the profile the document actually follows, for example a generic EN 16931 core invoice in UBL:
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
In an InvoiceXML create request the field is invoice.specificationId, and in the normal case you never set it: each /v1/create/* endpoint stamps the identifier matching the requested format and profile, in the currently valid version.
The raw rejection vs the InvoiceXML finding
Raw Schematron output states the rule and an XPath:
<svrl:failed-assert id="BR-01" flag="fatal"
location="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]">
<svrl:text>[BR-01]-An Invoice shall have a Specification
identifier (BT-24).</svrl:text>
</svrl:failed-assert>
The InvoiceXML validators return the same failure as an actionable finding:
{
"rule": "BR-01",
"layer": "en16931",
"line": null,
"message": "An invoice must have a specification identifier. Add the profile identifier to the document header.",
"btCodes": ["BT-24"],
"fields": ["specificationId"],
"raw": "[BR-01] EN16931: An Invoice shall have a Specification identifier (BT-24)."
}
No decoding of rule codes, no rephrasing standardese for your end customers: the message is display-ready, fields maps the finding to the exact request field, and the stable rule key lets clients localize by code when they want their own copy.
Check or generate compliant documents
Validate any UBL or CII file in the UBL validator or the XRechnung validator. When you generate through POST /v1/create/ubl or POST /v1/create/facturx, BR-01 cannot fail: the correct identifier is stamped server-side. For the bigger picture of the core rules, read EN 16931 explained.
Related rules and identifiers
- urn:cen.eu:en16931:2017, the identifier a generic core invoice declares
- BR-DE-21, the German rule that BT-24 must specifically be the XRechnung identifier
- The XRechnung CustomizationID and the Peppol BIS CustomizationID, the two most common BT-24 values
- BR-16, the sibling core rule requiring at least one invoice line