NewStripe: a buyer with a NIF always gets a standard invoice, and the simplified threshold is deprecated
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog

Cancel vs amend

Decide between cancelling an invoice (void) and issuing a corrective invoice, two operations with different fiscal weight.


The AEAT VeriFactu spec exposes three distinct fix operations: void (anulación), subsanación (replacing a record with a corrected one) and corrective invoice (factura 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

Void only what should never have been issued; correct everything else. Every situation, one row each, is in the table Void or correct.

OperationUse whenFiscal weight
VoidVOI-001 Void only an invoice that should never have been issuedA cancellation record is sent to AEAT, linked to the original
Corrective invoiceCOR-001 Wrong data on an issued invoice is fixed with a correctiveA new invoice, with its own record, corrects the original
SubsanaciónREC-010 Subsanación is only for errors that need no correctiveThe record is replaced by a corrected one; no new invoice

Void (anulación)

To void an invoice, call POST …/invoices/{invoice_id}/void with a reason: the invoice becomes VOIDED at once. A void is only for an invoice issued by mistake — the operation never took place, it was a test, or it is an accidental duplicate. Once the invoice has been sent or paid, confirm it with issued_in_error: true. The request rules and which invoices can be voided are in Invoice lifecycle; this section covers what reaches AEAT.

What happens:

  1. The invoice's commercial status moves to VOIDED.
  2. BeeL. submits a cancellation record (registro de anulación) to AEAT, separate from the original registration record (registro de alta).
  3. AEAT processes the cancellation and BeeL. updates the invoice's verifactu.submission_status to reflect the cancellation response. The cancellation is also a record of its own — see Did AEAT accept the cancellation? below.

What you give up:

  • The number stays used: a voided invoice keeps it, and the next invoice takes a new one (see Series and numbering).
  • The original registration record stays in AEAT's records, with the cancellation linked to it.

Did AEAT accept the cancellation?

The invoice's verifactu block summarises the registration: once you void, its submission_status moves with the cancellation, but invoice_hash, registration_number and registered_at keep describing the registration record. To see each record with its own status, list the invoice's VeriFactu records with List the VeriFactu records of an invoice:

curl "https://app.beel.es/api/v1/companies/{company_id}/invoices/{invoice_id}/verifactu-records" \
  -H "Authorization: Bearer $BEEL_API_KEY"
{
  "success": true,
  "data": {
    "records": [
      {
        "id": "2b1605c5-cdc4-45c1-b007-5261342947ec",
        "operation": "REGISTRATION",
        "submission_status": "ACCEPTED",
        "invoice_hash": "1863E77D540083E4259F4AF44322E16B962CB5D72C2F949AB2B30FA83E93FF84",
        "registration_number": "094365f5-9637-40e9-851a-4e964a939b0b",
        "registered_at": "2026-09-19T09:27:44.490799Z",
        "qr_url": "https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR?nif=B27534239&numserie=S-2026-0001&fecha=19-09-2026&importe=121.00"
      },
      {
        "id": "582ed3b9-51e1-48a0-b725-137ae5b2efb1",
        "operation": "VOID",
        "submission_status": "PENDING",
        "registration_number": "e2e5f3db-999a-4c9f-afd5-7a7a059ca384",
        "registered_at": "2026-09-19T09:28:15.523675Z"
      }
    ]
  },
  "meta": { "timestamp": "2026-09-19T09:28:16Z", "request_id": "ac4654e8df3bb20e339c4086fadc6725" }
}

Records come ordered by registered_at, the registration first. The VOID record answers the question: PENDING while AEAT has not replied, VOIDED once it accepts the cancellation, REJECTED if it refuses it, with error_message giving the reason and error_code carrying AEAT's code when AEAT gave one. invoice_hash and qr_url only travel on REGISTRATION records. registration_number is BeeL.'s identifier (a UUID) for the record, not an AEAT code, and registered_at is when the record was created. Each record's id is the verifactu_registration_id you receive in verifactu.status.updated, so a webhook can be matched to the exact record it reports on.

You don't have to poll for it. verifactu.status.updated is sent for the cancellation record too, and its operation says which record changed: REGISTRATION for the invoice's registration, VOID for its cancellation. A VOID event with new_status: VOIDED is AEAT accepting the cancellation; with REJECTED, error_code and error_message say why.

{
  "type": "verifactu.status.updated",
  "data": {
    "invoice_id": "550e8400-e29b-41d4-a716-446655440000",
    "invoice_number": "2026-0042",
    "verifactu_registration_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "operation": "VOID",
    "previous_status": "PENDING",
    "new_status": "VOIDED"
  }
}

Voiding while the registration is still PENDING. You can void an invoice before AEAT has answered the registration record. The cancellation is sent once the registration is accepted, so until then the list shows only the REGISTRATION record; the VOID record appears when the cancellation goes out, and reaches VOIDED when AEAT accepts it. In sandbox this takes a few minutes. If AEAT ends up rejecting the registration instead, no cancellation is sent at all.

Voiding an invoice that never reached AEAT sends nothing. If the registration was refused before reaching AEAT, abandoned, or rejected by AEAT, there is no record there to cancel: the invoice becomes VOIDED in BeeL., no VOID record appears, and verifactu.submission_status keeps the registration's outcome. See Handling AEAT rejections.

Corrective invoice (rectificativa)

A new invoice is issued, referencing the original, with its own AEAT tipo_factura (R1–R5) and its own registration record (no cancellation record). The original is never erased from AEAT. Request shapes, codes and every scenario are in Corrective invoices.

Use a corrective invoice for:

  • Wrong amount / IVA rate
  • Wrong customer NIF, name or address, when the invoice went to the right customer (R4, no lines — see Correcting the recipient's data)
  • Post-issuance discount or quantity adjustment
  • Bad debt write-off
  • Insolvency proceedings (concurso de acreedores) adjustment

A customer who asks for a full invoice instead of a ticket is not a correction: that is the exchange of simplified invoices. And a withholding that should not have been applied is not one either: void the invoice and issue a new one without it.

Subsanación

Subsanación is the AEAT mechanism that replaces a registration record with a corrected one (AEAT's FAQ: «sustitución del "registro de alta" por otro registro subsanado»). It never changes what the invoice says, so it only applies when the error needs no corrective invoice: for example a rejection caused by an issuing NIF that was not yet in the census.

Subsanación is never the way to fix a typo in the description, a wrong amount, a wrong recipient NIF or a wrong series. An error in the invoice's amounts or content is corrected with a corrective invoice (POST /invoices/{id}/corrective), which produces a new fiscal document; a void is only for an invoice that should never have been issued. A corrective invoice keeps the recipient of the invoice it corrects, and changes only that recipient's data (COR-017 A corrective keeps the recipient, except to correct the recipient's data): an invoice issued to the wrong party is corrected in full with a TOTAL corrective and invoiced again to the right one.

When the cause was outside the invoice and you have resolved it, contact BeeL. with the invoice — see Handling AEAT rejections.

Decision matrix

The situations and what to do with each are in Void or correct, a table built from the rules that decide it. Two cases that depend on what AEAT answered:

  • AEAT never registered the invoice (REJECTED): voiding it sends nothing to AEAT — see Void.
  • Rejected because the issuing NIF was not in the census yet: nothing in the invoice is wrong, so it is a subsanación — contact it@beel.es once the NIF is registered.