Cancelar un CFDI de retenciones
Cancela ante el SAT una constancia de retenciones ya timbrada, con motivo 01–04.
Desde la v1.43.0. Los motivos son los del catálogo del SAT: 01 comprobante emitido con errores con relación (exige folioSustitucion, el UUID de la constancia que la 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.
Consume un timbre. Responde 202 con el recurso: el estatus y el acuse quedan en él. En retenciones el SAT usa los mismos estatus que en un CFDI, con un 1 delante: 1201 cancelada y 1202 ya estaba cancelada. Exige Idempotency-Key.
Si cancelas justo después de timbrar, el SAT puede responder CR1205 - UUID No existe durante cerca de un minuto. Ese intento se reembolsa; hay que reintentar después.
Por MCP, cancel_retencion acepta el mismo cuerpo. Al completarse se puede avisar con el webhook retencion.cancelled.
Authorization: Bearer sk_test_... | sk_live_...El header x-account-id indica la cuenta. Si no eres miembro, la respuesta es 403.
Parámetros
Parámetros de ruta
| Campo | Tipo | Descripción |
|---|---|---|
| idreq | string | Id de la retención. |
Headers
| Campo | Tipo | Descripción |
|---|---|---|
| Idempotency-Keyreq | string | Llave única de la operación de cancelación, de 1 a 255 caracteres. |
Cuerpo (JSON)
| Campo | Tipo | Descripción |
|---|---|---|
| motivoreq | string | 01, 02, 03 o 04. |
| folioSustitucion | string | UUID del CFDI que sustituye al cancelado. Obligatorio con motivo 01. |
Ejemplos
curl -X POST https://api.cfdi.express/v1/retenciones/ret7k3q9x2m4v1t8p6d0n5cb/cancel \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: cancel-retencion-2026-09-prestador-42" \
-H "Content-Type: application/json" \
-d '{ "motivo": "02" }'Respuesta
{
"id": "ret7k3q9x2m4v1t8p6d0n5cb",
"object": "retencion",
"status": "cancelled",
"uuid": "9f1b2c3d-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
"cveRetenc": "26",
"ejercicio": 2026,
"mes": 9
}Errores
| Status | code | Cuándo aparece |
|---|---|---|
| 400 | validation_error | Motivo inválido o falta folioSustitucion con motivo 01. |
| 401 | unauthorized | Falta el header Authorization o la llave es inválida. |
| 402 | insufficient_credits | No hay saldo para el timbre de la cancelación. |
| 404 | not_found | La retención no existe en tu cuenta. |
| 422 | sat_rejected | El SAT rechazó la cancelación. |
| 503 | pac_unavailable | El PAC no está disponible. |
Notas
- El 202 trae el recurso con su
statusy el acuse encancellation. El OpenAPI publicado no detalla los campos internos decancellation.
