1. Preparas XML o datos fiscales
Para timbrado, tu ERP genera el XML CFDI 4.0 y lo envía en base64. Para cancelación o consulta SAT, envía UUID, RFC emisor, RFC receptor, total y motivo cuando aplique.
SOATI E-Factura®
Integra tu ERP, e-commerce, sistema contable o desarrollo propio con SOATI E-Factura® para enviar XML CFDI 4.0 por HTTPS, consultar timbres disponibles, cancelar comprobantes y revisar estado SAT sin cambiar la captura principal de tu sistema.
Alcance técnico
La integración está pensada para sistemas que ya generan su XML CFDI y necesitan conectarse con SOATI para timbrar, consultar saldo de timbres, cancelar comprobantes o revisar estado SAT desde su propio flujo operativo.
Importante: si necesitas que SOATI genere el XML desde conceptos, clientes e impuestos, se revisa como un flujo adicional porque cambia el alcance fiscal y operativo.
Documentación técnica
El integrador envía una solicitud REST con headers de autenticación, clave de idempotencia y XML en base64. La URL final y credenciales se entregan durante la activación del servicio.
POST /efactura/v1/cfdi/timbrado
Host: soati.net
Content-Type: application/json
Accept: application/json
X-Api-User: usuario_api
X-Api-Key: soati_live_********
Idempotency-Key: ERP-FAC-2026-000001
X-Request-Id: 7f2a9c52-9d51-46b5-bcb4-646c88a7ad90
{
"rfc_emisor": "AAA010101AAA",
"external_reference": "FAC-2026-000001",
"response_format": "xml_pdf",
"xml_base64": "PD94bWwgdmVyc2lvbj0..."
} Flujo
Para timbrado, tu ERP genera el XML CFDI 4.0 y lo envía en base64. Para cancelación o consulta SAT, envía UUID, RFC emisor, RFC receptor, total y motivo cuando aplique.
La integración usa usuario técnico, API key e Idempotency-Key en headers. Las credenciales no viajan en la URL.
Se revisa autorización del RFC, formato de datos, idempotencia, disponibilidad de timbres, reglas de cancelación y trazabilidad antes de procesar la operación.
Tu sistema recibe XML/PDF timbrado, saldo de timbres, acuse de cancelación o estado SAT según el endpoint consumido.
Seguridad
La integración se plantea con buenas prácticas para APIs: transporte seguro, credenciales fuera de URL, idempotencia, límites de uso y trazabilidad para soporte.
Cada conexión opera con usuario técnico y llave propia. La llave puede regenerarse o revocarse sin exponer accesos principales.
El integrador usa una clave estable por documento para poder reintentar sin duplicar timbrados ni consumir operaciones de más.
El consumo se realiza por HTTPS con TLS 1.2 o superior. Usuario, API key y request_id se envían por headers, no por query string.
Cada solicitud conserva request_id, referencia externa, RFC, estatus, UUID, fecha, IP y respuesta pública útil para conciliación.
Los límites por minuto, día, usuario o IP ayudan a proteger el servicio contra reintentos agresivos o integraciones mal configuradas.
La respuesta separa el mensaje útil para el integrador del detalle técnico interno, evitando exponer información sensible.
Endpoints
Los endpoints se mantienen simples para facilitar integración desde cualquier ERP o lenguaje. La URL base de referencia es https://soati.net/efactura/v1; la URL final se confirma al activar el servicio.
| Método | Ruta | Uso |
|---|---|---|
| POST | /efactura/v1/cfdi/timbrado | Timbrar un XML CFDI recibido desde un ERP, e-commerce o sistema externo. |
| GET | /efactura/v1/cfdi/timbrado/{request_id} | Consultar el estado de una solicitud previa para conciliación o reintentos. |
| GET | /efactura/v1/timbres/estado | Consultar timbres disponibles para el RFC o grupo autorizado antes de procesar lotes. |
| POST | /efactura/v1/cfdi/cancelacion | Solicitar cancelación de un CFDI timbrado con motivo SAT y folio de sustitución cuando aplique. |
| POST | /efactura/v1/cfdi/consulta-sat | Consultar estado SAT, cancelabilidad y estatus de cancelación de un CFDI. |
| GET | /efactura/v1/health | Validar de forma controlada la disponibilidad del servicio. |
Headers
La API no usa sesión web ni cookies. La autenticación viaja por headers y cada documento debe llevar una clave de idempotencia para reintentos seguros.
| Header | Uso | Descripción |
|---|---|---|
X-Api-User | Obligatorio | Usuario técnico asignado a la integración. |
X-Api-Key | Obligatorio | Llave privada de consumo. Nunca debe enviarse en la URL ni guardarse en código público. |
Idempotency-Key | Obligatorio | Clave única por documento para reintentos seguros, por ejemplo ERP-FAC-2026-000001. |
Content-Type | Obligatorio | application/json para solicitudes estándar. |
Accept | Recomendado | application/json para XML/PDF en base64 o application/xml para recibir XML directo. |
X-Request-Id | Recomendado | Identificador generado por tu sistema para rastrear la operación extremo a extremo. |
Payload
Para reducir errores de integración, el XML viaja en base64 y el RFC emisor se valida contra la empresa autorizada para la llave técnica.
| Campo | Tipo | Req. | Descripción |
|---|---|---|---|
rfc_emisor | string | Sí | RFC de la empresa configurada y autorizada para la API. Debe coincidir con el XML. |
xml_base64 | string | Sí | XML CFDI 4.0 en base64. Se recomienda para evitar problemas de acentos y codificación. |
external_reference | string | No | Folio o referencia del ERP para conciliación interna. |
response_format | xml | xml_pdf | No | Define si la respuesta debe incluir solo XML timbrado o XML + PDF. |
Respuesta
La respuesta entrega lo necesario para que tu ERP cierre su operación: UUID, request_id, XML timbrado, PDF cuando aplique y datos de consumo para control interno.
Accept: application/xml.{
"status": "timbrado",
"request_id": "7f2a9c52-9d51-46b5-bcb4-646c88a7ad90",
"external_reference": "FAC-2026-000001",
"uuid": "11111111-2222-3333-4444-555555555555",
"xml_base64": "PD94bWwgdmVyc2lvbj0...",
"pdf_base64": "JVBERi0xLjQKJc...",
"timbres": {
"consumidos": 1,
"saldo_antes": 125,
"saldo_despues": 124
},
"pac": {
"codigo": "OK",
"mensaje": "Comprobante timbrado correctamente"
}
} Reintentos
Si tu sistema no recibe respuesta por timeout, no conviene crear una solicitud nueva a ciegas. Puedes consultar el estado por request_id o reenviar con la misma Idempotency-Key.
GET /efactura/v1/cfdi/timbrado/{request_id}
Accept: application/json
X-Api-User: usuario_api
X-Api-Key: soati_live_********
{
"request_id": "7f2a9c52-9d51-46b5-bcb4-646c88a7ad90",
"status": "timbrado",
"uuid": "11111111-2222-3333-4444-555555555555",
"external_reference": "FAC-2026-000001"
} Timbres disponibles
Antes de procesar lotes, jobs nocturnos o timbrados automáticos de alto volumen, tu ERP puede consultar los timbres disponibles para evitar que una operación se detenga a la mitad.
GET /efactura/v1/timbres/estado?rfc_emisor=AAA010101AAA
Accept: application/json
X-Api-User: usuario_api
X-Api-Key: soati_live_********
{
"status": "ok",
"rfc_emisor": "AAA010101AAA",
"timbres": {
"disponibles": 124,
"reservados": 0,
"consumidos_mes": 18
},
"actualizado_en": "2026-06-20T12:30:00-06:00",
"mensaje": "Saldo consultado correctamente"
} Cancelación CFDI
La API permite solicitar la cancelación de un CFDI previamente timbrado. Tu sistema conserva el control del flujo y SOATI devuelve una respuesta útil para guardar acuse, estado, cancelabilidad y seguimiento.
Cancelación simple
POST /efactura/v1/cfdi/cancelacion
Content-Type: application/json
Accept: application/json
X-Api-User: usuario_api
X-Api-Key: soati_live_********
Idempotency-Key: ERP-CAN-2026-000001
{
"rfc_emisor": "AAA010101AAA",
"rfc_receptor": "XAXX010101000",
"total": "116.00",
"uuid": "11111111-2222-3333-4444-555555555555",
"motivo_cancelacion": "02"
} Cancelación por sustitución
{
"rfc_emisor": "AAA010101AAA",
"rfc_receptor": "XAXX010101000",
"total": "116.00",
"uuid": "11111111-2222-3333-4444-555555555555",
"motivo_cancelacion": "01",
"folio_sustitucion": "22222222-3333-4444-5555-666666666666"
} | Campo | Tipo | Req. | Descripción |
|---|---|---|---|
rfc_emisor | string | Sí | RFC emisor autorizado para la llave de API. |
rfc_receptor | string | Sí | RFC receptor del CFDI que se desea cancelar. |
total | string | Sí | Total exacto del CFDI. Se recomienda enviarlo como texto con dos decimales. |
uuid | string | Sí | UUID fiscal del CFDI timbrado. |
motivo_cancelacion | string | Sí | Clave SAT de motivo: 01, 02, 03 o 04. |
folio_sustitucion | string | Condicional | UUID del CFDI sustituto. Es obligatorio cuando el motivo sea 01. |
La cancelación puede quedar aceptada, rechazada, en proceso o pendiente de aceptación del receptor, según las reglas SAT aplicables. Por eso tu ERP debe guardar el request_id y permitir consulta posterior.
{
"status": "cancelacion_procesada",
"request_id": "b5c88f37-1c95-46ef-9b46-44f43d80b629",
"uuid": "11111111-2222-3333-4444-555555555555",
"acuse_xml_base64": "PD94bWwgdmVyc2lvbj0...",
"estado": "Vigente",
"es_cancelable": "Cancelable con aceptación",
"estatus_cancelacion": "En proceso",
"estatus_uuid": "201",
"pac": {
"codigo": "OK",
"mensaje": "Solicitud de cancelación enviada correctamente"
}
} Consulta SAT
Cuando una cancelación queda en proceso, requiere aceptación o necesitas conciliar el estado fiscal de un comprobante, tu sistema puede consultar el estado SAT del CFDI con los datos fiscales del documento.
POST /efactura/v1/cfdi/consulta-sat
Content-Type: application/json
Accept: application/json
X-Api-User: usuario_api
X-Api-Key: soati_live_********
{
"rfc_emisor": "AAA010101AAA",
"rfc_receptor": "XAXX010101000",
"total": "116.00",
"uuid": "11111111-2222-3333-4444-555555555555"
} {
"status": "consulta_ok",
"request_id": "48d8801e-02ef-4b1f-8721-6c038bf69e46",
"uuid": "11111111-2222-3333-4444-555555555555",
"estado": "Vigente",
"es_cancelable": "Cancelable sin aceptación",
"estatus_cancelacion": "No cancelado",
"estatus_uuid": "200",
"pac": {
"codigo": "OK",
"mensaje": "Consulta SAT correcta"
}
} | Campo | Tipo | Req. | Descripción |
|---|---|---|---|
rfc_emisor | string | Sí | RFC emisor del CFDI. |
rfc_receptor | string | Sí | RFC receptor del CFDI. |
total | string | Sí | Total exacto del CFDI, preferentemente con dos decimales. |
uuid | string | Sí | UUID fiscal a consultar. |
Compatibilidad
La especificación usa estándares comunes: HTTPS, JSON, XML, códigos HTTP e idempotencia. Esto permite integrarla desde distintos lenguajes sin depender de un SDK propietario.
El ERP conserva captura, clientes, productos y control interno. SOATI recibe el XML y devuelve respuesta fiscal para guardar en el expediente.
Un servicio o job puede enviar XML sellados, guardar request_id, registrar UUID y evitar que el usuario dependa de una pantalla abierta.
La tienda genera el comprobante desde pedidos, usa una clave de idempotencia por orden y recibe XML timbrado para entrega al cliente.
Un proceso intermedio puede preparar el XML, llamar la API por HTTPS y devolver el resultado a SAP, sistemas propios o aplicaciones heredadas.
Escenarios
Usa una Idempotency-Key estable por serie/folio, guarda request_id, UUID y XML timbrado, y consulta estatus si hay timeout.
Ejecuta el timbrado desde un servicio o proceso controlado, no desde una pantalla que el usuario pueda cerrar durante la operación.
Consume con cURL, TLS verificado, credenciales fuera del directorio público y XML en base64 para evitar problemas de codificación.
Implementa cola, límites, reintentos con espera y conciliación por external_reference para mantener control administrativo.
Errores
Separar errores técnicos de errores fiscales ayuda a decidir cuándo reintentar, cuándo consultar estatus y cuándo corregir el XML antes de volver a timbrar.
| HTTP | Código | Cuándo aparece |
|---|---|---|
| 400 | REQUEST_INVALIDO | JSON inválido, XML faltante, base64 incorrecto o parámetro no soportado. |
| 401 | AUTH_INVALIDA | Usuario o API key incorrectos. |
| 403 | RFC_NO_AUTORIZADO | El RFC emisor no corresponde a la empresa autorizada para la llave. |
| 409 | IDEMPOTENCY_CONFLICT | La misma Idempotency-Key se reutilizó con un XML distinto. |
| 413 | XML_DEMASIADO_GRANDE | El XML excede el límite permitido para la operación. |
| 422 | CFDI_INVALIDO / PAC_RECHAZO | El XML no cumple reglas fiscales o fue rechazado por el PAC. |
| 422 | CANCELACION_RECHAZADA | Motivo inválido, UUID no localizable, CFDI no cancelable o folio de sustitución faltante. |
| 422 | CONSULTA_SAT_RECHAZADA | Los datos fiscales enviados no coinciden con el CFDI consultado. |
| 429 | RATE_LIMIT | Exceso de solicitudes por minuto, día, usuario o IP. |
| 502 / 503 | PAC_NO_DISPONIBLE | Dependencia temporal no disponible; conviene consultar estatus o reintentar con la misma clave. |
Implementación
El arranque se trabaja por etapas para que el ERP conserve su operación actual y el equipo técnico pueda validar credenciales, respuestas, errores e idempotencia antes de pasar a producción.
Confirmamos si tu sistema enviará XML CFDI ya formado o si necesitas un flujo adicional para construir documentos desde datos de operación.
Se habilita el servicio para el RFC emisor, el esquema de respuesta requerido y las condiciones de consumo contratadas.
Se entrega usuario de API, API key y lineamientos de resguardo para que tu equipo no coloque secretos en código público.
Validamos XML CFDI 4.0 representativos, respuesta del PAC, UUID, PDF, errores esperados y conciliación con tu referencia externa.
Tu sistema debe reutilizar la misma Idempotency-Key en timeouts o fallas temporales para evitar duplicados.
Se revisa monitoreo inicial, trazabilidad, consumo de timbres por volumen y soporte para ajustes de operación.
Troubleshooting
Estos casos ayudan a tu equipo técnico a diagnosticar sin exponer secretos ni depender de mensajes internos.
| Código | Causa probable | Acción sugerida |
|---|---|---|
AUTH_INVALIDA | Usuario o llave incorrecta, revocada o con espacios. | Revisar que la API key activa sea la vigente y no esté copiada con caracteres extra. |
RFC_NO_AUTORIZADO | El RFC del XML no coincide con la empresa asociada. | Validar RFC en XML, empresa configurada y usuario técnico asignado. |
CFDI_INVALIDO | El XML no cumple estructura CFDI 4.0. | Validar Anexo 20, namespaces, sello, certificado, importes y datos fiscales antes de reenviar. |
PAC_RECHAZO | El PAC devolvió una regla fiscal no cumplida. | Corregir el XML; no conviene reintentar sin cambios. |
IDEMPOTENCY_CONFLICT | Misma clave de idempotencia con XML distinto. | Usar una clave por documento y conservar el XML original para reintentos. |
TIMEOUT | La dependencia tardó más que el timeout del cliente. | Consultar estado por request_id o reenviar con la misma Idempotency-Key. |
CANCELACION_RECHAZADA | Motivo SAT inválido, UUID no localizable, CFDI no cancelable o sustitución faltante. | Revisar motivo, UUID, total y folio de sustitución cuando el motivo sea 01. |
CANCELACION_EN_PROCESO | La cancelación requiere tiempo adicional o aceptación del receptor. | Guardar request_id y consultar posteriormente el estado SAT del comprobante. |
CONSULTA_SAT_SIN_RESULTADO | Los datos fiscales no coinciden con el CFDI. | Validar RFC emisor, RFC receptor, total exacto y UUID antes de repetir la consulta. |
TIMBRES_INSUFICIENTES | El RFC o grupo autorizado no tiene saldo suficiente para timbrar. | Consultar timbres disponibles antes de procesos masivos y solicitar paquete si el saldo es bajo. |
Buenas prácticas
Estas reglas reducen duplicados, errores de soporte, exposición de credenciales y diferencias entre el folio interno del ERP y el CFDI timbrado.
Preguntas frecuentes
Esta integración está pensada para recibir XML CFDI ya formado y sellado por el sistema externo. Si necesitas que SOATI construya el XML desde datos de operación, se revisa como un flujo adicional porque cambia el alcance del proyecto.
La URL base de referencia es https://soati.net/efactura/v1. La URL final, credenciales y condiciones de uso se entregan al activar el servicio para tu empresa.
Sí. La integración puede configurarse para devolver solo XML timbrado o XML + PDF, según el flujo operativo contratado.
Usa una Idempotency-Key estable por documento. Si ocurre un timeout o falla temporal, reintenta con la misma clave o consulta el estado por request_id.
La integración contempla el endpoint GET /efactura/v1/timbres/estado para que tu sistema revise el saldo disponible antes de enviar lotes, procesos automáticos o timbrados de alto volumen.
Sí. Puede solicitar cancelación de CFDI timbrados usando el UUID, datos fiscales del comprobante, motivo SAT y folio de sustitución cuando el motivo sea 01.
Tu sistema debe guardar el request_id y consultar posteriormente el estado SAT del CFDI. Algunas cancelaciones pueden quedar en proceso o requerir aceptación del receptor.
Sí. Al usar HTTPS, JSON, XML y códigos HTTP, puede integrarse desde .NET, PHP, JavaScript, Python, Java, SAP, e-commerce, middleware o sistemas propios.
Guarda el request_id, UUID, XML timbrado, PDF cuando aplique, external_reference, fecha, HTTP status y mensaje de respuesta para conciliación y soporte.
Cuéntanos qué ERP o sistema quieres conectar, cuántos CFDI emites al día y si necesitas respuesta XML o XML + PDF.
También puedes escribir a contacto [arroba] soati.mx o llamar al (55) 5556-1730.