# BR-65: Add the listID attribute to the item classification code

An item classification code in `cac:CommodityClassification` must name its classification system in `listID`, using a UNTDID 7143 code.

- Layer: EN 16931
- Severity: fatal (the document is invalid)
- Topics: Lines and prices, Code lists
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-65/
- Explanation last updated: 2026-09-24

## The short answer

`BR-65` fails when `cac:CommodityClassification/cbc:ItemClassificationCode` on a line has no `listID` attribute. Add `listID` with the UNTDID 7143 code for the classification the code comes from: `TST` for UNSPSC, `STI` for the EU Common Procurement Vocabulary (CPV) or `HS` for the Harmonised System, for example.

Without the scheme the buyer cannot tell which classification the code belongs to. Choose `listID` by where the code came from, not by which value validates.

## What the rule checks

The rule runs on each `cbc:ItemClassificationCode` under `cac:CommodityClassification` in an invoice or credit note line and tests only that a `listID` attribute exists. An item with several classifications is checked code by code: when tried, a second classification without `listID` was reported at `cac:CommodityClassification[2]` while the first passed.

The attribute value is checked by `BR-CL-13`, not here. When tried, `listID=""` passed this rule and was reported by that one.

`listVersionID` is a separate, optional attribute and does not replace `listID`. A code carrying only `listVersionID` still failed this rule when tried, while `listID="HS"` with `listVersionID="2022"` passed.

`schemeID` is not an alternative either. The classification code is a UBL code type, which has no such attribute, and when tried a `schemeID` in place of `listID` was refused at the XSD layer.

| Term | Meaning | UBL element |
|---|---|---|
| BT-158 | Item classification identifier | `cac:InvoiceLine/cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode (cac:CreditNoteLine/cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode in a credit note)` |
| BT-158 | Item classification identifier: its scheme identifier attribute | `cac:InvoiceLine/cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listID` |
| BT-158 | Item classification identifier: its scheme version attribute | `cac:InvoiceLine/cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listVersionID` |

## How an integration ends up here

Possible causes, from the shape of the rule rather than from measured usage:

- Products carry a classification code in the ERP with no record of which classification it belongs to, and the mapping writes the code alone.
- The scheme is held as a name such as `UNSPSC` or `CPV`, and the attribute is skipped for names that have no entry in the translation table.
- The version of the classification is written to `listVersionID` and the scheme itself is forgotten.
- A buyer asked for a classification code on the invoice and it was added as a fixed value in the template, without the attribute.

## How to fix it

1. Identify the classification system each code was taken from: CPV in public procurement, UNSPSC, the Harmonised System, or another.
2. Look up its code in the UNTDID 7143 list published with the Peppol BIS code lists. `STI` is CPV, `TST` is UNSPSC and `HS` is the Harmonised System; the codes are upper case.
3. Write the code to the `listID` attribute of `cbc:ItemClassificationCode`, and add `listVersionID` if the classification needs a version to be read correctly.
4. If you cannot establish the scheme, leave the classification out. It is optional, and a code with a guessed scheme misleads the buyer.

## Before and after

These are fragments, not complete documents. The complete synthetic documents they come from are linked below.

Fragment of the failing invoice: the classification code has no listID

```xml
<cac:Item>
  <cbc:Name>Example service</cbc:Name>
  <!-- standard identifier omitted from this fragment -->
  <cac:CommodityClassification>
    <cbc:ItemClassificationCode>80111600</cbc:ItemClassificationCode>
  </cac:CommodityClassification>
  <!-- tax category and item attribute omitted from this fragment -->
</cac:Item>
```

Fragment of the corrected invoice: listID TST identifies the code as a UNSPSC code

```xml
<cac:Item>
  <cbc:Name>Example service</cbc:Name>
  <!-- standard identifier omitted from this fragment -->
  <cac:CommodityClassification>
    <cbc:ItemClassificationCode listID="TST">80111600</cbc:ItemClassificationCode>
  </cac:CommodityClassification>
  <!-- tax category and item attribute omitted from this fragment -->
</cac:Item>
```

Only the `listID` attribute differs: missing in the failing invoice, `TST`, the UNTDID 7143 code for UNSPSC, in the corrected one. The failing document reports only `BR-65`, since `BR-CL-13` has no attribute value to look up. On a real invoice the attribute names whichever classification your own code comes from.

### What the validator reported

- The failing invoice reports **BR-65**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-65-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/item-details-valid.xml)

Recorded on phive 12.1.0 / phive-rules-peppol 4.5.6 / Saxon-HE 12.10, the engine behind the free validator, using synthetic data. A recorded result is regression evidence for these documents; it is not a certification.

## Where it applies

- Applies to `cac:InvoiceLine` in an `Invoice` and `cac:CreditNoteLine` in a `CreditNote`. When tried, a credit note whose classification code lost its `listID` reported this rule alone.
- Commodity classification is optional. A line without `cac:CommodityClassification` passes both this rule and `BR-CL-13`.
- The classification code and the item standard identifier use different attributes and lists: `listID` with UNTDID 7143 here, `schemeID` with the ISO 6523 ICD list on `cac:StandardItemIdentification`.

## Related rules

- [BR-CL-13 checks that the listID value is a UNTDID 7143 code](https://ironfang.uk/docs/finance/rules/BR-CL-13.md)
- [BR-64 is the matching attribute check for the item standard identifier](https://ironfang.uk/docs/finance/rules/BR-64.md)
- [BR-CL-21 checks the scheme code of the item standard identifier against the ICD list](https://ironfang.uk/docs/finance/rules/BR-CL-21.md)

## Scope and source

Written for Peppol BIS Billing 3.0.21 (May 2026), EN 16931 1.3.16, as applied to UBL 2.1 Invoice and CreditNote documents. Other profiles, syntaxes and releases can define this identifier differently. Guidance version 2026-09-24.1: source checked 2026-09-24, explanation last updated 2026-09-24.

[The official definition of BR-65](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-65/) carries the normative wording and test. This page is our explanation of it, not a copy.

Guidance does not change the engine verdict. Fixing this finding does not mean the document passes every layer, and validation does not certify legal or tax compliance or transmit a document over Peppol.

## Links

- [This rule as a web page](https://ironfang.uk/docs/finance/rules/BR-65)
- [Free Peppol invoice validator](https://ironfang.uk/tools/peppol-validator)
- [Rule index](https://ironfang.uk/docs/finance/rules.md)
- [Ironfang Finance API docs](https://ironfang.uk/docs/finance)
- The same rule is available to MCP clients as the tool `finance.rule.get` on https://mcp.ironfang.uk/mcp
