Factuarea APIDevelopers

Fiscal invoice examples

The 21 Spanish tax scenarios for invoicing, which four of them ship as ready-to-send request examples in the API Reference, and a corrective example for each AEAT R-code (R1–R5).

Spanish invoicing covers many tax scenarios — domestic B2B, intra-EU goods and services, OSS distance sales, IGIC in the Canary Islands, IPSI in Ceuta/Melilla, IRPF withholding, equivalence surcharge, exempt and non-subject operations. Getting the right combination of tax_rate, exemption_reason, regime_key, retention_rate and surcharge_rate on each line is the hard part.

To make this concrete, the API Reference ships four named, ready-to-send request examples on POST /v1/companies/{company}/invoices — a curated, representative set rather than one per scenario. Each one is a valid payload you can copy, adapt and send: pick the closest one in the request-body examples dropdown, then use the table below and the guide linked on each row for the rest.

All the routes in this guide hang off /v1/companies/{company}/…: {company} is the id (UUID v7) of the tax ID you operate on, and in the curl examples it is $COMPANY_ID. Reach a tax ID explains how to resolve it.

The 21 scenarios

Every row below is a scenario you can express line by line with the fields above. The four marked ★ are the ones that also ship as named request examples you can pick straight from the dropdown; the remaining seventeen are documented here and in the linked guide, but have no named example in the spec — build them from the closest starred one.

Scenario keyScenarioGuide
★ b2b_nacionalDomestic B2B, 21% VAT per line (general AEAT regime 01).Regime keys
b2b_nacional_iva_reducidoReduced (10%) or super-reduced (4%) VAT, regime 01.Line tax classification
★ b2cFinal consumer (no recipient tax ID; simplified invoice where applicable).Simplified or full
★ intracomunitario_bienesIntra-EU supply of goods, exempt E5 (art. 25 LIVA).International customers
intracomunitario_serviciosIntra-EU B2B services, reverse charge — qualification S2 (subject, not exempt, charged quota 0) derived from the isp header regime, not an exemption cause.International customers
ossOSS distance sales (destination-country VAT), regime_key: 17.International customers · Regime keys
igic_canariasIGIC in the Canary Islands, regime_key: 08.Territorial taxes
ipsi_ceuta_melillaIPSI in Ceuta / Melilla, regime_key: 08.Territorial taxes
★ con_irpfPer-line IRPF withholding (retention_rate).Line tax classification
con_recargo_equivalenciaEquivalence surcharge using a legal VAT↔surcharge pair, regime_key: 18.Line tax classification · Regime keys
exenta_articulo_20Exempt under art. 20 LIVA, exemption_reason: E1.Line tax classification
exenta_exportacionExport outside the EU, exempt E2 (art. 21), regime_key: 02.International customers · Regime keys
no_sujetaNon-subject operation, exemption_reason: N1 / N2.Line tax classification
inversion_sujeto_pasivo_nacionalDomestic reverse charge (e.g. construction work), tax_rate: 0.Line tax classification
regimen_especial_bienes_usadosUsed-goods margin scheme (REBU), regime_key: 03.Regime keys
regimen_agencias_viajesTravel-agency scheme (REAV), regime_key: 05.Regime keys
criterio_cajaCash-basis scheme, regime_key: 07.Regime keys
multilinea_iva_mixtoSeveral lines at different VAT rates (21% / 10% / 4%).Line tax classification
con_descuento_y_metadataPer-line discount_percent plus integration metadata.Fiscal cookbook
con_idempotency_keySafe retries with the Idempotency-Key header.Fiscal cookbook
cliente_extranjero_alternative_idForeign recipient with an alternative ID (AEAT type↔country matrix).International customers

Each of the four starred examples is also published as a reusable components.examples.invoice_* entry in the OpenAPI spec, so SDKs and tooling can resolve them by $ref.

The fiscal value objects (regime, exemption reason, IRPF, surcharge) come from Factuarea's tax engine. The examples show valid combinations; for the field-by-field contract see the POST /v1/companies/{company}/invoices request schema and Amounts and dates.

A full invoice with structured data

A complete invoice for a public customer that carries every structured block of the contract: references of the header and of the line, the invoicing period, legal literals, the four DIR3 centres and a payment schedule. The line adds up to 121.00 (100 plus 21% VAT), and the three instalments add up to the same 121.00.

curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices \
  -H "Authorization: Bearer $FACTUAREA_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "019e0000-0000-7000-8000-0000000000f1",
    "series_id": "019e0000-0000-7000-8000-0000000000f2",
    "issued_on": "2026-01-15",
    "due_on": "2026-04-15",
    "business_references": {
      "receiver_contract_reference": "CON-2026-1",
      "receiver_transaction_reference": "PED-2026-1",
      "file_reference": "EXP-2026-1"
    },
    "invoicing_period": { "start_date": "2026-01-01", "end_date": "2026-01-31" },
    "legal_literals": ["Pago sujeto al contrato indicado."],
    "administrative_centres": [
      { "role_code": "01", "code": "L01000001", "name": "Oficina contable" },
      { "role_code": "02", "code": "L01000002", "name": "Órgano gestor" },
      { "role_code": "03", "code": "L01000003", "name": "Unidad tramitadora" },
      { "role_code": "04", "code": "L01000004", "name": "Órgano proponente" }
    ],
    "lines": [
      {
        "description": "Servicio contratado",
        "quantity": 1,
        "unit_price": 100,
        "tax_rate": 21,
        "business_references": {
          "issuer_contract_reference": "REF-2026-01",
          "issuer_contract_date": "2026-01-10"
        },
        "delivery_notes_references": [{ "number": "ALB-2026-1", "date": "2026-01-10" }]
      }
    ],
    "payment_terms": [
      { "due_date": "2026-02-15", "amount": "40.00", "payment_means": "01" },
      { "due_date": "2026-03-15", "amount": "30.00", "payment_means": "04",
        "account": { "iban": "ES9121000418450200051332", "bic": "CAIXESBBXXX" } },
      { "due_date": "2026-04-15", "amount": "51.00", "payment_means": "04",
        "account": { "iban": "ES9121000418450200051332", "bic": "CAIXESBBXXX" } }
    ]
  }'

What each block must satisfy:

  • business_references (header) has exactly three keys, each up to 20 characters; the dates and the issuer references live on the line.
  • administrative_centres holds at most one centre per role_code (01 accounting office, 02 managing body, 03 processing unit, 04 proposing body). code is a DIR3 code of 9 or 10 alphanumeric characters starting with a letter; name is optional, up to 40 characters. Sending [] selects no centre.
  • payment_terms rows keep your order, dates do not decrease, amounts are two-decimal strings and add up exactly to total_to_pay. Payment codes 02 and 04 carry the account; the others take none.
  • delivery_notes_references[].number is up to 30 characters and date is optional.

The answer is 201 with the invoice, which now returns the persisted identity of every instalment (payment_terms[].id, UUID v7), payment_terms_version and administrative_version. Keep them: any later change to an existing schedule or to the routing sends the version back (expected_payment_terms_version, expected_version of administrative revisions), and a missing version answers 428.

If an instalment is wrong, for example "40.5" instead of "40.50", nothing is written:

{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_invoice_payment_terms",
    "message": "Las condiciones de pago de la factura no son válidas.",
    "param": "payment_terms.1.amount",
    "request_id": "req_..."
  }
}

A corrective invoice of -50.00 carries signed instalments with the same rule: "-20.00" and "-30.00". See Corrective invoices and Invoice business data.

Corrective invoices by R-code

A corrective (rectificativa) invoice carries the AEAT correction code that states why the original is being corrected. POST /v1/companies/{company}/invoices/{id}/corrective ships one named example per code, each a valid payload that produces that exact correction_code:

ExampleCodeApplies toGuide
r1_error_fundadoR1Well-founded error in law / cancellation. Full invoices F1/F3.Corrective invoices
r2_concursoR2Insolvency proceedings of the recipient. F1/F3.Corrective invoices
r3_incobrableR3Bad debts. F1/F3.Corrective invoices
r4_otrasR4Other causes; full or partial (correction_type: partial with lines). F1/F3.Corrective invoices
r5_simplificadaR5Correction of a simplified invoice. F2 only.Corrective invoices · Simplified or full

Pass correction_code explicitly to select the R-code; R5 applies only to simplified (F2) invoices.

A corrective is itself a fiscal document: once issued it is reported to AEAT via VeriFactu just like any other invoice. Use the example that matches the legal reason — the code is not cosmetic.

On this page

Need a hand?Contact support