Cancelar una factura
POSThttps://api.cfdi.express/v1/invoices/{id}/cancelAPI keyIdempotency-Key
Cancela ante el SAT un CFDI timbrado, con motivo 01–04, y guarda el acuse de cancelación.
Los motivos son los del catálogo del SAT: 01 comprobante emitido con errores con relación (exige folioSustitucion, el UUID del CFDI que lo sustituye), 02 emitido con errores sin relación, 03 no se llevó a cabo la operación y 04 operación nominativa relacionada en una factura global.
La cancelación consume un timbre.
Autenticación
Authorization: Bearer sk_test_... | sk_live_...Parámetros
Parámetros de ruta
| Campo | Tipo | Descripción |
|---|---|---|
| idreq | string | Id de la factura. |
Headers
| Campo | Tipo | Descripción |
|---|---|---|
| Idempotency-Keyreq | string | Llave única de la operación de cancelación. |
Cuerpo (JSON)
| Campo | Tipo | Descripción |
|---|---|---|
| motivoreq | string | 01, 02, 03 o 04 del catálogo c_MotivoCancelacion. |
| folioSustitucion | string | UUID del CFDI que sustituye al cancelado. Obligatorio con motivo 01. |
Ejemplos
cURL
curl -X POST https://api.cfdi.express/v1/invoices/inv7k3q9x2m4v1t8p6d0n5cb/cancel \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: cancel_order_1001" \
-H "Content-Type: application/json" \
-d '{ "motivo": "02" }'cURL — motivo 01 con sustitución
curl -X POST https://api.cfdi.express/v1/invoices/inv7k3q9x2m4v1t8p6d0n5cb/cancel \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: cancel_order_1001_v2" \
-H "Content-Type: application/json" \
-d '{
"motivo": "01",
"folioSustitucion": "7a2c8e10-55b4-4c31-9a12-1d0e6f3b8c44"
}'Respuesta
202 Accepted
{
"id": "inv7k3q9x2m4v1t8p6d0n5cb",
"object": "invoice",
"status": "cancelled",
"uuid": "9f1b2c3d-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
"cancellation": {
"motivo": "02",
"folioSustitucion": null,
"status": "cancelled",
"chargedCentavos": 100,
"acuseUrl": "https://files.cfdi.express/acuse-9f1b2c3d.xml?X-Amz-Expires=900&...",
"requestedAt": "2026-08-18T18:02:44.310Z",
"resolvedAt": "2026-08-18T18:02:46.882Z"
}
}Errores
| Status | code | Cuándo aparece |
|---|---|---|
| 400 | validation_error | Motivo inválido, falta folioSustitucion con motivo 01, o la factura no está timbrada. |
| 401 | unauthorized | Falta el header Authorization o la llave es inválida. |
| 402 | insufficient_credits | No hay saldo para el timbre de cancelación. |
| 404 | not_found | La factura no existe en tu cuenta. |
| 422 | sat_rejected | El SAT rechazó la cancelación. |
| 503 | pac_unavailable | El PAC no está disponible. |
Notas
- Una factura PPD con complementos de pago vigentes no se puede cancelar: cancela primero los REPs con POST /v1/payments/{id}/cancel.
- El acuse XML del SAT queda disponible en
cancellation.acuseUrlcomo URL firmada de 15 minutos.
