Saltar al contenido principal

Emitir una Factura de Ingreso

Aprende cómo crear y timbrar una Factura de Ingreso (CFDI tipo "I") usando el endpoint POST /invoices. Este endpoint valida los datos, calcula impuestos, sella el CFDI con tu CSD y lo timbra automáticamente con el PAC.

¿Qué obtienes?

Un CFDI 4.0 timbrado con UUID fiscal, archivos XML y PDF, listo para entregar a tu cliente.


Endpoint

POST https://sandbox-api.lummy.com/invoices
Ambientes
  • Sandbox: https://sandbox-api.lummy.com
  • Producción: https://api.lummy.com

Autenticación y Headers

HeaderTipoObligatorioDescripción
Content-Typeapplication/jsonFormato del body
x-organization-idstring (UUID)ID de tu organización
x-api-keystringTu API Key
x-idempotencystring (UUID)UUID único para prevenir duplicados
Idempotencia

El header x-idempotency garantiza que no se dupliquen facturas. Si reenvías el mismo request con el mismo UUID, recibirás la factura original sin crear una nueva. Genera un UUID único por cada factura nueva.


Request Body

El body debe contener un JSON con la estructura del CFDI siguiendo el Anexo 20 del SAT. A continuación, un ejemplo completo de una factura de servicios profesionales:

Estructura JSON

{
"tipoDeComprobante": "I",
"receptor": {
"rfc": "XAXX010101000",
"nombre": "PUBLICO EN GENERAL",
"regimenFiscal": "616",
"domicilioFiscal": "06500"
},
"usoCFDI": "G03",
"metodoPago": "PUE",
"formaPago": "03",
"fecha": "2025-11-19T10:00:00",
"moneda": "MXN",
"exportacion": "01",
"lugarExpedicion": "06500",
"conceptos": [
{
"claveProdServ": "81111500",
"claveUnidad": "E48",
"descripcion": "Desarrollo de Software - Sistema Web a Medida",
"cantidad": 1,
"valorUnitario": 15000.0,
"objetoImp": "02",
"impuestos": {
"traslados": [
{
"base": 15000.0,
"impuesto": "002",
"tipoFactor": "Tasa",
"tasaOCuota": 0.16
}
]
}
}
]
}

Ejemplos de Código

A continuación, ejemplos funcionales en diferentes lenguajes para integrar el endpoint en tu sistema:

curl -X POST https://sandbox-api.lummy.com/invoices \
-H "Content-Type: application/json" \
-H "x-organization-id: ${LUMMY_ORG_ID}" \
-H "x-api-key: ${LUMMY_API_KEY}" \
-H "x-idempotency: $(uuidgen)" \
-d '{
"tipoDeComprobante": "I",
"receptor": {
"rfc": "XAXX010101000",
"nombre": "PUBLICO EN GENERAL",
"regimenFiscal": "616",
"domicilioFiscal": "06500"
},
"usoCFDI": "G03",
"metodoPago": "PUE",
"formaPago": "03",
"fecha": "2025-11-19T10:00:00",
"moneda": "MXN",
"exportacion": "01",
"lugarExpedicion": "06500",
"conceptos": [
{
"claveProdServ": "81111500",
"claveUnidad": "E48",
"descripcion": "Desarrollo de Software - Sistema Web a Medida",
"cantidad": 1,
"valorUnitario": 15000.00,
"objetoImp": "02",
"impuestos": {
"traslados": [
{
"base": 15000.00,
"impuesto": "002",
"tipoFactor": "Tasa",
"tasaOCuota": 0.16
}
]
}
}
]
}'
Variables de entorno

Define LUMMY_ORG_ID y LUMMY_API_KEY en tu shell:

export LUMMY_ORG_ID="your-organization-uuid"
export LUMMY_API_KEY="your-api-key"

Response

Respuesta Exitosa (HTTP 201 Created)

{
"invoiceId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"cfdiUuid": "cfa52b8b-93f2-4e6b-8c73-64ad88deb17c",
"verificationUrl": "https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=cfa52b8b-93f2-4e6b-8c73-64ad88deb17c&re=AAA010101AAA&rr=XAXX010101000&tt=17400.00&fe=/OAgdg==",
"xmlS3Url": "https://lummy-invoices.s3.amazonaws.com/cfdi/cfa52b8b-93f2-4e6b-8c73-64ad88deb17c.xml",
"pdfS3Url": "https://lummy-invoices.s3.amazonaws.com/cfdi/cfa52b8b-93f2-4e6b-8c73-64ad88deb17c.pdf"
}
CampoTipoDescripción
invoiceIdstring (UUID)ID interno de la factura en Lummy
cfdiUuidstring (UUID)UUID fiscal del SAT - Folio fiscal del CFDI timbrado
verificationUrlstring (URL)URL para verificar el CFDI en el portal del SAT
xmlS3Urlstring (URL)URL pública para descargar el XML timbrado
pdfS3Urlstring (URL)URL pública para descargar el PDF de la factura
Importante

El cfdiUuid es el Folio Fiscal oficial. Este UUID debe aparecer en todas las representaciones impresas del CFDI y es el identificador único que tu cliente usará para verificar la factura en el SAT.


Respuestas de Error

400 Bad Request - Datos Inválidos

{
"statusCode": 400,
"message": "RFC inválido: debe tener 12 o 13 caracteres",
"error": "Bad Request"
}

Causas comunes:

  • RFC con formato incorrecto
  • Claves de catálogo SAT inválidas (ej. claveProdServ, usoCFDI)
  • Fechas fuera del rango permitido por el SAT
  • Campos requeridos faltantes

404 Not Found - CSD No Encontrado

{
"statusCode": 404,
"message": "No se encontró CSD activo para la sucursal",
"error": "Not Found"
}

Solución: Verifica que tu organización tenga un Certificado de Sello Digital (CSD) vigente cargado en el sistema.


409 Conflict - Idempotencia Duplicada

{
"statusCode": 409,
"message": "La clave de idempotencia ya ha sido usada",
"error": "Conflict"
}

Solución: Si recibes este error, significa que ya existe una factura con ese x-idempotency. Genera un nuevo UUID si quieres crear una factura diferente.


Campos Obligatorios Explicados

exportacion

  • Valores: 01 (No aplica), 02 (Definitiva), 03 (Temporal)
  • Para ventas nacionales, siempre usa '01'

objetoImp

  • 01: No objeto de impuesto
  • 02: Sí objeto de impuesto (requiere nodo impuestos)
  • 03: Sí objeto de impuesto y NO obligado al desglose

claveProdServ

Clave del catálogo SAT de productos y servicios:

  • 81111500: Servicios de ingeniería de software
  • 84111506: Servicios de consultoría en tecnología
  • Buscar más claves aquí

claveUnidad

Unidad de medida del SAT:

  • E48: Unidad de servicio
  • H87: Pieza
  • KGM: Kilogramo

Notas Importantes

Cálculo Automático de Totales

No necesitas enviar los campos Subtotal, Total, ni Importe de conceptos. Nuestro sistema los calcula automáticamente según las reglas del SAT para garantizar precisión.

Zona Horaria

El campo fecha debe enviarse en hora local del lugar de expedición. El sistema ajustará automáticamente la zona horaria según el código postal de lugarExpedicion.

Transaccionalidad

Si el timbrado falla después de validar los datos, NO se consume un timbre de tu saldo. El sistema usa transacciones atómicas para garantizar consistencia.


Siguientes Pasos


Soporte

¿Necesitas ayuda? Contáctanos: