# BR-CL-19: Use an allowance reason code from the UNTDID 5189 list

An allowance reason code must be one of the UNTDID 5189 codes permitted in Peppol, such as 95 for Discount. A word such as DISCOUNT is not a code.

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

## The short answer

`BR-CL-19` fails when `cbc:AllowanceChargeReasonCode` on an allowance (`cbc:ChargeIndicator` of `false`) is not one of the 19 codes in the UNTDID 5189 subset: 41, 42, 60, 62 to 68, 70, 71, 88, 95, 100 and 102 to 105. Replace the value with the code that describes the allowance, or remove the code and describe the allowance in `cbc:AllowanceChargeReason`.

The Peppol layer repeats the check as `PEPPOL-EN16931-CL002`, so an unknown code fails both layers. A plain discount is `95`; the recorded example had the word `DISCOUNT` in its place.

## What the rule checks

Every `cbc:AllowanceChargeReasonCode` inside a `cac:AllowanceCharge` that reads as an allowance is checked, wherever it sits: at document level, on a line, and, when tried, inside `cac:Price` as well.

Leading and trailing whitespace is ignored, and the remaining value must equal a listed code exactly. When tried, ` 95 ` with spaces around it passed.

Only the allowance list counts. A charge code such as `CG`, valid on a charge, was rejected on the document allowance when tried.

The permitted set is a Peppol subset of UNTDID 5189, so a code that exists in the full UNTDID list but not in the subset still fails.

An empty code element matches nothing and fails, together with `PEPPOL-EN16931-R008` for the empty element.

The text beside the code is free and is not compared with it. When tried, code `95` next to the text `Freight` was accepted, because `BR-CO-05`, the agreement check, always passes in this release.

| Term | Meaning | UBL element |
|---|---|---|
| BT-98 | Document level allowance reason code | `cac:AllowanceCharge/cbc:AllowanceChargeReasonCode` |
| BT-140 | Invoice line allowance reason code | `cac:InvoiceLine/cac:AllowanceCharge/cbc:AllowanceChargeReasonCode (cac:CreditNoteLine in a credit note)` |

## How an integration ends up here

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

- The integration writes its own discount type name, such as `DISCOUNT` or `PROMO`, into the code element instead of a UNTDID code.
- A charge code is reused for an allowance, or allowance and charge codes share one lookup table.
- The code comes from an internal numbering that also uses numbers, so a value such as `1` or `10` looks plausible but is not on the list.
- A code is added to every allowance, including ones whose source has no reason type, and a placeholder fills the gap.

## How to fix it

1. Read the finding location to see which allowance holds the code: one under the root, one on a line, or the price discount.
2. Decide what the allowance is from its source record and find the matching entry in the UNTDID 5189 subset that Peppol publishes for BIS Billing 3.0. `95` is Discount and `100` is Special rebate.
3. Write that code in `cbc:AllowanceChargeReasonCode`. Keep your own label, if you want it on the document, in `cbc:AllowanceChargeReason`.
4. If no code fits, remove `cbc:AllowanceChargeReasonCode` and keep the text. An allowance with text alone is valid; one with neither fails `BR-CO-21` or `BR-CO-23`.
5. Keep the mapping from your discount types to UNTDID codes as a table in the integration, separate from the charge mapping.

## 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 document allowance has the word DISCOUNT as its reason code

```xml
<cac:AllowanceCharge>
  <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>DISCOUNT</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document discount</cbc:AllowanceChargeReason>
  <cbc:Amount currencyID="GBP">1.00</cbc:Amount>
  <!-- tax category omitted from this fragment -->
</cac:AllowanceCharge>
```

Fragment of the corrected invoice: the reason code is 95, Discount

```xml
<cac:AllowanceCharge>
  <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document discount</cbc:AllowanceChargeReason>
  <cbc:Amount currencyID="GBP">1.00</cbc:Amount>
  <!-- tax category omitted from this fragment -->
</cac:AllowanceCharge>
```

The failing invoice has `DISCOUNT` in the document allowance reason code; the corrected one has `95`, the UNTDID 5189 code for Discount. The failing document also reports `PEPPOL-EN16931-CL002`, the Peppol copy of this code list check, at the same element, and the one correction clears both findings. The reason text is identical in the two documents.

### What the validator reported

- The failing invoice reports **BR-CL-19** and `PEPPOL-EN16931-CL002`. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-CL-19-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/invoice-rich.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 `Invoice` and `CreditNote`, and to allowances on `cac:InvoiceLine` and `cac:CreditNoteLine`. When tried, `DISCOUNT` on the line allowance, and on the document allowance of a credit note, reported this rule and `PEPPOL-EN16931-CL002` together.
- A reason code on the price discount inside `cac:Price` is checked too, but even a valid one there drew the warnings `UBL-CR-633` and `UBL-CR-669` when tried. A price discount is better sent without a code.
- Charges use a different list, UNTDID 7161, which `BR-CL-20` checks. Which list applies follows `cbc:ChargeIndicator`.

## Related rules

- [BR-CL-20 is the code list check for charge reason codes](https://ironfang.uk/docs/finance/rules/BR-CL-20.md)
- [BR-CO-21 requires a document-level allowance to have a reason code or text in the first place](https://ironfang.uk/docs/finance/rules/BR-CO-21.md)
- [BR-CO-23 requires the same of allowances on a line](https://ironfang.uk/docs/finance/rules/BR-CO-23.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-CL-19](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CL-19/) 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-CL-19)
- [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
