AttestwireRule referenceBR-02

BR-02 An invoice must have an invoice number

noun · EN 16931 · fatal · BT-1

an invoice with no number is a note, not an invoice.

Your invoice was refused because it has no invoice number. Every invoice needs one, and this is a one-field fix: put the number your accounting system shows for this document in the invoice number field and send it again. In the standard that field is number 1, written BT-1, and BR-02 is the rule that checks it.

Business term
BT-1 — Invoice number
Severity
fatal
Applies to
All profiles

The fix

Use the invoice number your accounting system displays on the document, the one your customer will quote when they call about it, and pass it as invoiceNumber. Do not pass the database primary key behind it. If you build the number from a sequence, format it once at the point of issue and store the formatted value, so that a reissue of the same document cannot produce a different number.

What the rule requires

The invoice must carry an identifier, and that identifier must be unique within your own numbering. Beyond that the standard is relaxed about the format: it is a plain string, with no length, pattern or “must be an integer” requirement. 2026-000142, INV/2026/08/17 and a1b2c3 all satisfy business term BT-1.

Our input check fires when invoiceNumber is missing, empty, or only whitespace. It cannot check uniqueness, because it only ever sees one invoice at a time. That part stays with you.

An Invoice shall have an Invoice number (BT-1).

BR-02 — EN 16931-1 business rules, as published in the Peppol BIS Billing 3.0 rule tables

Failing and passing

Fails — invoiceNumber is blank
validateInput({
  profile: "en16931",
  invoiceNumber: "",          // <- BR-02
  issueDate: "2026-08-09",
  currency: "EUR",
  seller: { /* ... */ },
  buyer:  { /* ... */ },
  lines:  [ /* ... */ ],
});
// -> { valid: false, errors: [ { rule: "BR-02", ... } ] }
Passes
validateInput({
  profile: "en16931",
  invoiceNumber: "2026-000142",
  issueDate: "2026-08-09",
  currency: "EUR",
  seller: { /* ... */ },
  buyer:  { /* ... */ },
  lines:  [ /* ... */ ],
});
// -> { valid: true, errors: [] }

Why it exists

Every system that handles the invoice later refers to it by this number: the buyer’s accounts-payable matching, a credit note that references this document six months from now, your audit trail, the tax authority’s reconciliation. EN 16931 itself only asks that the number is there.

National VAT law generally goes further and wants the number sequential and gap-free within a series, which is why the library’s fix line says “sequential” and tells you to cancel with a credit note rather than reuse a number.

What the library returns

The full error returned by @attestwire/en16931. It includes the rule ID, affected field and suggested correction. Developers can use this object in their application:

TeachingError
{
  "rule": "BR-02",
  "field": "BT-1",
  "severity": "fatal",
  "message": "An invoice must have an invoice number (BT-1). It is the identifier the buyer, your accounts-receivable ledger and the tax authority all use to refer to this one document, so it must be unique within your numbering sequence.",
  "fix": "Set invoiceNumber to your next sequential invoice identifier. Do not reuse a number, even for a document you later cancel — issue a credit note instead.",
  "example": "\"invoiceNumber\": \"2026-000142\"",
  "xpath": "/ubl:Invoice/cbc:ID",
  "docsUrl": "https://attestwire.com/rules/BR-02"
}

xpath is always a UBL path. On a CII invoice, look for the matching CII field instead.

How our check differs

The uniqueness and “do not reuse” advice in our fix is not part of BR-02. EN 16931 asserts presence only. Sequential, gap-free numbering comes from national VAT law instead (for example §14 UStG in Germany, or art. 242 of the VAT Directive as implemented locally).

We put it in the fix because a developer reading the rule alone will build something that fails an audit later. For the legal requirement itself, refer to your own jurisdiction.

See also: BR-01 — the specification identifier; older builds of this library used this id for a missing invoice number.