Cancel vs amend
Decide between cancelling an invoice (void) and issuing a corrective (rectificativa). Each operation has different fiscal weight.
The AEAT VeriFactu spec exposes three distinct fix operations: anulación, subsanación, and rectificativa. They look similar but mean very different things. Pick the wrong one and you either misreport or burn an invoice number.
The 30-second decision
What's wrong with the invoice?
│
├─ Issued by mistake — never should have existed
│ → ANULACIÓN (POST /invoices/{id}/void)
│
├─ Numbers / customer / amount need correction
│ → RECTIFICATIVA (POST /invoices/{id}/corrective — see Corrective invoices)
│
└─ Non-fiscal metadata typo (descripción, custom field, ...)
→ SUBSANACIÓN (BeeL handles internally on AEAT rejection;
no public endpoint to drive manually)| Operation | Use when | Fiscal weight | Original status after |
|---|---|---|---|
| Anulación (void) | The invoice shouldn't exist at all — wrong customer billed, accidental duplicate | A registro de anulación is sent to AEAT, linked to the original | VOIDED (no corrective in chain) |
| Rectificativa (corrective) | The invoice should exist but the data is wrong | New registro corrects or replaces | RECTIFIED (PARTIAL) / VOIDED (TOTAL) |
| Subsanación (internal) | A previous registro was rejected by AEAT for a non-fiscal reason and needs a retry with the corrected metadata | Updates the in-flight registro, no new fiscal record | Same as before |
Anulación does not fix errors. AEAT explicitly says: if the invoice has incorrect data but the operation actually happened, you must issue a rectificativa. Use anulación only for invoices that were issued in error and have no commercial reality.
Anulación (void)
curl -X POST "https://app.beel.es/api/v1/invoices/{invoice_id}/void" \
-H "Authorization: Bearer beel_sk_live_xxx"What happens:
- The invoice's commercial status moves to
VOIDED. - BeeL submits a registro de anulación to AEAT (separate from the original registro de alta).
- AEAT processes the cancellation and BeeL updates the invoice's
verifactu.submission_statusto reflect the cancellation response.
What you give up:
- You cannot reissue the same
serie + numeroafterwards. AEAT remembers the number was used. - The original registro de alta stays in AEAT's records (with the anulación linked to it).
If you simply realised the customer never existed and you want to "free up" the invoice number, this is not the way — AEAT does not allow renumbering. Pick a different serie + numero for the next attempt.
See the voidInvoice API reference for the full schema.
Rectificativa (corrective)
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": "R1",
"reason": "Customer-agreed post-issuance discount on professional services.",
"lines": [
{ "description": "Discount adjustment", "quantity": -1, "unit_price": 200, "discount_percentage": 0,
"main_tax": { "type": "IVA", "percentage": 21, "regime_key": "01" } }
]
}'A new invoice is issued, referencing the original. Its own AEAT tipo_factura is R1/R2/R3/R4/R5, and it has its own registro de alta (no anulación). The original stays RECTIFIED (PARTIAL) or VOIDED (TOTAL) — but is never erased from AEAT.
Use rectificativa for:
- Wrong amount / IVA rate
- Wrong customer NIF or name
- Post-issuance discount or quantity adjustment
- Bad debt write-off
- Concurso de acreedores adjustment
- Converting an F2 ticket into a proper F1 (R5 TOTAL on the F2 + new F1)
See Corrective invoices for every scenario with payloads.
Subsanación (amend the registro)
Subsanación is the AEAT mechanism for resubmitting a rejected registro with corrected metadata. The fiscal record stays the same — only the metadata changes.
BeeL handles subsanación for you on AEAT rejection: when an invoice's verifactu_status is REJECTED because of a non-fiscal field (typo in description, wrong serie code mapping), BeeL retries the submission with the corrected metadata. There is no public API endpoint to drive subsanación manually.
If subsanación isn't enough (e.g. you need a rechazo_previo value that BeeL doesn't set automatically), write to it@beel.es — we'll handle it operationally.
Decision matrix
| Symptom | Operation | Notes |
|---|---|---|
| Issued an invoice for the wrong customer entirely | Anulación (void) | Then issue a new one for the right customer |
| Invoice was a duplicate (you accidentally fired the endpoint twice) | Anulación (void) on the duplicate | Original stays valid |
| Customer's NIF was wrong | Rectificativa R1 TOTAL | Anulación + reissue also works but leaves an anulación in the AEAT trail |
| Amount was wrong (under-/over-charged) | Rectificativa R1 PARTIAL (delta) or TOTAL (replace) | Pick based on bookkeeping preference |
| Customer didn't pay and you wrote off the debt | Rectificativa R3 | Pair with the legal claim documentation |
AEAT rejected because of a typo in descripcion | BeeL retries automatically | No new invoice needed |
| AEAT rejected because of a wrong NIF | Anulación + reissue with correct NIF, or rectificativa R1 | Subsanación can't fix fiscal data |
| Invoice was sent to AEAT but you've discovered an IVA-rate error | Rectificativa R1 | Most common case |
Related
- Corrective invoices — R1–R5 with full examples
- Submission states — how cancellation fits in the lifecycle
- Auto-submit policy — applies to cancel registros too
- voidInvoice API reference
- createCorrectiveInvoice API reference