NewThree filters returned the wrong rows
BeeL
Get StartedMulti-NIFVeriFactuStripeAPI ReferenceChangelog

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.

PROFORMA has no AEAT code. The fourth value of type is a commercial document with no fiscal validity: it never enters VeriFactu (no QR, no AEAT submission, verifactu_enabled forced to false), it cannot be corrective, and it lives on its own statuses (ACTIVECONVERTED or VOIDED, plus the derived EXPIRED) without ever reaching ISSUED. It still requires full recipient data, like a STANDARD.

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/companies/{company_id}/invoices" \
  -H "Authorization: Bearer beel_sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "STANDARD",
    "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/companies/{company_id}/invoices" \
  -H "Authorization: Bearer beel_sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "SIMPLIFIED",
    "recipient": {},
    "lines": [
      {
        "description": "Computer repair service",
        "quantity": 1,
        "unit": "service",
        "unit_price": 300,
        "discount_percentage": 0,
        "main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" }
      }
    ],
    "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