Corrective invoices (R1–R5)
Pick the right rectification type and code, and see the canonical request shapes BeeL accepts for each scenario.
A corrective invoice (factura rectificativa) corrects a previously issued invoice. BeeL exposes them through POST /v1/invoices/{invoice_id}/corrective — the URL points to the original invoice, and the body describes the correction.
You decide two things:
rectification_type—TOTAL(replace / cancel the original) orPARTIAL(apply a delta)rectification_code—R1–R5(the legal motive)
Plus a free-text reason describing the situation in human language.
The two axes
PARTIAL (one delta registro, easy bookkeeping)
┌────────────────────────────────────────────────┐
why → │ R1 │ R2 │ R3 │ R4 │ R5 (F2 only) │
├────────────────────────────────────────────────┤
TOTAL (one registro replaces the original)rectification_type | AEAT tipo_rectificativa | What BeeL sends to AEAT |
|---|---|---|
PARTIAL | I (por diferencias) | One registro with delta lines; no importe_rectificativa block |
TOTAL | S (por sustitución) | One registro with the new totals + the original totals echoed in importe_rectificativa |
The original invoice's status changes after issuance:
PARTIAL→ original becomesRECTIFIED(can be corrected again)TOTAL→ original becomesVOIDED(terminal, no further correctives)
Pick the reason (R1–R5)
rectification_code | When to use | Legal basis |
|---|---|---|
| R1 | Almost every common correction: wrong amount, post-issuance discount, returned goods | Art. 80 Uno/Dos/Seis LIVA + error fundado en derecho |
| R2 | The customer is in formal concurso de acreedores | Art. 80 Tres LIVA |
| R3 | Bad debt: invoice is uncollectable after the legal procedure | Art. 80 Cuatro LIVA |
| R4 | Customer-requested cancellation, post-issuance changes outside R1–R3 | Resto de causas |
| R5 | Correcting a simplified (F2) invoice — any reason | Art. 80 Uno/Dos LIVA for F2 |
R5 is for F2 only. You cannot correct an F1 with R5, and you cannot correct an F2 with R1–R4. BeeL rejects mismatches at the API boundary.
Scenario 1 — TOTAL cancellation (R1)
The original should be cancelled outright (e.g. project cancelled before commencement). No lines needed for TOTAL — BeeL replaces the original with empty content.
curl -X POST "https://app.beel.es/api/v1/invoices/{invoice_id}/corrective" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"rectification_type": "TOTAL",
"rectification_code": "R1",
"reason": "Cancellation of invoice issued due to a legally founded error under Art. 80 Uno LIVA. The transaction was not completed due to project cancellation before commencement.",
"notes": "Original invoice F/2025/0042 fully cancelled. Customer notified."
}'The original becomes VOIDED; the corrective carries the matching tipo_rectificativa S to AEAT.
Scenario 2 — PARTIAL adjustment for bankruptcy (R2)
Customer entered concurso de acreedores; you adjust the outstanding amount to what the insolvency administrator agreed. Send the delta as a PARTIAL:
curl -X POST "https://app.beel.es/api/v1/invoices/{invoice_id}/corrective" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"rectification_type": "PARTIAL",
"rectification_code": "R2",
"reason": "Partial correction of invoice due to customer bankruptcy proceedings under Art. 80 Tres LIVA. Amount adjusted to the agreement reached with the insolvency administrator.",
"lines": [
{
"description": "Adjustment for bankruptcy proceedings - 40% amount reduction",
"quantity": -16,
"unit": "hours",
"unit_price": 37.5,
"discount_percentage": 0,
"main_tax": {
"type": "IVA",
"percentage": 21,
"regime_key": "01"
}
}
],
"notes": "Correction approved by insolvency administrator. Case 123/2024 Commercial Court No. 2 Madrid."
}'Lines carry negative quantity (or negative unit_price) to express the reduction. The original stays RECTIFIED.
Scenario 3 — PARTIAL bad-debt write-off (R3)
Documented bad debt under Art. 80 Cuatro LIVA. Send a negative line that zeroes out the IVA on the uncollectible part:
curl -X POST "https://app.beel.es/api/v1/invoices/{invoice_id}/corrective" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"rectification_type": "PARTIAL",
"rectification_code": "R3",
"reason": "Partial correction for bad debt under Art. 80 Cuatro LIVA. More than 6 months have elapsed since the invoice due date and collection efforts via notarial demands have been documented without result.",
"lines": [
{
"description": "Bad debt adjustment - Full cancellation of outstanding amount",
"quantity": -40,
"unit": "hours",
"unit_price": 37.5,
"discount_percentage": 0,
"main_tax": {
"type": "IVA",
"percentage": 21,
"regime_key": "01"
}
}
],
"notes": "Collection efforts documented via notarial demands (Protocol 456/2024). Original invoice due on 15/03/2024."
}'Scenario 4 — TOTAL customer-requested cancellation (R4)
Catch-all for valid corrections outside R1–R3. The customer asked to cancel the whole invoice:
curl -X POST "https://app.beel.es/api/v1/invoices/{invoice_id}/corrective" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"rectification_type": "TOTAL",
"rectification_code": "R4",
"reason": "Invoice cancellation at customer'\''s request. The service was cancelled before delivery and full cancellation of the invoice has been agreed.",
"notes": "Invoice cancelled at customer'\''s request. No outstanding amount pending collection."
}'Scenario 5 — R5: cancelling an F2 to issue a proper F1
You issued an F2 ticket and the customer now needs an identified F1. The clean path:
-
TOTAL corrective with
rectification_code: R5on the F2curl -X POST "https://app.beel.es/api/v1/invoices/{f2_invoice_id}/corrective" \ -H "Authorization: Bearer beel_sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{ "rectification_type": "TOTAL", "rectification_code": "R5", "reason": "Customer requested an identified invoice replacing the original simplified ticket.", "notes": "Replaced by F1 issued same date with full recipient data." }' -
New F1 (
POST /v1/invoiceswithtype: STANDARD) with the customer's NIF and full data.
Both records stay in AEAT (the F2, its R5 cancellation, and the new F1). The running fiscal total reconciles.
Validation rules BeeL applies
| Rule | What happens if you break it |
|---|---|
rectification_code must match the original type (R5 ↔ F2, R1–R4 ↔ F1) | Rejected at issuance with a clear error |
| Original must exist and belong to your account | Rejected — the URL {invoice_id} resolves to nothing |
Original cannot already be VOIDED (TOTAL terminates the chain) | Rejected — chain is closed |
For PARTIAL, line totals can be negative or positive — anything goes mathematically | — |
For TOTAL, omit lines (BeeL clears the original); for PARTIAL, lines are required | — |
Related
- Invoice types — R1–R5 in the broader catalogue
- Cancel vs amend — when to use the void endpoint instead
- Submission states — what happens after BeeL submits the corrective
- createCorrectiveInvoice API reference — full request schema
Simplified vs standard (F1 vs F2)
When to issue a factura simplificada (F2), when you must use a factura ordinaria (F1), and what BeeL enforces at the API boundary.
Tax classification per line
Set `exemption_reason` on each line correctly. Includes the full mapping from BeeL API values to AEAT codes (S1/S2/N1/N2/E1–E6).