Cancelación por UUID
Cancela un CFDI directamente por su UUID, sin enviar tus Certificados de Sello Digital en la petición. Timbra resuelve la firma con el CSD configurado en tu cuenta.
Tienes dos variantes del mismo servicio:
- Con un cuerpo JSON.
- Con los parámetros en la ruta de la URL.
Variante 1: JSON
Cancela un CFDI por UUID enviando un objeto JSON.
Request
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
uuid | string | Sí | UUID del CFDI que quieres cancelar. |
motivo | string | No | Motivo de cancelación del SAT. Por defecto 03. |
folio_sustituto | string | Condicional | UUID del CFDI sustituto. Obligatorio cuando motivo es 01. |
rfc | string | No | RFC del emisor. Si se omite, se usa el RFC asociado a la API Key. |
json
{
"uuid": "A1B2C3D4-5E6F-7890-ABCD-EF1234567890",
"motivo": "02",
"folio_sustituto": ""
}Ejemplo
bash
curl -X POST "https://dashboard.timbra.com.mx/api/masivo/cfdi33/cancel/uuid" \
-H "Authorization: Bearer tmb_live_tu_api_key_aqui" \
-H "Content-Type: application/json" \
-d '{
"uuid": "A1B2C3D4-5E6F-7890-ABCD-EF1234567890",
"motivo": "02",
"folio_sustituto": ""
}'js
const response = await fetch(
'https://dashboard.timbra.com.mx/api/masivo/cfdi33/cancel/uuid',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TIMBRA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
uuid: 'A1B2C3D4-5E6F-7890-ABCD-EF1234567890',
motivo: '02',
folio_sustituto: ''
})
}
)
const result = await response.json()
if (!response.ok) {
throw new Error(result.message)
}
console.log('Acuse:', result.data.acuse)python
import os
import requests
response = requests.post(
"https://dashboard.timbra.com.mx/api/masivo/cfdi33/cancel/uuid",
headers={
"Authorization": f"Bearer {os.environ['TIMBRA_API_KEY']}",
"Content-Type": "application/json",
},
json={
"uuid": "A1B2C3D4-5E6F-7890-ABCD-EF1234567890",
"motivo": "02",
"folio_sustituto": "",
},
)
result = response.json()
if response.status_code != 200:
raise Exception(result["message"])
print("Acuse:", result["data"]["acuse"])Variante 2: parámetros en la URL
Cancela un CFDI por UUID con los datos en la ruta.
Parámetros
| Parámetro | Obligatorio | Descripción |
|---|---|---|
rfc | Sí | RFC del emisor del CFDI. |
uuid | Sí | UUID del CFDI que quieres cancelar. |
motivo | Sí | Motivo de cancelación del SAT (01, 02, 03 o 04). |
folioSustituto | Condicional | UUID del CFDI sustituto. Obligatorio cuando el motivo es 01. |
Ejemplo
http
POST /api/masivo/cfdi33/cancel/EKU9003173C9/A1B2C3D4-5E6F-7890-ABCD-EF1234567890/02bash
curl -X POST "https://dashboard.timbra.com.mx/api/masivo/cfdi33/cancel/EKU9003173C9/A1B2C3D4-5E6F-7890-ABCD-EF1234567890/02" \
-H "Authorization: Bearer tmb_test_tu_api_key_aqui"js
const rfc = 'EKU9003173C9'
const uuid = 'A1B2C3D4-5E6F-7890-ABCD-EF1234567890'
const motivo = '02'
const response = await fetch(
`https://dashboard.timbra.com.mx/api/masivo/cfdi33/cancel/${rfc}/${uuid}/${motivo}`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TIMBRA_API_KEY}`
}
}
)
const result = await response.json()
if (!response.ok) {
throw new Error(result.message)
}
console.log('Acuse:', result.data.acuse)python
import os
import requests
rfc = "EKU9003173C9"
uuid = "A1B2C3D4-5E6F-7890-ABCD-EF1234567890"
motivo = "02"
response = requests.post(
f"https://dashboard.timbra.com.mx/api/masivo/cfdi33/cancel/{rfc}/{uuid}/{motivo}",
headers={"Authorization": f"Bearer {os.environ['TIMBRA_API_KEY']}"},
)
result = response.json()
if response.status_code != 200:
raise Exception(result["message"])
print("Acuse:", result["data"]["acuse"])Para incluir un folio sustituto, agrega el UUID al final de la ruta:
http
POST /api/masivo/cfdi33/cancel/EKU9003173C9/A1B2C3D4-5E6F-7890-ABCD-EF1234567890/01/B2C3D4E5-6F70-8901-BCDE-F23456789012Response
Ambas variantes responden con la misma estructura:
json
{
"status": "success",
"data": {
"msg": "Se ha cancelado correctamente",
"uuid": "A1B2C3D4-5E6F-7890-ABCD-EF1234567890",
"acuse": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Acuse ...>"
}
}data.acuse contiene el acuse de cancelación en XML.
Errores
| HTTP | Causa |
|---|---|
400 | Falta uuid o algún parámetro obligatorio de la ruta. |
400 | El motivo no es válido o falta el folio sustituto cuando el motivo es 01. |
400 | El RFC del emisor no es un RFC de prueba válido en Sandbox. |
400 | El SAT o el PAC rechazaron la cancelación. El detalle viene en message. |
401 | La API Key falta, es inválida o fue revocada. |
500 | Error interno al procesar la cancelación. |
Ejemplo cuando falta el UUID:
json
{
"status": "error",
"message": "El parámetro \"uuid\" es requerido."
}Notas
- La cancelación no consume timbres.
- En modo Test, el RFC del emisor debe ser uno de los RFCs de prueba del SAT. Consulta Ambientes Live y Test.
- El RFC de la ruta o del body debe coincidir con el emisor del CFDI.
- Si necesitas firmar con certificados que no están configurados en tu cuenta, usa Cancelación por CSD.
- Guarda el acuse de cancelación como comprobante de la operación.