Timbrar XML sellado
Si tu sistema ya arma el XML del CFDI 4.0 y lo sella con tu CSD, mándalo tal cual y la API solo lo timbra. Es el camino más corto: no hay que traducir tu XML a nuestro JSON.
POST
/invoice/stampxmlPOST
/invoice/stampxmlfileCuándo usarlo
Úsalo si tu ERP ya genera la cadena original y el sello. Si prefieres mandar los datos y que nosotros armemos y sellemos el XML, usa Crear un CFDI. Las dos rutas usan 1 folio por CFDI timbrado.
| stampxml / stampxmlfile | create | |
|---|---|---|
| Quién arma y sella el XML | Tu sistema, con tu CSD. | La API, con el CSD cargado en tu cuenta. |
| Validación antes de timbrar | La del proveedor de timbrado y el SAT. | Tipos del JSON, esquema del SAT (702) y luego el SAT. |
| Queda en tus CFDI emitidos | No: no aparece en los listados ni se puede enviar con invoice/send. | Sí. |
No se genera: arma el tuyo con XmlBase64. | Sí, con tu plantilla. |
Mandar el XML en Base64
POST
/invoice/stampxmlCuerpo (formulario)
xmlbase64- El XML del CFDI 4.0, completo y sellado, en Base64 estándar. Codifica el cuerpo del formulario: un
+sin codificar llega como espacio y rompe el XML.
# El XML ya sellado con tu CSD, en Base64 y codificado para el formulario
curl -sS -X POST "$FD_API/invoice/stampxml" \
-H "X-Api-Key: $FD_API_KEY" \
--data-urlencode "xmlbase64=$(base64 < factura-sellada.xml | tr -d '\n')"Mandar el XML como archivo
POST
/invoice/stampxmlfileCuerpo (multipart/form-data)
xml- El archivo
.xmldel CFDI sellado, hasta 40 MB. Deja que tu cliente HTTP ponga elContent-Type: multipart/form-datacon suboundary; si lo fijas a mano como formulario normal, el archivo no llega.
curl -sS -X POST "$FD_API/invoice/stampxmlfile" \
-H "X-Api-Key: $FD_API_KEY" \
-F "xml=@factura-sellada.xml"La respuesta
Las dos rutas responden igual. El XML timbrado completo viene en cfdi.XmlBase64: guárdalo, es tu comprobante.
{
"message": "XML stamped successfully",
"code": 200,
"cfdi": {
"NoCertificado": "30001000000500003416",
"UUID": "6F0C2E1A-9B3D-4C7E-8A51-2D4F6B8C0E13",
"FechaTimbrado": "2026-11-03T10:15:30",
"RfcProvCertif": "AAA010101AAA",
"SelloCFD": "Q2V4...Zm9vYmFy",
"NoCertificadoSAT": "30001000000500003456",
"SelloSAT": "Tm9w...ZGF0YQ==",
"CadenaOrigTFD": "||1.1|6F0C2E1A-9B3D-4C7E-8A51-2D4F6B8C0E13|2026-11-03T10:15:30|AAA010101AAA|Q2V4...Zm9vYmFy|30001000000500003456||",
"CadenaQR": "https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=6F0C2E1A-…",
"XmlBase64": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4...",
"PDF": "https://app.facturadigital.com.mx/docs/pdf/6F0C2E1A-9B3D-4C7E-8A51-2D4F6B8C0E13",
"XML": "https://app.facturadigital.com.mx/docs/xml/EKU9003173C9/6F0C2E1A-9B3D-4C7E-8A51-2D4F6B8C0E13"
}
}CadenaOrigTFDes la cadena original del timbre fiscal digital, para tu PDF.CadenaQRes la URL de verificación del SAT para el código QR de tu PDF.XMLdescarga el XML timbrado siempre que el RFC emisor del XML sea el de tu cuenta.PDFno se genera para un XML timbrado así; arma tu representación impresa conXmlBase64.
Errores
| code | Cuándo pasa | Qué hacer |
|---|---|---|
| 400 | Falta xmlbase64 (o el archivo xml), o el archivo no es .xml. | Revisa el nombre del campo y el tipo de cuerpo. |
| 400 + clave del SAT | El SAT o el proveedor rechazaron el XML: sello, esquema o una regla de la matriz. La clave va al inicio de message. | Búscala en la matriz de errores y corrige el XML. |
400 + timbre_previo | Ese mismo XML ya se había timbrado. context.uuid trae el UUID y no se cobra otro folio. | Usa ese UUID; no lo vuelvas a enviar. |
| 601 | Tu cuenta no tiene folios. | Compra folios. |
| 5037 | No se pudo conectar con el proveedor de timbrado; no se envió nada. | Reintenta tal cual en unos minutos. |
| 5034 | El proveedor no respondió a tiempo: el CFDI pudo haberse timbrado. | No reenvíes a ciegas. Si context.uuid viene, ese es tu UUID; si no, revisa en el SAT antes de reintentar. |
Revisado contra la API v5 en producción el 2026-11-03.