NewStripe: a buyer with a NIF always gets a standard invoice, and the simplified threshold is deprecated
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog

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:

ValueRate nameNotes
0ExemptUse together with an exemption_reason (see below)
4Super-reducedBasic food, books, medicines
10ReducedHospitality, transport, most foods
21StandardDefault for goods and services
5TemporaryOnly on operations dated 2022-07-01 to 2024-09-30
2, 7.5TemporaryOnly 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, so send the operation_date of the period. List tax types publishes each rate with its valid_from / valid_until. Each temporary rate has its own surcharge pair (see 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.

The four families

                        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)

Mapping table: BeeL. API value ↔ AEAT code

AEAT codeBeeL exemption_reason valueWhen to use
S1 (default)omit the fieldDefault — subject to IVA, normal seller-collects
S2ISP_ART_84_2_A … ISP_ART_84_2_FISP — buyer self-assesses the IVA (the letter of Art. 84.Uno.2.º LIVA that applies)
N1NO_SUJETA_ART_7_9Not subject by general rules (internal transfers, etc.)
N2NO_SUJETA_LOCALIZACIONOperation localised outside Spain (intra-EU services, services to non-EU)
E1EXENTA_ART_20Educational, medical, social, insurance, residential rental
E2EXENTA_ART_21Exports of goods to non-EU territories
E3EXENTA_ART_22International transport, customs zone operations
E4EXENTA_ART_24Bonded warehouse operations
E5EXENTA_ART_25Intra-EU sales of goods to a business with valid VIES VAT-ID
E6EXENTA_ART_140Investment gold (Art. 140 bis LIVA), usually with regime_key: "04"
E6OTROAny other case not covered above. Requires exemption_reason_text
❌ rejectedEXENTA_ART_26Art. 26 exempts the buyer's intra-EU acquisition, not a supply you invoice — see below
❌ rejectedISP_ART_84_2_GThe law requires these supplies in a special series — see below
❌ rejectedREGIMEN_ART_129 / REGIMEN_ART_135 / REGIMEN_ART_141 / REGIMEN_ART_154 / REGIMEN_ART_163_DECIESRejected by the API — see below

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

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 when you create or update the invoice. Drop the exemption_reason and set the matching main_tax.regime_key instead — see Regime keys.

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, 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. A corrective invoice of an original that already carried one of them keeps it.

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.

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)

{
  "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)

{
  "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)

{
  "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).

Exempt educational service (E1)

{
  "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 BeeL. enforces

RuleWhat happens if you break it
If exemption_reason is set, main_tax.percentage must be 0 and equivalence_surcharge_rate must not be setRejected at issuance
EXENTA_ART_25 (E5) requires the customer to have an alternative_id of type NIF_IVARejected — 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 youRejected — EXEMPTION_INCOMPATIBLE_WITH_REGIME
regime_key: "02" requires EXENTA_ART_21 or EXENTA_ART_22 on the lineRejected — REGIME_REQUIRES_INCOMPATIBLE_EXEMPTION
ISP_* cannot pair with equivalence_surcharge_rateRejected — 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 > 0Rejected — 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_textRejected

Decision tree

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.