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

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)

├─ Anything in the invoice's own data is wrong
│  (numbers / customer / amount / descripción / serie / any content)
│  → RECTIFICATIVA  (POST /invoices/{id}/corrective — see Corrective invoices)
│     or void + reissue

└─ The invoice data is fine; the submission failed for a cause
   external to it (issuing NIF not censado, representation unsigned)
   → SUBSANACIÓN  (resubmits the unchanged record once the external
                    cause is resolved; no public endpoint)
OperationUse whenFiscal weightOriginal status after
Anulación (void)The invoice shouldn't exist at all — wrong customer billed, accidental duplicateA registro de anulación is sent to AEAT, linked to the originalVOIDED (no corrective in chain)
Rectificativa (corrective)The invoice should exist but the data is wrongNew registro corrects or replacesRECTIFIED (PARTIAL) / VOIDED (TOTAL)
Subsanación (resubmit)A registro was rejected for a cause external to the invoice's data (issuing NIF not yet censado, representation unsigned) and the same, unchanged record needs to be resubmittedResubmits the identical registro, no new fiscal recordSame 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/companies/{company_id}/invoices/{invoice_id}/void" \
  -H "Authorization: Bearer beel_sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Invoice issued by mistake: the operation never took place."
  }'

The body is required: reason is mandatory and must be at least 10 characters. void_date is optional and defaults to today. Only an ISSUED, SENT, OVERDUE, PAID or RECTIFIED invoice can be voided.

What happens:

  1. The invoice's commercial status moves to VOIDED.
  2. BeeL. submits a registro de anulación to AEAT (separate from the original registro de alta).
  3. AEAT processes the cancellation and BeeL. updates the invoice's verifactu.submission_status to reflect the cancellation response.

What you give up:

  • You cannot reissue the same serie + numero afterwards. 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/companies/{company_id}/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 (resubmit the registro)

Subsanación is the AEAT mechanism for resubmitting the same registro after a rejection. The fiscal record is immutable and does not change — subsanación does not, and cannot, edit the invoice's content. It therefore only ever addresses causes external to the invoice's data: for example an issuing NIF that was not yet censado in VeriFactu, or a representation that was not signed at submission time. Once the external cause is resolved, the identical record is sent again.

Because the record is immutable, subsanación is never the way to fix a typo in descripcion, a wrong amount, a wrong receptor NIF, or a wrong serie code. Any error in the invoice's own data is corrected with a rectificativa (POST /invoices/{id}/corrective) or void + reissue, both of which produce a new fiscal document.

There is no public API endpoint to drive subsanación, and BeeL. does not perform it automatically today. If a submission is stuck on an external cause you cannot resolve yourself, write to it@beel.es and we'll handle it operationally.

Decision matrix

SymptomOperationNotes
Issued an invoice for the wrong customer entirelyAnulació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 duplicateOriginal stays valid
Customer's NIF was wrongRectificativa R1 TOTALAnulació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 debtRectificativa R3Pair with the legal claim documentation
AEAT rejected because of a typo in descripcionRectificativa R1, or void + reissueThe record is immutable; subsanación can't edit content
AEAT rejected because of a wrong NIFAnulación + reissue with correct NIF, or rectificativa R1Subsanación can't fix invoice data
Rejected because the issuing NIF wasn't censado yetSubsanación (resubmit once registered)External cause; the invoice data is fine
Invoice was sent to AEAT but you've discovered an IVA-rate errorRectificativa R1Most common case