# Examples cookbook

Runnable curl + JSON for every common VeriFactu scenario, mapped to BeeL's public API.

Every scenario below maps a real AEAT case to the exact JSON BeeL's public API expects. Field names and enum values come straight from the OpenAPI spec — copy, change the recipient, and ship. For the *why* behind each combination, follow the cross-links into the concept pages.

<Callout type="info">
  All examples target `https://app.beel.es/api/v1/companies/{company_id}/invoices` and assume your account has VeriFactu enabled. Sandbox keys (`beel_sk_test_*`) submit to AEAT pre-production and don't consume quota.

  None of them send an issue date: BeeL. sets `issue_date` to the day the invoice is actually issued, when its billing record is generated. To record an operation that happened earlier, send `operation_date` (today or a past date). To issue on a future date, create a draft and use `PUT /v1/companies/{company_id}/invoices/{invoice_id}/schedule`.
</Callout>

## Quick reference

| Scenario | `type` | `exemption_reason` | `regime_key` | Surcharge | Recipient |
|---|---|---|---|---|---|
| [F2 simplified — under the cap, no recipient](#f2-simplified--under-the-cap-no-recipient) | `SIMPLIFIED` | — | `"01"` | — | omitted |
| [F1 standard — Spanish B2B](#f1-standard--spanish-business-customer) | `STANDARD` | — | `"01"` | — | NIF + address |
| [F1 multiple VAT rates](#f1-with-multiple-vat-rates-per-line) | `STANDARD` | — | `"01"` | — | NIF + address |
| [F1 with IRPF](#f1-with-irpf-withholding) | `STANDARD` | — | `"01"` | — | NIF + address |
| [F1 equivalence surcharge](#f1-with-recargo-de-equivalencia) | `STANDARD` | — | `"18"` | `5.2` | NIF + address |
| [F1 intra-EU B2B goods (E5)](#f1-intra-eu-b2b--goods-e5) | `STANDARD` | `EXENTA_ART_25` | `"01"` | — | `NIF_IVA` |
| [F1 intra-EU B2B services (N2)](#f1-intra-eu-b2b--services-n2) | `STANDARD` | `NO_SUJETA_LOCALIZACION` | `"01"` | — | `NIF_IVA` |
| [F1 B2C OSS over threshold](#f1-intra-eu-b2c--oss-over-threshold) | `STANDARD` | — (regime key alone → N2) | `"17"` | — | `PASSPORT` |
| [F1 B2C under threshold](#f1-intra-eu-b2c--under-oss-threshold) | `STANDARD` | — | `"01"` | — | `PASSPORT` |
| [F1 export non-EU (E2)](#f1-export-of-goods-to-non-eu-e2) | `STANDARD` | `EXENTA_ART_21` | `"02"` | — | `PASSPORT` |
| [F1 services non-EU (N2)](#f1-services-to-non-eu-n2) | `STANDARD` | `NO_SUJETA_LOCALIZACION` | `"01"` | — | `PASSPORT` |
| [F1 exempt E1 (medical/edu)](#f1-exempt-operation-e1--educationalmedical) | `STANDARD` | `EXENTA_ART_20` | `"01"` | — | NIF + address |
| [F1 IGIC (Canary Islands)](#f1-with-igic-canary-islands) | `STANDARD` | — | `"01"` | — | NIF + address |
| [F1 not subject (N1)](#f1-not-subject-n1) | `STANDARD` | `NO_SUJETA_ART_7_9` | `"01"` | — | NIF + address |
| [F1 ISP — reverse charge (S2)](#f1-isp--reverse-charge-s2) | `STANDARD` | `ISP_ART_84_2_F` | `"01"` | — | NIF + address |
| [F1 REBU (used goods)](#f1-rebu-used-goods-art-antiques) | not accepted | — | `"03"` | — | — |
| [R1 corrective — partial](#r1-corrective--partial-by-differences) | (corrective) | — | `"01"` | — | inherited |
| [R5 corrective — return on F2](#r5-corrective--return-on-simplified-f2) | (corrective) | — | `"01"` | — | none, like the F2 |
| [Voiding](#voiding-anulación) | n/a | — | — | — | n/a |

The first row of every table is the canonical pattern; everything below it is a variation. Read [Tax classification per line](/verifactu/tax-classification) for the full enum of `exemption_reason` codes and how they map to AEAT's S1/S2/N1/N2/E1–E6 four-family taxonomy.

## F2 simplified — under the cap, no recipient

The bread-and-butter ticket invoice. Use `SIMPLIFIED` when the total stays under 3,000 €, the customer is a consumer, and you don't identify them. A `SIMPLIFIED` invoice with a `nif` or `alternative_id` in `recipient` is rejected ([`SIMPLIFIED_INVOICE_FORBIDS_IDENTIFIED_RECIPIENT`](/errors/SIMPLIFIED_INVOICE_FORBIDS_IDENTIFIED_RECIPIENT)) — identify the customer and it is an F1. Pass `recipient: {}` — the field itself is required, but every property inside it is optional for `SIMPLIFIED`, and BeeL. fills *consumidor final* automatically.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "SIMPLIFIED",
    "recipient": {},
    "lines": [
      {
        "description": "Menú del día",
        "quantity": 2,
        "unit": "unit",
        "unit_price": 14.50,
        "main_tax": { "type": "IVA", "percentage": 10, "regime_key": "01" }
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "SIMPLIFIED",
  "recipient": {},
  "lines": [
    {
      "description": "Menú del día",
      "quantity": 2,
      "unit": "unit",
      "unit_price": 14.50,
      "main_tax": { "type": "IVA", "percentage": 10, "regime_key": "01" }
    }
  ],
  "options": { "issue_directly": true }
}
```

See [Simplified vs standard](/verifactu/simplified-vs-standard) for the 3,000 € cap, the 400 € limit that is your responsibility, and why BeeL. always issues an identified customer's invoice as an F1.

## F1 standard — Spanish business customer

The default B2B invoice between two Spanish entities. The recipient needs a Spanish NIF, which BeeL. checks against the AEAT census together with the name.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 4a7d1ed4-9bc9-4f7e-b1e9-7c2a5f9b8d11" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "ACCIONA SA",
      "nif": "A08001851",
      "address": {
        "street": "Avenida de Europa",
        "number": "18",
        "postal_code": "28108",
        "city": "Alcobendas",
        "province": "Madrid",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Consultoría de arquitectura — Sprint mayo",
        "quantity": 40,
        "unit": "hours",
        "unit_price": 75.00,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
      }
    ],
    "payment_info": {
      "method": "BANK_TRANSFER",
      "iban": "ES9121000418450200051332",
      "payment_term_days": 30
    },
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "ACCIONA SA",
    "nif": "A08001851",
    "address": {
      "street": "Avenida de Europa",
      "number": "18",
      "postal_code": "28108",
      "city": "Alcobendas",
      "province": "Madrid",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Consultoría de arquitectura — Sprint mayo",
      "quantity": 40,
      "unit": "hours",
      "unit_price": 75.00,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
    }
  ],
  "payment_info": {
    "method": "BANK_TRANSFER",
    "iban": "ES9121000418450200051332",
    "payment_term_days": 30
  },
  "options": { "issue_directly": true }
}
```

The `Idempotency-Key` header is optional but recommended for any `issue_directly: true` call — retrying with the same UUID returns the original response instead of duplicating the record.

## F1 with multiple VAT rates per line

One invoice can mix any combination of the [allowed VAT percentages](/verifactu/tax-classification#allowed-main_taxpercentage-values) (`0`, `4`, `5`, `10`, `21`). BeeL. builds the `vat_breakdown` automatically by grouping lines per rate.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "ACCIONA SA",
      "nif": "A08001851",
      "address": {
        "street": "Calle Cava Baja",
        "number": "35",
        "postal_code": "28005",
        "city": "Madrid",
        "province": "Madrid",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Vino reserva (caja 6 botellas)",
        "quantity": 4,
        "unit": "box",
        "unit_price": 90.00,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
      },
      {
        "description": "Servicio de catering — menú degustación",
        "quantity": 25,
        "unit": "menu",
        "unit_price": 32.00,
        "main_tax": { "type": "IVA", "percentage": 10, "regime_key": "01" }
      },
      {
        "description": "Pan artesano",
        "quantity": 50,
        "unit": "unit",
        "unit_price": 1.20,
        "main_tax": { "type": "IVA", "percentage": 4, "regime_key": "01" }
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "ACCIONA SA",
    "nif": "A08001851",
    "address": {
      "street": "Calle Cava Baja",
      "number": "35",
      "postal_code": "28005",
      "city": "Madrid",
      "province": "Madrid",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Vino reserva (caja 6 botellas)",
      "quantity": 4,
      "unit": "box",
      "unit_price": 90.00,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
    },
    {
      "description": "Servicio de catering — menú degustación",
      "quantity": 25,
      "unit": "menu",
      "unit_price": 32.00,
      "main_tax": { "type": "IVA", "percentage": 10, "regime_key": "01" }
    },
    {
      "description": "Pan artesano",
      "quantity": 50,
      "unit": "unit",
      "unit_price": 1.20,
      "main_tax": { "type": "IVA", "percentage": 4, "regime_key": "01" }
    }
  ],
  "options": { "issue_directly": true }
}
```

**What changes vs. the previous example:** three lines instead of one, each with a different `main_tax.percentage`. The response `totals.vat_breakdown` carries three entries (`21`, `10`, `4`).

## F1 with IRPF withholding

Professionals subject to IRPF retention add `irpf_rate` to the line. The accepted values are `0`, `1`, `2`, `2.8`, `6`, `7`, `7.6`, `9.5`, `15`, `19` or `24` (`IrpfPercentage` enum) — for general professional activity it's almost always `15` (or `7` during the first three years of activity). The issuer here is an individual professional: a company issuer only bears `0`, `19`, `24` and `9.5`, and any other rate is rejected with `422` [`IRPF_RATE_NOT_FOR_CORPORATE_ISSUER`](/errors/IRPF_RATE_NOT_FOR_CORPORATE_ISSUER) (see [Amounts and rounding](/guides/amounts-and-rounding#irpf)).

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "ACCIONA SA",
      "nif": "A08001851",
      "address": {
        "street": "Avenida de Europa",
        "number": "18",
        "postal_code": "28108",
        "city": "Alcobendas",
        "province": "Madrid",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Servicios de abogacía — asesoramiento mercantil",
        "quantity": 12,
        "unit": "hours",
        "unit_price": 120.00,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" },
        "irpf_rate": 15
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "ACCIONA SA",
    "nif": "A08001851",
    "address": {
      "street": "Avenida de Europa",
      "number": "18",
      "postal_code": "28108",
      "city": "Alcobendas",
      "province": "Madrid",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Servicios de abogacía — asesoramiento mercantil",
      "quantity": 12,
      "unit": "hours",
      "unit_price": 120.00,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" },
      "irpf_rate": 15
    }
  ],
  "options": { "issue_directly": true }
}
```

<Callout type="warn">
  BeeL. **never** accepts IRPF on `SIMPLIFIED` invoices: a simplified invoice issued through BeeL. does not identify its recipient, and a withholding is made by an identified payer. If your customer withholds, issue an F1. See [Simplified vs standard](/verifactu/simplified-vs-standard).
</Callout>

## F1 with equivalence surcharge [#f1-with-recargo-de-equivalencia]

For retailers that have declared themselves subject to the regime, add `equivalence_surcharge_rate` to each line and set `main_tax.regime_key: "18"`.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "ACCIONA SA",
      "nif": "A08001851",
      "address": {
        "street": "Calle del Comercio",
        "number": "56",
        "postal_code": "08001",
        "city": "Barcelona",
        "province": "Barcelona",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Lote de auriculares inalámbricos para reventa",
        "quantity": 30,
        "unit": "unit",
        "unit_price": 45.00,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "18" },
        "equivalence_surcharge_rate": 5.2
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "ACCIONA SA",
    "nif": "A08001851",
    "address": {
      "street": "Calle del Comercio",
      "number": "56",
      "postal_code": "08001",
      "city": "Barcelona",
      "province": "Barcelona",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Lote de auriculares inalámbricos para reventa",
      "quantity": 30,
      "unit": "unit",
      "unit_price": 45.00,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "18" },
      "equivalence_surcharge_rate": 5.2
    }
  ],
  "options": { "issue_directly": true }
}
```

<Callout type="info">
  The IVA-RE pairs are strict: `4 ↔ 0.5`, `10 ↔ 1.4`, `21 ↔ 5.2` (and `21 ↔ 1.75` for tobacco); the temporary rates have their own pairs, accepted only on operations of their period. Pass `0` to disable the surcharge on a specific line. See [Equivalence surcharge](/verifactu/equivalence-surcharge) for the full table.
</Callout>

## F1 intra-EU B2B — goods (E5)

EU-to-EU sales of goods between two businesses with valid VIES VAT-IDs are **exempt under Art. 25 LIVA**. The buyer self-assesses the IVA in their country. BeeL. checks that the German VAT-ID has the `DE` structure; whether it is active in VIES is for you to check before invoicing — see [International customers](/verifactu/international-customers#identifying-foreign-customers).

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Berliner Industrie GmbH",
      "alternative_id": {
        "type": "NIF_IVA",
        "number": "DE123456789",
        "country_code": "DE"
      },
      "address": {
        "street": "Friedrichstraße",
        "number": "200",
        "postal_code": "10117",
        "city": "Berlin",
        "province": "Berlin",
        "country": "Alemania",
        "country_code": "DE"
      }
    },
    "lines": [
      {
        "description": "Componentes electrónicos — pedido EU-2026-0042",
        "quantity": 500,
        "unit": "unit",
        "unit_price": 8.40,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
        "exemption_reason": "EXENTA_ART_25"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Berliner Industrie GmbH",
    "alternative_id": {
      "type": "NIF_IVA",
      "number": "DE123456789",
      "country_code": "DE"
    },
    "address": {
      "street": "Friedrichstraße",
      "number": "200",
      "postal_code": "10117",
      "city": "Berlin",
      "province": "Berlin",
      "country": "Alemania",
      "country_code": "DE"
    }
  },
  "lines": [
    {
      "description": "Componentes electrónicos — pedido EU-2026-0042",
      "quantity": 500,
      "unit": "unit",
      "unit_price": 8.40,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "EXENTA_ART_25"
    }
  ],
  "options": { "issue_directly": true }
}
```

**What changes vs. the previous example:** recipient uses `alternative_id.type: "NIF_IVA"` (VIES VAT-ID) instead of `nif`; line carries `main_tax.percentage: 0` and `exemption_reason: "EXENTA_ART_25"`. See [International customers > B2B intra-EU goods](/verifactu/international-customers#b2b-intra-eu--goods-e5).

## F1 intra-EU B2B — services (N2)

Same German customer, but selling **services** instead of goods. Services to an EU business are **not subject by place of supply** (*no sujetas por localización*, Art. 69 LIVA): the place of supply is the buyer's country, so the operation is outside the scope of Spanish IVA.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Berliner Industrie GmbH",
      "alternative_id": {
        "type": "NIF_IVA",
        "number": "DE123456789",
        "country_code": "DE"
      },
      "address": {
        "street": "Friedrichstraße",
        "number": "200",
        "postal_code": "10117",
        "city": "Berlin",
        "province": "Berlin",
        "country": "Alemania",
        "country_code": "DE"
      }
    },
    "lines": [
      {
        "description": "Consultoría de arquitectura cloud",
        "quantity": 60,
        "unit": "hours",
        "unit_price": 110.00,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
        "exemption_reason": "NO_SUJETA_LOCALIZACION"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Berliner Industrie GmbH",
    "alternative_id": {
      "type": "NIF_IVA",
      "number": "DE123456789",
      "country_code": "DE"
    },
    "address": {
      "street": "Friedrichstraße",
      "number": "200",
      "postal_code": "10117",
      "city": "Berlin",
      "province": "Berlin",
      "country": "Alemania",
      "country_code": "DE"
    }
  },
  "lines": [
    {
      "description": "Consultoría de arquitectura cloud",
      "quantity": 60,
      "unit": "hours",
      "unit_price": 110.00,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "NO_SUJETA_LOCALIZACION"
    }
  ],
  "options": { "issue_directly": true }
}
```

**What changes vs. the previous example:** `exemption_reason` flips from `EXENTA_ART_25` (E5, goods) to `NO_SUJETA_LOCALIZACION` (N2, services). The recipient block is identical — the bienes-vs-servicios distinction is per-line, not per-customer.

## F1 intra-EU B2C — OSS over threshold

Once your annual cross-border B2C sales to EU consumers exceed 10,000 € you must apply destination-country IVA via the One-Stop-Shop (OSS) and file Modelo 369. The line carries `regime_key: "17"` and the **destination country's rate** — 19 % for Germany below. The regime key widens the accepted rates beyond the Spanish menu, and it alone classifies the line as N2, so the line takes **no `exemption_reason`**: adding one would force the rate to 0 % and drop the destination IVA from the breakdown.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Anna Schmidt",
      "alternative_id": {
        "type": "PASSPORT",
        "number": "C0HJ4P9DT",
        "country_code": "DE"
      },
      "address": {
        "street": "Müllerstraße",
        "number": "47",
        "postal_code": "80469",
        "city": "München",
        "province": "Bayern",
        "country": "Alemania",
        "country_code": "DE"
      }
    },
    "lines": [
      {
        "description": "Suscripción anual plataforma SaaS",
        "quantity": 1,
        "unit": "year",
        "unit_price": 480.00,
        "main_tax": { "type": "IVA", "percentage": 19, "regime_key": "17" }
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Anna Schmidt",
    "alternative_id": {
      "type": "PASSPORT",
      "number": "C0HJ4P9DT",
      "country_code": "DE"
    },
    "address": {
      "street": "Müllerstraße",
      "number": "47",
      "postal_code": "80469",
      "city": "München",
      "province": "Bayern",
      "country": "Alemania",
      "country_code": "DE"
    }
  },
  "lines": [
    {
      "description": "Suscripción anual plataforma SaaS",
      "quantity": 1,
      "unit": "year",
      "unit_price": 480.00,
      "main_tax": { "type": "IVA", "percentage": 19, "regime_key": "17" }
    }
  ],
  "options": { "issue_directly": true }
}
```

The 10,000 € threshold is an **annual aggregate across all EU countries** — not per-country, not per-customer. Once you cross it (or opt in voluntarily) every cross-border B2C sale is OSS until year-end.

## F1 intra-EU B2C — under OSS threshold

Below the threshold (and not opted in), cross-border B2C sales are billed with **Spanish IVA** as if the consumer were Spanish. No `exemption_reason`, default `regime_key: "01"`, normal rate.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Anna Schmidt",
      "alternative_id": {
        "type": "PASSPORT",
        "number": "C0HJ4P9DT",
        "country_code": "DE"
      },
      "address": {
        "street": "Müllerstraße",
        "number": "47",
        "postal_code": "80469",
        "city": "München",
        "province": "Bayern",
        "country": "Alemania",
        "country_code": "DE"
      }
    },
    "lines": [
      {
        "description": "Curso online — fotografía digital",
        "quantity": 1,
        "unit": "course",
        "unit_price": 149.00,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Anna Schmidt",
    "alternative_id": {
      "type": "PASSPORT",
      "number": "C0HJ4P9DT",
      "country_code": "DE"
    },
    "address": {
      "street": "Müllerstraße",
      "number": "47",
      "postal_code": "80469",
      "city": "München",
      "province": "Bayern",
      "country": "Alemania",
      "country_code": "DE"
    }
  },
  "lines": [
    {
      "description": "Curso online — fotografía digital",
      "quantity": 1,
      "unit": "course",
      "unit_price": 149.00,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
    }
  ],
  "options": { "issue_directly": true }
}
```

**What changes vs. the previous example:** same German individual, but `regime_key` drops back to `"01"`, `exemption_reason` is removed, and `percentage` becomes the standard Spanish `21`. The 10,000 €/year aggregate decides which of the two shapes to use; track it externally.

## F1 export of goods to non-EU (E2)

Goods leaving the EU are **exempt under Art. 21 LIVA**. The line needs `exemption_reason: EXENTA_ART_21`, `regime_key: "02"` (Export), and `percentage: 0`. The customer's `alternative_id.type` will typically be `PASSPORT` for individuals or `OTHER_DOCUMENT` for foreign businesses.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Northeast Imports Inc.",
      "alternative_id": {
        "type": "PASSPORT",
        "number": "551234567",
        "country_code": "US"
      },
      "address": {
        "street": "5th Avenue",
        "number": "725",
        "postal_code": "10022",
        "city": "New York",
        "province": "NY",
        "country": "Estados Unidos",
        "country_code": "US"
      }
    },
    "lines": [
      {
        "description": "Aceite de oliva virgen extra — palet 480 botellas",
        "quantity": 1,
        "unit": "pallet",
        "unit_price": 3850.00,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "02" },
        "exemption_reason": "EXENTA_ART_21"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Northeast Imports Inc.",
    "alternative_id": {
      "type": "PASSPORT",
      "number": "551234567",
      "country_code": "US"
    },
    "address": {
      "street": "5th Avenue",
      "number": "725",
      "postal_code": "10022",
      "city": "New York",
      "province": "NY",
      "country": "Estados Unidos",
      "country_code": "US"
    }
  },
  "lines": [
    {
      "description": "Aceite de oliva virgen extra — palet 480 botellas",
      "quantity": 1,
      "unit": "pallet",
      "unit_price": 3850.00,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "02" },
      "exemption_reason": "EXENTA_ART_21"
    }
  ],
  "options": { "issue_directly": true }
}
```

See [International customers > Exports of goods](/verifactu/international-customers#exports-of-goods-non-eu) for the documentary evidence (DUA / customs declaration) you should keep alongside the invoice.

## F1 services to non-EU (N2)

Services to a customer outside the EU are **not subject by place of supply** — same N2 family as intra-EU B2B services. The recipient is non-EU but the line shape is identical to the EU service case.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Northeast Imports Inc.",
      "alternative_id": {
        "type": "PASSPORT",
        "number": "551234567",
        "country_code": "US"
      },
      "address": {
        "street": "5th Avenue",
        "number": "725",
        "postal_code": "10022",
        "city": "New York",
        "province": "NY",
        "country": "Estados Unidos",
        "country_code": "US"
      }
    },
    "lines": [
      {
        "description": "Diseño de identidad de marca",
        "quantity": 1,
        "unit": "project",
        "unit_price": 6500.00,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
        "exemption_reason": "NO_SUJETA_LOCALIZACION"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Northeast Imports Inc.",
    "alternative_id": {
      "type": "PASSPORT",
      "number": "551234567",
      "country_code": "US"
    },
    "address": {
      "street": "5th Avenue",
      "number": "725",
      "postal_code": "10022",
      "city": "New York",
      "province": "NY",
      "country": "Estados Unidos",
      "country_code": "US"
    }
  },
  "lines": [
    {
      "description": "Diseño de identidad de marca",
      "quantity": 1,
      "unit": "project",
      "unit_price": 6500.00,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "NO_SUJETA_LOCALIZACION"
    }
  ],
  "options": { "issue_directly": true }
}
```

**What changes vs. the previous example:** `exemption_reason` flips from `EXENTA_ART_21` (E2, goods) to `NO_SUJETA_LOCALIZACION` (N2, services); `regime_key` drops from `"02"` (Export) back to the default `"01"`.

## F1 exempt operation (E1) — educational/medical

Operations exempt under Art. 20 LIVA (education, medical, social, insurance, residential rental). Set `exemption_reason: EXENTA_ART_20`, `percentage: 0`, and use `exemption_reason_text` to record the specific subparagraph.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Academia Cervantes SL",
      "nif": "A08001851",
      "address": {
        "street": "Calle Princesa",
        "number": "27",
        "postal_code": "28008",
        "city": "Madrid",
        "province": "Madrid",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Clases particulares de matemáticas — trimestre primavera",
        "quantity": 36,
        "unit": "hours",
        "unit_price": 28.00,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
        "exemption_reason": "EXENTA_ART_20",
        "exemption_reason_text": "Operación exenta de IVA según Art. 20.Uno.10º LIVA (enseñanza)"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Academia Cervantes SL",
    "nif": "A08001851",
    "address": {
      "street": "Calle Princesa",
      "number": "27",
      "postal_code": "28008",
      "city": "Madrid",
      "province": "Madrid",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Clases particulares de matemáticas — trimestre primavera",
      "quantity": 36,
      "unit": "hours",
      "unit_price": 28.00,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "EXENTA_ART_20",
      "exemption_reason_text": "Operación exenta de IVA según Art. 20.Uno.10º LIVA (enseñanza)"
    }
  ],
  "options": { "issue_directly": true }
}
```

`exemption_reason_text` is free-text (max 500 chars). It's shown on the PDF and persisted on the VeriFactu record, but doesn't change AEAT classification.

## F1 with IGIC (Canary Islands)

Canary Islands operations use IGIC instead of IVA. Switch `main_tax.type` to `"IGIC"` and pick a valid IGIC rate (`0`, `3`, `5`, `7`, `9.5`, `15`, `20`).

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Importaciones Atlántico SL",
      "nif": "A08001851",
      "address": {
        "street": "Calle León y Castillo",
        "number": "200",
        "postal_code": "35004",
        "city": "Las Palmas de Gran Canaria",
        "province": "Las Palmas",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Mobiliario de oficina — sillas ergonómicas",
        "quantity": 10,
        "unit": "unit",
        "unit_price": 180.00,
        "main_tax": { "type": "IGIC", "percentage": 7, "regime_key": "01" }
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Importaciones Atlántico SL",
    "nif": "A08001851",
    "address": {
      "street": "Calle León y Castillo",
      "number": "200",
      "postal_code": "35004",
      "city": "Las Palmas de Gran Canaria",
      "province": "Las Palmas",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Mobiliario de oficina — sillas ergonómicas",
      "quantity": 10,
      "unit": "unit",
      "unit_price": 180.00,
      "main_tax": { "type": "IGIC", "percentage": 7, "regime_key": "01" }
    }
  ],
  "options": { "issue_directly": true }
}
```

IPSI (Ceuta and Melilla) works identically: `main_tax.type: "IPSI"` with one of its rates (`0.5`, `1`, `2`, `4`, `8`, `10`). See [Territorial taxes](/verifactu/territorial-taxes) for the full picture.

## F1 not subject (N1)

Operations *not subject* to IVA under the general rules of Art. 7 LIVA — internal transfers between branches, samples for promotion, out-of-scope operations. Use `exemption_reason: NO_SUJETA_ART_7_9` and `percentage: 0`.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Distribuciones Hermanas Pérez SL",
      "nif": "A08001851",
      "address": {
        "street": "Polígono Industrial San Isidro",
        "number": "12",
        "postal_code": "46980",
        "city": "Paterna",
        "province": "Valencia",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Muestras comerciales sin valor — catálogo 2026",
        "quantity": 50,
        "unit": "unit",
        "unit_price": 12.00,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
        "exemption_reason": "NO_SUJETA_ART_7_9",
        "exemption_reason_text": "Entrega de muestras gratuitas (Art. 7.4º LIVA)"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Distribuciones Hermanas Pérez SL",
    "nif": "A08001851",
    "address": {
      "street": "Polígono Industrial San Isidro",
      "number": "12",
      "postal_code": "46980",
      "city": "Paterna",
      "province": "Valencia",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Muestras comerciales sin valor — catálogo 2026",
      "quantity": 50,
      "unit": "unit",
      "unit_price": 12.00,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "NO_SUJETA_ART_7_9",
      "exemption_reason_text": "Entrega de muestras gratuitas (Art. 7.4º LIVA)"
    }
  ],
  "options": { "issue_directly": true }
}
```

## F1 ISP — reverse charge (S2)

Reverse charge (*inversión del sujeto pasivo*): the **buyer** self-assesses the IVA instead of the seller charging it. Common cases: construction services subcontracted to a developer (`ISP_ART_84_2_F`), scrap metal deliveries (`ISP_ART_84_2_C`), and operations performed by non-established entities (`ISP_ART_84_2_A`).

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "recipient": {
      "legal_name": "Promociones Inmobiliarias del Mediterráneo SA",
      "nif": "A46789012",
      "address": {
        "street": "Gran Vía Marqués del Turia",
        "number": "47",
        "postal_code": "46005",
        "city": "Valencia",
        "province": "Valencia",
        "country": "España",
        "country_code": "ES"
      }
    },
    "lines": [
      {
        "description": "Ejecución de obra — instalación eléctrica edificio Torre Norte",
        "quantity": 1,
        "unit": "project",
        "unit_price": 42000.00,
        "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
        "exemption_reason": "ISP_ART_84_2_F",
        "exemption_reason_text": "Inversión del sujeto pasivo — Art. 84.Uno.2º.f LIVA (ejecución de obra)"
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "type": "STANDARD",
  "recipient": {
    "legal_name": "Promociones Inmobiliarias del Mediterráneo SA",
    "nif": "A46789012",
    "address": {
      "street": "Gran Vía Marqués del Turia",
      "number": "47",
      "postal_code": "46005",
      "city": "Valencia",
      "province": "Valencia",
      "country": "España",
      "country_code": "ES"
    }
  },
  "lines": [
    {
      "description": "Ejecución de obra — instalación eléctrica edificio Torre Norte",
      "quantity": 1,
      "unit": "project",
      "unit_price": 42000.00,
      "main_tax": { "type": "IVA", "percentage": 0, "regime_key": "01" },
      "exemption_reason": "ISP_ART_84_2_F",
      "exemption_reason_text": "Inversión del sujeto pasivo — Art. 84.Uno.2º.f LIVA (ejecución de obra)"
    }
  ],
  "options": { "issue_directly": true }
}
```

<Callout type="warn">
  ISP lines must **never** carry `equivalence_surcharge_rate` — the buyer self-assesses the full tax, so the surcharge cannot apply. BeeL. rejects the combination at validation time.
</Callout>

## F1 REBU (used goods, art, antiques)

Not accepted: a line with `regime_key: "03"` is rejected with `422` [`REGIME_KEY_NOT_SUPPORTED`](/errors/REGIME_KEY_NOT_SUPPORTED). Under the used-goods regime the invoice must not show the tax separately (RD 1619/2012, art. 16.2.c), and a BeeL. invoice always does. See [Regime keys](/verifactu/regime-keys#keys-that-are-not-accepted).

## R1 corrective — partial (by differences)

The most common rectification. Apply a delta to a previously issued invoice — quantities can be positive or negative. The URL points to the **original** invoice; the body describes only the change. The original status flips to `RECTIFIED`.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/corrective" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8b9c2e44-bbcd-4f23-9a01-1c3d5e7f9a02" \
  -d '{
    "rectification_type": "PARTIAL",
    "rectification_code": "R1",
    "reason": "Descuento comercial post-emisión acordado con el cliente (5 horas no facturables)",
    "lines": [
      {
        "description": "Ajuste por horas no facturables — Sprint mayo",
        "quantity": -5,
        "unit": "hours",
        "unit_price": 75.00,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
      }
    ],
    "options": { "issue_directly": true }
  }'
```

```json
{
  "rectification_type": "PARTIAL",
  "rectification_code": "R1",
  "reason": "Descuento comercial post-emisión acordado con el cliente (5 horas no facturables)",
  "lines": [
    {
      "description": "Ajuste por horas no facturables — Sprint mayo",
      "quantity": -5,
      "unit": "hours",
      "unit_price": 75.00,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
    }
  ],
  "options": { "issue_directly": true }
}
```

The `quantity: -5` produces a negative line — that's the canonical "by differences" pattern. See [Corrective invoices](/verifactu/corrective-invoices) for when to pick `PARTIAL` vs `TOTAL` and which code (R1–R4) applies to your case.

## R5 corrective — return on simplified F2

R5 is **reserved for rectifying SIMPLIFIED invoices**, whatever the cause. The common case: the customer returns one of the items on the ticket.

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices/9f8e7d6c-5b4a-3210-fedc-ba9876543210/corrective" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rectification_type": "PARTIAL",
    "rectification_code": "R5",
    "reason": "El cliente devolvió uno de los dos artículos del tique",
    "lines": [
      {
        "description": "Devolución - camiseta talla M",
        "quantity": -1,
        "unit_price": 16.53,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
      }
    ]
  }'
```

```json
{
  "rectification_type": "PARTIAL",
  "rectification_code": "R5",
  "reason": "El cliente devolvió uno de los dos artículos del tique",
  "lines": [
    {
      "description": "Devolución - camiseta talla M",
      "quantity": -1,
      "unit_price": 16.53,
      "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
    }
  ]
}
```

**What changes vs. the previous example:** `rectification_code` goes from `R1` to `R5`, and, like the F2, the R5 reaches AEAT without recipient data. A customer who asks for an invoice with their details after a ticket is not a correction: nothing in the ticket is wrong, so that is not an R5 but an [exchange of the simplified invoice](/verifactu/simplified-vs-standard#upgrading-an-f2-to-f1-the-canje-case).

## Voiding [#voiding-anulación]

If the operation **never happened** — duplicate emission, wrong customer, test invoice escaped to production — use the void endpoint, **not** a corrective. Voiding is for "this invoice should not exist"; corrective is for "this invoice exists but the numbers are wrong".

```bash
curl -X POST "https://app.beel.es/api/v1/companies/{company_id}/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/void" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Duplicado de la factura F-2026-0142, emitida dos veces por error",
    "issued_in_error": true
  }'
```

```json
{
  "reason": "Duplicado de la factura F-2026-0142, emitida dos veces por error",
  "issued_in_error": true
}
```

The invoice flips to `VOIDED` and, if AEAT had accepted its registration, the cancellation record is sent automatically; if the registration never reached AEAT, nothing is sent. `issued_in_error: true` confirms the invoice was issued by mistake: it is required once the invoice has been sent or paid ([`VOID_REQUIRES_ISSUED_IN_ERROR`](/errors/VOID_REQUIRES_ISSUED_IN_ERROR)). See [Cancel and fix](/verifactu/cancel-and-fix) for the decision tree between void and corrective.


## Related

<Related>

- [Tax classification per line](/verifactu/tax-classification) — the `exemption_reason` mapping
- [Corrective invoices](/verifactu/corrective-invoices) — every R1–R5 scenario
- [International customers](/verifactu/international-customers) — the cross-border cases in depth


</Related>

---

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