Respuestas y errores
Toda respuesta es JSON con code y message. El estado HTTP solo distingue éxito (200) de error (400); lo que pasó está en code.
Éxito y error
{
"message": "The document was generated successfully",
"code": 200,
"cfdi": { "UUID": "6F1A2B3C-4D5E-4F60-8172-93A4B5C6D7E8", "…": "…" }
}{
"message": "El CFDI no cumple con el esquema del SAT. Se encontró 1 error de validación. Revisa el campo 'errors' para el detalle.",
"code": 702,
"errorType": "cfdi_schema_validation",
"errors": [
{ "severity": "error", "field": "Rfc", "value": "ZKA010101JWY", "message": "Elemento 'Receptor', campo 'Rfc': …" }
]
}Cuerpo de un error
message- Qué pasó, en inglés o en español según el error. Algunos rechazos incluyen el texto del SAT.
code- El código de la API (601, 702, 5034…). No es el estado HTTP.
errorType- Categoría estable para tu código:
cfdi_schema_validation,json_type_validation,cartaporte_validation,timbre_previo… errors- El detalle, uno por problema, con
field,valueymessagecuando aplica. context- Datos extra, por ejemplo
{ "uuid": "…" }cuando el CFDI ya existe.
| HTTP | Cuándo |
|---|---|
| 200 | Éxito. También "no encontrado" en las consultas de autofactura y catálogos, que responden 200 con code "404". |
| 400 | Cualquier error de la petición, de tu cuenta, del esquema o del SAT. Lee code. |
| 401 / 403 | Solo GET /account/authorize: usuario o contraseña incorrectos, o bloqueo por intentos. |
| 405 | El método HTTP no existe en esa ruta (por ejemplo GET en /invoice/create). |
| 429 | Freno de reintentos idénticos (code 4290). Ver uso justo. |
Códigos de la API
| code | Qué significa | ¿Se reintenta? |
|---|---|---|
| 400 | Falta un parámetro, tiene otro formato o el SAT rechazó el CFDI (la clave va en message). | No: corrige primero. |
| 501 | La llave falta, no existe o es de otro ambiente. | No: revisa la llave. |
| 502 | Falta un parámetro obligatorio (en listados y validador). | No. |
| 601 | Tu cuenta no tiene folios o créditos. | Después de comprar. |
| 602 | Tu cuenta no tiene un CSD activo. | Después de cargarlo. |
| 625 | El UUID no está en tu cuenta (invoice/send). | No. |
| 702 | El XML no cumple el esquema del SAT. | No: errors[] dice qué campo. |
| 706 | No se pudo usar tu CSD. | Después de volver a cargarlo. |
| 4290 | Freno de una petición idéntica ya rechazada. | No: respeta Retry-After. |
| 5034 | El CFDI pudo haberse timbrado sin respuesta legible. | Verifica primero. |
| 5037 | No se pudo conectar con el proveedor de timbrado; no se envió nada. | Sí. |
| 5040 | Un problema del servidor antes de timbrar; no se envió nada. | Avísanos. |
Todos están en la matriz de errores con su mensaje exacto, junto a las claves del SAT.
Rechazos del SAT
Cuando el SAT o el proveedor de timbrado rechazan un CFDI, code es 400 y la clave de la matriz del SAT va al inicio de message. Separa la clave del texto con una expresión como ^([A-Za-z]+\d+)\s*-.
{
"message": "CFDI40143 - Este RFC del receptor no existe en la lista de RFC inscritos no cancelados del SAT.",
"code": 400
}El texto que sigue a la clave puede cambiar cuando el SAT actualiza su matriz; la clave no. Un rechazo del SAT no usa folio y se repite igual mientras el dato no cambie.
Respuesta incierta: 5034
Un 5034 dice que la petición llegó al proveedor de timbrado y no volvió una respuesta legible. El CFDI pudo quedar timbrado en el SAT. La respuesta trae la serie y el folio que se usaron y, si se pudo leer, context.uuid.
{
"message": "El PAC no respondió a tiempo: tu factura pudo haberse timbrado en el SAT aunque no aparezca en tus CFDIs emitidos. Revisa tu buzón o el portal del SAT antes de volver a intentar. Se usó la serie A folio 1001.",
"code": 5034,
"Serie": "A",
"Folio": "1001"
}- Si viene
context.uuid, el CFDI existe: guárdalo y no lo reenvíes. - Si no, búscalo por su serie y folio en tus listados (
GET /invoice/listbydaterange) unos minutos después, o en el portal del SAT. - Solo si no aparece, reintenta. Si reintentas con la misma
Fechay el mismoFolioque mandaste antes, y el primero sí se timbró, la API respondetimbre_previocon su UUID en lugar de duplicarlo.
Uso justo
Cada cuenta tiene 10,000 respuestas de rechazo al día sin costo. Un rechazo es una respuesta 4xx a una petición con llave válida. Los rechazos del SAT por los datos capturados (claves CFDI40xxx) y los 702 por un dato mal formado no cuentan, tampoco lo que piden las pantallas de la propia plataforma.
Si tu integración rebasa el límite, te avisamos antes de cualquier cargo. Con un excedente pendiente se puede activar, a mano, un freno: la API responde HTTP 429 con code 4290 y el encabezado Retry-After a una petición idéntica a otra que ya rechazó en las últimas 24 horas. Las peticiones nuevas o distintas siguen funcionando. Los detalles están en la Política de uso justo de la API.
Formato
- JSON en UTF-8. Manda
Accept: application/jsono no mandesAccept. - Las fechas van en hora del centro de México y sin zona:
2026-11-03 10:15:42o2026-11-03T10:15:42. - Los listados regresan los valores de la base como texto:
"1160.000000","1". - La API se llama de servidor a servidor. Muchos parámetros van en encabezados que un navegador no puede mandar a otro dominio, y la llave nunca debe estar en el navegador.
Revisado contra la API v5 en producción el 2026-11-03.