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 codeNameBeeL request fieldsCustomer ID required?Notes
F1Factura ordinariatype: STANDARDYes (NIF or alternative_id)Default for B2B and high-value B2C
F2Factura simplificadatype: SIMPLIFIEDConditionalTotal ≤ 400 € without identifying the customer, or ≤ 3 000 € with NIF (see Simplified vs standard)
F3Factura sustitutivaNot implementedSee workaround in Simplified vs standard
R1Rectificativa por error fundado en derechotype: CORRECTIVE + rectification_code: R1YesMost common correction
R2Rectificativa por concurso de acreedorestype: CORRECTIVE + rectification_code: R2YesCustomer in formal insolvency
R3Rectificativa por crédito incobrabletype: CORRECTIVE + rectification_code: R3YesBad debt
R4Rectificativa por resto de causastype: CORRECTIVE + rectification_code: R4YesCatch-all not in R1–R3
R5Rectificativa de factura simplificadatype: CORRECTIVE + rectification_code: R5No (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.nif or recipient.alternative_id is mandatory
  • If the customer is an individual (NIF starting with a digit), the legal_name must 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:

  • recipient block 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_codeR1R5 (the AEAT legal motive)
  • rectification_typePARTIAL (delta) or TOTAL (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:

  1. Issue a R5 corrective on the F2 with rectification_type: TOTAL (cancels the simplified)
  2. Issue a brand-new STANDARD invoice 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

FieldReason
emitida_por_tercero_o_destinatario (T / D)BeeL is always the self-issuance path; third-party issuance is out of scope
facturas_sustituidasTied to F3, which is not emitted

Next