Invoice types
F1, F2, R1–R5 — what each VeriFactu invoice type means, when BeeL emits each one, and which API fields map to which AEAT code.
Every invoice you submit to VeriFactu carries a tipo_factura code. BeeL derives that code from your invoice's type and (for correctives) the rectification_code you set. This page is the canonical map between BeeL's invoice model and the AEAT type codes.
The full catalogue
| AEAT code | Name | BeeL request fields | Customer ID required? | Notes |
|---|---|---|---|---|
| F1 | Factura ordinaria | type: STANDARD | Yes (NIF or alternative_id) | Default for B2B and high-value B2C |
| F2 | Factura simplificada | type: SIMPLIFIED | Conditional | Total ≤ 400 € without identifying the customer, or ≤ 3 000 € with NIF (see Simplified vs standard) |
| F3 | Factura sustitutiva | Not implemented | — | See workaround in Simplified vs standard |
| R1 | Rectificativa por error fundado en derecho | type: CORRECTIVE + rectification_code: R1 | Yes | Most common correction |
| R2 | Rectificativa por concurso de acreedores | type: CORRECTIVE + rectification_code: R2 | Yes | Customer in formal insolvency |
| R3 | Rectificativa por crédito incobrable | type: CORRECTIVE + rectification_code: R3 | Yes | Bad debt |
| R4 | Rectificativa por resto de causas | type: CORRECTIVE + rectification_code: R4 | Yes | Catch-all not in R1–R3 |
| R5 | Rectificativa de factura simplificada | type: CORRECTIVE + rectification_code: R5 | No (matches F2) | The only way to correct an F2 |
rectification_code (R1–R5) is why the rectificative exists. rectification_type (PARTIAL / TOTAL) is how the correction works mathematically — see Corrective invoices. The free-text reason is the human description.
How BeeL chooses the code
The decision happens at issuance, never on the draft:
type=STANDARD → F1
type=SIMPLIFIED → F2 (must satisfy the simplified rules)
type=CORRECTIVE → R{rectification_code} (R1, R2, R3, R4, R5)You cannot override tipo_factura directly — set the right type and rectification_code and BeeL maps them. If you try to issue a STANDARD invoice that fails the F1 rules (e.g. missing recipient.nif and no alternative_id), the request is rejected with a descriptive error before anything is sent to AEAT.
F1 — Factura ordinaria
Use F1 when the recipient is identified. This is the default for B2B, professional services, and any B2C invoice above the simplified threshold.
curl -X POST "https://app.beel.es/api/v1/invoices" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "STANDARD",
"issue_date": "2026-05-18",
"recipient": {
"legal_name": "Comercial Martínez SL",
"nif": "B87654321",
"address": {
"street": "Avenida de la Constitución",
"number": "45",
"postal_code": "41001",
"city": "Sevilla",
"province": "Sevilla",
"country": "España"
}
},
"lines": [
{
"description": "Business strategic consulting",
"quantity": 8,
"unit": "hours",
"unit_price": 125,
"discount_percentage": 0,
"main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
}
],
"payment_info": { "method": "BANK_TRANSFER", "iban": "ES9121000418450200051332", "payment_term_days": 30 }
}'What BeeL forces on F1:
recipient.niforrecipient.alternative_idis mandatory- If the customer is an individual (NIF starting with a digit), the
legal_namemust match the AEAT census or VeriFactu rejects the registro (BeeL validates this for you via the NIF Validation API) - At least one
lines[]entry; line totals must reconcile
F2 — Factura simplificada
Use F2 when you don't identify the recipient and the total is small enough that the law allows it.
curl -X POST "https://app.beel.es/api/v1/invoices" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "SIMPLIFIED",
"issue_date": "2026-05-18",
"recipient": {},
"lines": [
{
"description": "Computer repair service",
"quantity": 1,
"unit": "service",
"unit_price": 300,
"discount_percentage": 0,
"main_tax": { "type": "IVA", "percentage": 21, "regime_key": "20" }
}
],
"payment_info": { "method": "CASH" }
}'What BeeL forces on F2:
recipientblock is optional (empty object or omit it)total(IVA included) must be ≤ 3 000 € — request rejected above the threshold- All other line semantics work exactly as on F1
See Simplified vs standard for the full decision criteria.
R1–R5 — Rectificative invoices
A corrective invoice always targets an original (via the URL {invoice_id}) and carries:
rectification_code—R1–R5(the AEAT legal motive)rectification_type—PARTIAL(delta) orTOTAL(replace)reason— free-text human description (required)
The combination determines what BeeL sends to AEAT (tipo_rectificativa = S for TOTAL, I for PARTIAL). Examples for every common scenario live in Corrective invoices.
R5 is reserved for F2. You cannot use R1–R4 on a simplified invoice, and you cannot use R5 on a standard one. BeeL enforces this — pick the rectification_code that matches the original type.
F3 — Why BeeL doesn't emit it
F3 (factura sustitutiva) is the AEAT mechanism for converting a previously simplified invoice into a normal one in a single submission. BeeL does not implement it because the equivalent flow with two steps is unambiguous:
- Issue a
R5corrective on the F2 withrectification_type: TOTAL(cancels the simplified) - Issue a brand-new
STANDARDinvoice referencing the same operation
Both registros are submitted independently and the running total reconciles cleanly. If you have a strong reason to need F3 specifically, write to it@beel.es.
What BeeL never sets
| Field | Reason |
|---|---|
emitida_por_tercero_o_destinatario (T / D) | BeeL is always the self-issuance path; third-party issuance is out of scope |
facturas_sustituidas | Tied to F3, which is not emitted |
Next
- Simplified vs standard — the F1/F2 decision tree
- Corrective invoices — every R1–R5 scenario with payloads
- Tax classification — the
exemption_reason↔ AEAT code mapping - createInvoice API reference — full request schema