Cancel an invoice
LiveServed by the v1 API in development with the same checks as production; production opens on the same contract. The capabilities from before v1 keep running in production at the path your account team gives you.
Requests the cancellation with the SAT. Invoices above 1,000 MXN to a taxpayer need the receiver's acceptance: the status stays cancellation_requested until they accept, and invoice.cancelled tells you when it is done. Smaller invoices and those to the general public are cancelled right away. The invoice is not deleted: it stays with status cancelled and its cancellation details.
Needs the invoices:cancel scope.
oauth2 invoices:cancelAuthorizationBearer <token>OAuth 2.0 client credentials. Exchange your client_id and client_secret at /oauth/token of the environment for a bearer token valid for one hour. The playground of every operation asks for your own client and keeps it in your browser tab only.
Scope: invoices:cancel
id*stringThe invoice id.
^inv_[0-7][0-9a-hjkmnp-tv-z]{25}$reason*stringSAT c_MotivoCancelacion: 01 issued with errors and replaced by a new invoice; 02 issued with errors, not replaced; 03 the operation did not happen; 04 a nominative operation included in a global invoice.
"01""02""03""04"replacement_uuid?stringFolio fiscal of the new invoice that replaces this one. Required with reason 01, and not allowed with any other reason.
uuidThe cancellation was sent to the SAT.
application/json- response
id*string^inv_[0-7][0-9a-hjkmnp-tv-z]{25}$external_id*stringYour own id for this invoice, as you sent it.
status*stringstamped once the SAT accepted it. After a cancellation: cancellation_requested while the receiver must accept it, then cancelled.
"stamped""cancellation_requested""cancelled"type*stringSAT c_TipoDeComprobante of the CFDI, as sent.
"I""E""P""T""N"uuid*stringFolio fiscal the SAT assigned.
uuidverification_url?stringSAT page that verifies the invoice.
uristamp*The SAT stamp (TimbreFiscalDigital). Print it on your own representation of the CFDI.
issuer*receiver*third_party?|The taxpayer on whose behalf it was issued, or null.
place_of_issue?stringPostal code where it was issued.
items*array<>related_invoices?array<>Invoices this one is related to. Empty when there are none.
payment_method*string"PUE""PPD"payment_form*stringcfdi_use*stringcurrency*"MXN""MXN"subtotal*stringSum of the items before taxes.
^[0-9]+\.[0-9]{2}$vat*stringVAT transferred.
^[0-9]+\.[0-9]{2}$withholdings?|Total withheld. Null when nothing is withheld.
total*stringsubtotal + vat − withholdings.
^[0-9]+\.[0-9]{2}$periodicity?stringGlobal invoices only.
months?stringGlobal invoices only.
year?stringGlobal invoices only.
cancellation?|Null until you request a cancellation.
metadata?As you sent it.
created_at*stringdate-timestamped_at*stringdate-timeupdated_at*stringdate-timecurl -X DELETE 'https://api.dev.b2b.heru.app/v1/invoices/inv_01m4ra8w8mfa8svf5396b2p5e1?reason=02'{ "id": "inv_01m4tfeaarf5kae9wamfw419yc", "external_id": "INV-2026-000279", "status": "cancellation_requested", "type": "I", "uuid": "1F0C9B7E-2A4D-4C61-8E3B-5D7A9F2C4E80", "verification_url": "https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=1F0C9B7E-2A4D-4C61-8E3B-5D7A9F2C4E80&re=PDE180514R21&rr=CDE170303B61&tt=58000.00&fe=wEqS/Q==", "stamp": { "sat_certificate_number": "00001000000509465028", "issuer_certificate_number": "00001000000712345678", "pac_rfc": "SPR190613I52", "issuer_seal": "v/hmW60VefVtd6X5MYnA6I7Utbgca0wTlCi6t3z8iHSECda8b7zl04U1Rp3Utf2pjtVvNbjFXJV2BVdZ2qkHqbb4jNsXyeAc+jbeobC2ySEzr+fFvol1KEsg7C5LomVSGG0rszWIOIO2bWS50riz6B5uQga9nrJIqzSfR5HtQo1dsNgm+6H8atvrMpyI90N+ydbHmw29ONs6hZiHTkXLU86rJTKvYpmBCGO2lWvTUo2x49vqF7AZG5BnKbyw6yS1OEAtDlcJhIPU4FW4t7M1PeCk2RHKyddZTZEzngn48TT6AWE3zMjyrVxoA1V83qtCgh+EksDVt1e4w1NrwEqS/Q==", "sat_seal": "43WRIBNkAk1Z2Vp7udiZejDCbV/CZxuv2MG1Xq3s7CNLCu3H45o9DPlx/U31GDLCcHEXlC+OrqVoEZwDUFuWWim8Qx9ENQpHdKxf8hn9fChHyo1rY364aH+CiVdidiDeHphYGvVj0HkCLTinxvO2ZZT7vpAuR6r8TZbNVU7dml+KzbeGZA4IjG0Zmabx7Ij8iW+RXYIgonBt15rTZ8JG51+mf9fs7G7P4y9P4USN4WXsPsLVqpK1nI8PmC9jly4skkKp3osVtO75vumPdrGU8gZHBy9eAlgwKa1tbLFJu7FuUXS0S2upJWvMFyzMfeEaHNEgENpeMM4Usi9lA5bwkg==", "original_chain": "||1.1|1F0C9B7E-2A4D-4C61-8E3B-5D7A9F2C4E80|2026-10-13T05:12:58|SPR190613I52|v/hmW60VefVtd6X5MYnA6I7Utbgca0wTlCi6t3z8iHSECda8b7zl04U1Rp3Utf2pjtVvNbjFXJV2BVdZ2qkHqbb4jNsXyeAc+jbeobC2ySEzr+fFvol1KEsg7C5LomVSGG0rszWIOIO2bWS50riz6B5uQga9nrJIqzSfR5HtQo1dsNgm+6H8atvrMpyI90N+ydbHmw29ONs6hZiHTkXLU86rJTKvYpmBCGO2lWvTUo2x49vqF7AZG5BnKbyw6yS1OEAtDlcJhIPU4FW4t7M1PeCk2RHKyddZTZEzngn48TT6AWE3zMjyrVxoA1V83qtCgh+EksDVt1e4w1NrwEqS/Q==|00001000000509465028||" }, "issuer": { "rfc": "PDE180514R21", "name": "PLATAFORMA DEMO", "tax_regime": "601", "postal_code": "11000" }, "receiver": { "rfc": "CDE170303B61", "name": "COMERCIALIZADORA DEMO", "tax_regime": "601", "postal_code": "64000", "email": null }, "third_party": null, "place_of_issue": "11000", "items": [ { "description": "Desarrollo de sistema a la medida", "quantity": 1, "unit_code": "E48", "unit_price": "50000.00", "product_code": "81111500", "tax_object": "02", "vat_rate": "0.16", "subtotal": "50000.00", "vat": "8000.00", "withholdings": null } ], "related_invoices": [], "payment_method": "PUE", "payment_form": "03", "cfdi_use": "G03", "currency": "MXN", "subtotal": "50000.00", "vat": "8000.00", "withholdings": null, "total": "58000.00", "cancellation": { "reason": "01", "replacement_uuid": "7D41C0A2-6B0E-4F2C-9A51-3E8D2B6F9C14", "requested_at": "2026-10-14T13:27:04.640Z", "cancelled_at": null }, "metadata": {}, "created_at": "2026-10-13T11:12:55.640Z", "stamped_at": "2026-10-13T11:12:58.740Z", "updated_at": "2026-10-14T13:27:04.640Z"}Issue an invoicePOST
Issues a CFDI 4.0. **Who issues it** - Your company: send nothing, or `issuer.company_id` to pick one of your companies. - A merchant: `issuer.merchant_id`. - A worker with their own CSD: `issuer.worker_id`. - heru, on a worker's behalf (the worker needs no CSD): `third_party.worker_id`. - Your company, on another taxpayer's behalf: `third_party` with their RFC. **Who receives it** - One of your companies, a worker or a merchant: `receiver.company_id`, `receiver.worker_id` or `receiver.merchant_id`. heru fills their SAT data. - Anyone else: `receiver` with their RFC, name, regime and postal code. **Which companies can issue.** It depends on the credential: see [Companies](/companies). **Files.** Get the XML or the PDF with `GET /invoices/{id}/download`, which needs the `invoices:download` scope. **Synchronous.** heru stamps the CFDI with the PAC before answering, usually in 2 to 5 seconds, and returns it with its folio fiscal. Wait up to 30 seconds. If the PAC or the SAT do not answer in time you get `503` and nothing is created: retry after `Retry-After` with the same `Idempotency-Key`. If the connection drops or you get another `5xx`, retry the same way: you get the CFDI that was already stamped, never a second one. Needs the `invoices:write` scope.
List invoicesGET
Most recent first. Needs the `invoices:read` scope.