# Tax classification per line

Set `exemption_reason` on each line correctly, with the full mapping from BeeL. API values to AEAT codes (S1/S2/N1/N2/E1–E6).

Every line carries an optional `exemption_reason` that tells AEAT how the operation is classified for IVA purposes. The BeeL. API uses **descriptive enum values** (`EXENTA_ART_25`, `NO_SUJETA_LOCALIZACION`, `ISP_ART_84_2_A`, etc.); BeeL. translates those to the AEAT codes (E5, N2, S2) before submission.

If you leave `exemption_reason` unset, BeeL. classifies the line as **subject and not exempt** (*sujeta y no exenta*, S1) with the IVA rate you set in `main_tax.percentage`.

## Allowed `main_tax.percentage` values

`main_tax.percentage` is a plain number (0–100) cross-validated against `main_tax.type`. For `type: "IVA"` the rates in play are:

| Value | Rate name | Notes |
|---|---|---|
| `0` | Exempt | Use together with an `exemption_reason` (see below) |
| `4` | Super-reduced | Basic food, books, medicines |
| `10` | Reduced | Hospitality, transport, most foods |
| `21` | Standard | Default for goods and services |
| `5` | Temporary | Only on operations dated 2022-07-01 to 2024-09-30 |
| `2`, `7.5` | Temporary | Only on operations dated 2024-10-01 to 2024-12-31 |

The rates accepted on any date are 4, 10 or 21. The temporary ones no longer apply to new operations, but they stay accepted for corrective invoices and late-filed invoices of their period. The date judged is the invoice's `operation_date`, or the issue date when there is none: a temporary rate outside its period is rejected with `422` [`VAT_RATE_NOT_ACCEPTED_ON_DATE`](/errors/VAT_RATE_NOT_ACCEPTED_ON_DATE), so send the `operation_date` of the period. [List tax types](/tax-configuration/listTaxTypes) publishes each rate with its `valid_from` / `valid_until`. Each temporary rate has its own surcharge pair (see [Equivalence surcharge](/verifactu/equivalence-surcharge)). For IGIC/IPSI lines, use `main_tax.type: "IGIC"` (0, 3, 5, 7, 9.5, 15 or 20) or `"IPSI"` (0.5, 1, 2, 4, 8 or 10) — each type is validated against its own set of rates.

> **Rules that apply here:** [TAX-001 · Apply the VAT rate in force when the operation took place](/rules/taxes#tax-001) · [TAX-014 · Only the VAT rates AEAT accepts on the operation date](/rules/taxes#tax-014)

## The four families

```text
                        Operation is …
                              │
        ┌─────────────────────┼─────────────────────┐
   subject to IVA       not subject to IVA      exempt from IVA
   (sujeta)             (no sujeta)             (exenta)
        │                     │                     │
   ┌────┴────┐                │                     │
  S1        S2               N1 or N2          E1, E2, E3, E4, E5, E6
 normal    ISP              (location /        (legal exemption)
                            general rules)
```

> **Rules that apply here:** [CNT-001 · Every operation of the business is invoiced, exempt ones included](/rules/contents#cnt-001)

## Mapping table: BeeL. API value ↔ AEAT code

| AEAT code | BeeL `exemption_reason` value | When to use |
|---|---|---|
| **S1** (default) | *omit the field* | Default — subject to IVA, normal seller-collects |
| **S2** | `ISP_ART_84_2_A` … `ISP_ART_84_2_F` | ISP — buyer self-assesses the IVA (the letter of Art. 84.Uno.2.º LIVA that applies) |
| **N1** | `NO_SUJETA_ART_7_9` | Not subject by general rules (internal transfers, etc.) |
| **N2** | `NO_SUJETA_LOCALIZACION` | Operation localised outside Spain (intra-EU services, services to non-EU) |
| **E1** | `EXENTA_ART_20` | Educational, medical, social, insurance, residential rental |
| **E2** | `EXENTA_ART_21` | Exports of goods to non-EU territories |
| **E3** | `EXENTA_ART_22` | International transport, customs zone operations |
| **E4** | `EXENTA_ART_24` | Bonded warehouse operations |
| **E5** | `EXENTA_ART_25` | Intra-EU sales of goods to a business with valid VIES VAT-ID |
| **E6** | `EXENTA_ART_140` | Investment gold (Art. 140 bis LIVA), usually with `regime_key: "04"` |
| **E6** | `OTRO` | Any other case not covered above. Requires `exemption_reason_text` |
| ❌ rejected | `EXENTA_ART_26` | Art. 26 exempts the buyer's intra-EU acquisition, not a supply you invoice — see below |
| ❌ rejected | `ISP_ART_84_2_G` | The law requires these supplies in a special series — see below |
| ❌ rejected | `REGIMEN_ART_129` / `REGIMEN_ART_135` / `REGIMEN_ART_141` / `REGIMEN_ART_154` / `REGIMEN_ART_163_DECIES` | Rejected by the API — see below |

Only `EXENTA_ART_140` and `OTRO` map to **E6**; `ISP_*` maps to S2 and `NO_SUJETA_*` to N1/N2.

<Callout type="warn">
  **Special-regime values are rejected, not reported as E6.** The `REGIMEN_ART_*` values describe special regimes (agriculture compensation, used goods, travel agencies, equivalence surcharge, cash basis), not exemptions under arts. 20–26 LIVA, and AEAT models them with the regime key rather than as an exempt operation. A line carrying one of them is rejected — whether or not the NIF is under VeriFactu — with [`EXEMPTION_REGIME_NOT_SUPPORTED_IN_VERIFACTU`](/errors/EXEMPTION_REGIME_NOT_SUPPORTED_IN_VERIFACTU) when you create or update the invoice. Drop the `exemption_reason` and set the matching `main_tax.regime_key` instead — see [Regime keys](/verifactu/regime-keys).
</Callout>

<Callout type="warn">
  **Two values of the enum are rejected on an invoice line.** `EXENTA_ART_26` exempts the *acquisition* the buyer declares, not a supply the seller invoices: a line carrying it answers `422` [`EXEMPTION_NOT_FOR_ISSUED_INVOICE`](/errors/EXEMPTION_NOT_FOR_ISSUED_INVOICE), and a supply of goods to another Member State is `EXENTA_ART_25`. `ISP_ART_84_2_G` (silver, platinum, palladium, mobile phones, consoles, laptops and tablets) must be invoiced in a special series the API does not have: `422` [`REVERSE_CHARGE_CASE_NOT_SUPPORTED`](/errors/REVERSE_CHARGE_CASE_NOT_SUPPORTED). A corrective invoice of an original that already carried one of them keeps it.
</Callout>

<Callout type="info">
  When in doubt between `NO_SUJETA_LOCALIZACION` (N2) and `EXENTA_ART_25` (E5) for intra-EU operations, the rule is simple: **goods → E5**, **services → N2**. See [International customers](/verifactu/international-customers).
</Callout>

> **Rules that apply here:** [CNT-010 · An exempt operation states why it is exempt](/rules/contents#cnt-010)

## How you set it in the API

The `exemption_reason` lives **directly on each line**. There's also an optional `exemption_reason_text` to add free-text context.

### B2B intra-EU services (N2)

```json
{
  "lines": [
    {
      "description": "Consulting services to EU business",
      "quantity": 1,
      "unit": "service",
      "unit_price": 1000,
      "discount_percentage": 0,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "NO_SUJETA_LOCALIZACION",
      "exemption_reason_text": "Operation not subject to Spanish VAT under Art. 69 LIVA"
    }
  ]
}
```

### B2B intra-EU goods (E5)

```json
{
  "lines": [
    {
      "description": "Hardware supply to EU customer",
      "quantity": 1,
      "unit": "unit",
      "unit_price": 1000,
      "discount_percentage": 0,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "EXENTA_ART_25"
    }
  ]
}
```

### Reverse charge (*inversión del sujeto pasivo*, S2) [#inversión-del-sujeto-pasivo-s2]

```json
{
  "lines": [
    {
      "description": "Construction services subject to reverse charge",
      "quantity": 1,
      "unit": "project",
      "unit_price": 1000,
      "discount_percentage": 0,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "ISP_ART_84_2_F"
    }
  ]
}
```

Pick the letter of Art. 84.Uno.2.º LIVA that applies: `_A` (supplier not established in Spain), `_B` (unwrought or semi-finished gold), `_C` (scrap, waste and recovery materials), `_D` (greenhouse gas emission allowances), `_E` (certain real estate supplies) or `_F` (construction or renovation works). `_G` is rejected (see above).

> **Rules that apply here:** [CNT-012 · A reverse-charge invoice carries the mention «inversión del sujeto pasivo»](/rules/contents#cnt-012) · [TAX-002 · Reverse-charge operations are invoiced without charging VAT](/rules/taxes#tax-002)

### Exempt educational service (E1)

```json
{
  "lines": [
    {
      "description": "Training course",
      "quantity": 1,
      "unit": "course",
      "unit_price": 500,
      "discount_percentage": 0,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "EXENTA_ART_20"
    }
  ]
}
```

> **Rules that apply here:** [CNT-010 · An exempt operation states why it is exempt](/rules/contents#cnt-010)

## Rules BeeL. enforces

| Rule | What happens if you break it |
|---|---|
| If `exemption_reason` is set, `main_tax.percentage` must be `0` and `equivalence_surcharge_rate` must not be set | Rejected at issuance |
| `EXENTA_ART_25` (E5) requires the customer to have an `alternative_id` of type `NIF_IVA` | Rejected — E5 is reserved for intra-EU B2B with VAT-ID |
| `EXENTA_ART_21` (E2) and `EXENTA_ART_22` (E3) cannot use `regime_key: "01"` — exports go under `"02"`, which BeeL. doesn't set for you | Rejected — [`EXEMPTION_INCOMPATIBLE_WITH_REGIME`](/errors/EXEMPTION_INCOMPATIBLE_WITH_REGIME) |
| `regime_key: "02"` requires `EXENTA_ART_21` or `EXENTA_ART_22` on the line | Rejected — [`REGIME_REQUIRES_INCOMPATIBLE_EXEMPTION`](/errors/REGIME_REQUIRES_INCOMPATIBLE_EXEMPTION) |
| `ISP_*` cannot pair with `equivalence_surcharge_rate` | Rejected — [`ISP_INCOMPATIBLE_WITH_SURCHARGE`](/errors/ISP_INCOMPATIBLE_WITH_SURCHARGE): the buyer self-assesses the VAT in their own regime, so the Spanish retail surcharge doesn't apply |
| Default (no `exemption_reason`) requires `main_tax.percentage > 0` | Rejected — [`EXEMPT_ZERO_RATE_REQUIRES_REASON`](/errors/EXEMPT_ZERO_RATE_REQUIRES_REASON): a 0 % line must declare one of `EXENTA_ART_20..25`, `EXENTA_ART_140`, `NO_SUJETA_ART_7_9`, `NO_SUJETA_LOCALIZACION`, `ISP_ART_84_2_*` or `OTRO` |
| `OTRO` requires a free-text `exemption_reason_text` | Rejected |

> **Rules that apply here:** [TAX-003 · Reverse-charge lines carry no tax and never go on a simplified invoice](/rules/taxes#tax-003) · [TAX-005 · Exempt and non-subject lines carry no VAT rate](/rules/taxes#tax-005)

## Decision tree

```text
Where is the customer?
├─ In Spain
│  ├─ Operation is subject to IVA?
│  │  ├─ Yes, normal seller-collects-IVA  →  omit exemption_reason (S1)
│  │  ├─ Yes, ISP applies                 →  ISP_ART_84_2_A … _F (S2)
│  │  └─ Yes, but exempted by law         →  EXENTA_ART_20 ... 24, EXENTA_ART_140 (E1–E4, E6)
│  └─ Not subject (out-of-scope op)       →  NO_SUJETA_ART_7_9 (N1)
│
├─ EU country (intra-community)
│  ├─ Customer is B2B with VIES VAT-ID
│  │  ├─ Selling goods                    →  EXENTA_ART_25 (E5)
│  │  └─ Selling services                 →  NO_SUJETA_LOCALIZACION (N2)
│  └─ Customer is B2C (no VIES)
│     ├─ Under 10 000 € OSS threshold     →  omit (S1) — apply Spanish IVA
│     └─ Over OSS threshold               →  main_tax.regime_key="17" + destination rate (no exemption_reason)
│
└─ Non-EU
   ├─ Selling goods (export)              →  EXENTA_ART_21 + main_tax.regime_key="02"
   └─ Selling services                    →  NO_SUJETA_LOCALIZACION
```

The full payload examples for each path live in [International customers](/verifactu/international-customers).

> **Rules that apply here:** [TAX-018 · An issued invoice does not use the intra-EU acquisition exemption](/rules/taxes#tax-018)

## Related

<Related>

- [International customers](/verifactu/international-customers) — every B2B/B2C scenario in full
- [Regime keys](/verifactu/regime-keys) — when `main_tax.regime_key` is required alongside the classification
- [Equivalence surcharge](/verifactu/equivalence-surcharge) — incompatible with ISP and exempt lines
- [Create an invoice](/invoices/createCompanyInvoice) — full line schema

</Related>

---

Full OpenAPI spec: https://docs.beel.es/api/openapi