# BR-CL-22: Use a VATEX code for the VAT exemption reason code

`cbc:TaxExemptionReasonCode` must hold a code from the VATEX list, such as `VATEX-EU-132`. Made-up codes are rejected; send reason text if no code fits.

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

## The short answer

`BR-CL-22` fails when a `cbc:TaxExemptionReasonCode` holds a value that is not in the VATEX code list, and the finding points at that element. Replace the value with the VATEX code for the actual legal basis of the exemption, or remove the code and state the reason in `cbc:TaxExemptionReason` if no code fits.

The recorded example uses `VATEX-EU-EXEMPT`, which follows the pattern of real codes but does not exist.

## What the rule checks

The rule runs on every `cbc:TaxExemptionReasonCode` in the document and looks its value up in the VATEX list the validator carries: the EU article codes such as `VATEX-EU-132` and `VATEX-EU-143-1A`, the category codes `VATEX-EU-AE`, `VATEX-EU-IC`, `VATEX-EU-G` and `VATEX-EU-O`, the margin scheme codes `VATEX-EU-D`, `VATEX-EU-F`, `VATEX-EU-I` and `VATEX-EU-J`, and a set of French `VATEX-FR-` codes.

The value is trimmed and upper-cased before the lookup, so `vatex-eu-132` passed when tried. A space inside the value or a missing prefix fails: `VATEX EU 132` and `132` were both rejected.

An empty element fails this rule, and when tried it also brought `PEPPOL-EN16931-R008`.

A code that fails here still counts as an exemption reason for `BR-E-10`. When tried, `VATEX-EU-EXEMPT` on its own, with no reason text, reported this rule and nothing else.

Only list membership is checked. Whether a listed code suits the category is a Peppol matter, handled by `PEPPOL-EN16931-P0106` and its sibling rules.

| Term | Meaning | UBL element |
|---|---|---|
| BT-121 | VAT exemption reason code | `cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:TaxExemptionReasonCode` |
| BT-120 | VAT exemption reason text | `cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:TaxExemptionReason` |

## How an integration ends up here

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

- The code is assembled from a pattern, `VATEX-EU-` plus a label, instead of being chosen from the list.
- An internal exemption code or a national legal reference is written in the code element, where only VATEX codes are accepted.
- The article number is written without the `VATEX-EU-` prefix.

## How to fix it

1. Find the legal basis for the exemption in your tax determination.
2. Look up the VATEX code for that basis, for example `VATEX-EU-132` for an exemption under Article 132 of the VAT Directive, and write it exactly as listed.
3. If no code matches, drop `cbc:TaxExemptionReasonCode` and state the basis in `cbc:TaxExemptionReason`. An exempt breakdown needs one or the other under `BR-E-10`.
4. When both are sent, put the code before the text. When tried, the code after the text failed the XSD layer.

## 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 exempt breakdown carries an exemption code that is not in the VATEX list

```xml
<cac:TaxSubtotal>
  <cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
  <cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
  <cac:TaxCategory>
    <cbc:ID>E</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cbc:TaxExemptionReasonCode>VATEX-EU-EXEMPT</cbc:TaxExemptionReasonCode>
    <cbc:TaxExemptionReason>Exempt from VAT</cbc:TaxExemptionReason>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:TaxSubtotal>
```

Fragment of the corrected invoice: the invalid code is gone and the reason text remains

```xml
<cac:TaxSubtotal>
  <cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
  <cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
  <cac:TaxCategory>
    <cbc:ID>E</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cbc:TaxExemptionReason>Exempt from VAT</cbc:TaxExemptionReason>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:TaxSubtotal>
```

The failing invoice has `<cbc:TaxExemptionReasonCode>VATEX-EU-EXEMPT</cbc:TaxExemptionReasonCode>` before its reason text; the corrected one has the text alone. The failing document reports only `BR-CL-22`: the text keeps `BR-E-10` satisfied, and no other rule reads an unknown code. The correction shown removes the code, but a real VATEX code in the same place, such as `VATEX-EU-132`, also passed every layer when tried. The text `Exempt from VAT` is generic example wording; a real invoice should name the actual basis.

### What the validator reported

- The failing invoice reports **BR-CL-22**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-CL-22-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/exempt-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 UBL `Invoice` and `CreditNote`. An exempt credit note with `VATEX-EU-EXEMPT` reported this rule alone when tried.
- Reported by the EN 16931 layer. The Peppol layer then checks that the category-specific codes are used with their categories.
- Standard rated and Zero rated breakdowns may not carry an exemption reason at all, valid or not; `BR-S-10` and `BR-Z-10` reject one there.

## Related rules

- [BR-E-10 requires an exemption reason code or text on an exempt breakdown](https://ironfang.uk/docs/finance/rules/BR-E-10.md)
- [PEPPOL-EN16931-P0106 restricts the listed code VATEX-EU-IC to intra-community supply breakdowns](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-P0106.md)
- [BR-S-10 forbids any exemption reason on a Standard rated breakdown](https://ironfang.uk/docs/finance/rules/BR-S-10.md)
- [BR-IC-10 asks for an exemption reason on intra-community supply breakdowns](https://ironfang.uk/docs/finance/rules/BR-IC-10.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-22](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CL-22/) 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-22)
- [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
