Automation MCP Server Features Blog Pricing Contact
Validation rule EN 16931 core

BR-01

Every European e-invoice must say what it claims to be. BR-01 requires the specification identifier (BT-24), the URN that names the profile the document follows, and it fails the moment that declaration is missing or empty.

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.

Frequently asked questions

Which value should I put into BT-24?

The CustomizationID of the profile you actually follow: the XRechnung identifier for German B2G, the Peppol BIS Billing 3.0 identifier for the Peppol network, a Factur-X profile URN for hybrid PDFs, or plain urn:cen.eu:en16931:2017 for a generic core invoice. The reference section on this site documents each of these strings.

Is BR-01 the same as BR-DE-21?

They are neighbours, not twins. BR-01 is the core rule that some specification identifier exists. BR-DE-21 is the German overlay rule that the identifier is specifically the XRechnung one. An invoice can pass BR-01 and still fail BR-DE-21.

Why did my file fail BR-01 when the element is present?

Usually the element is present but empty, contains only whitespace, or sits in the wrong place: in UBL, cbc:CustomizationID must be a direct child of the invoice root; in CII the value belongs in ram:GuidelineSpecifiedDocumentContextParameter/ram:ID inside the ExchangedDocumentContext.

In which layer does BR-01 fire?

In the en16931 core layer. The rule applies to every format and profile: UBL, CII, XRechnung, Peppol BIS, Factur-X and ZUGFeRD all inherit it, so a missing BT-24 fails everywhere.