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.


Estructura del Request

El cuerpo de la petición es un objeto JSON que representa el CrearComprobanteDto.

Objeto Principal: CrearComprobanteDto

CampoTipoRequeridoDescripciónCatálogo SAT
sucursalIdstring (UUID)OpcionalID de la sucursal emisora. Si se omite, se usa la matriz.
clienteIdstring (UUID)OpcionalID de un cliente existente. Si se provee, se ignora el objeto receptor.
receptorReceptorDtoCondicionalObjeto con los datos del receptor. Requerido si no se provee clienteId.
tipoDeComprobantestringObligatorioTipo de Comprobante. Para facturas de ingreso, usar I.c_TipoDeComprobante
usoCFDIstringCondicionalUso que el receptor le dará a la factura. Requerido si tipoDeComprobante es I o E.c_UsoCFDI
metodoPagostringCondicionalMétodo de pago. Requerido si tipoDeComprobante es I o E.c_MetodoPago
formaPagostringCondicionalForma de pago. Requerido si tipoDeComprobante es I o E.c_FormaPago
condicionesDePagostringOpcionalCondiciones comerciales aplicables para el pago del comprobante.
seriestringOpcionalSerie para el folio del comprobante.
foliostringOpcionalFolio del comprobante.
fechastring (ISO 8601)ObligatorioFecha y hora de expedición del comprobante.
monedastringObligatorioMoneda del comprobante.c_Moneda
tipoCambionumberCondicionalTipo de cambio. Requerido si moneda es diferente de MXN y XXX.
exportacionstringObligatorioClave que indica si el comprobante ampara una operación de exportación.c_Exportacion
lugarExpedicionstringObligatorioCódigo postal del lugar de expedición del comprobante.c_CodigoPostal
conceptosConceptoDto[]CondicionalArreglo de conceptos. Requerido si tipoDeComprobante no es P.
cfdiRelacionadosCfdiRelacionadosDtoOpcionalNodo para especificar información de CFDI relacionados.
informacionGlobalInformacionGlobalDtoCondicionalNodo para especificar información de la factura global. Requerido si el RFC del receptor es XAXX010101000.
complementoPagoComplementoPagoDtoCondicionalNodo para el Complemento de Recepción de Pagos. Requerido si tipoDeComprobante es P.
complementoCartaPorteComplementoCartaPorteDtoCondicionalNodo para el Complemento Carta Porte. Requerido si tipoDeComprobante es T.
addendastringOpcionalNodo XML de la addenda requerida por el cliente.
espaciosDeNombresEspacioDeNombreDto[]CondicionalArreglo de namespaces (xmlns) requeridos por la addenda. Requerido si se incluye addenda.
complementosComplementoGenericoDto[]OpcionalArreglo para otros complementos de factura.

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:

Objeto: ReceptorDto

CampoTipoRequeridoDescripciónCatálogo SAT
rfcstringObligatorioRFC del receptor.
nombrestringObligatorioNombre o Razón Social del receptor.
regimenFiscalstringObligatorioRégimen Fiscal del receptor.c_RegimenFiscal
domicilioFiscalstringObligatorioCódigo Postal del domicilio fiscal del receptor.c_CodigoPostal

Objeto: ConceptoDto

CampoTipoRequeridoDescripciónCatálogo SAT
descripcionstringObligatorioDescripción del concepto.
valorUnitarionumberObligatorioPrecio unitario del concepto.
cantidadnumberObligatorioCantidad de bienes o servicios del concepto.
claveProdServstringObligatorioClave de producto o servicio.c_ClaveProdServ
claveUnidadstringObligatorioClave de unidad de medida.c_ClaveUnidad
objetoImpstringObligatorioClave que indica si el concepto es objeto de impuesto.c_ObjetoImp
descuentonumberOpcionalMonto del descuento aplicable al concepto.
impuestosConceptoImpuestosDtoCondicionalNodo de impuestos del concepto. Requerido si objetoImp es 02.
aCuentaTercerosACuentaTercerosDtoOpcionalNodo para especificar información de cuenta de terceros.
cuentaPredialstringOpcionalNúmero de cuenta predial.
informacionAduaneraInformacionAduaneraDto[]OpcionalNodo para especificar información aduanera.
partesParteDto[]OpcionalNodo para especificar las partes del concepto.
complementoConceptostringOpcionalNodo XML del complemento de concepto.

Objeto: ConceptoImpuestosDto

CampoTipoRequeridoDescripción
trasladosConceptoTrasladoDto[]OpcionalArreglo de traslados de impuestos.
retencionesConceptoRetencionDto[]OpcionalArreglo de retenciones de impuestos.

Objeto: ConceptoTrasladoDto

CampoTipoRequeridoDescripciónCatálogo SAT
basenumberObligatorioBase imponible para el cálculo del impuesto.
impuestostringObligatorioClave del impuesto.c_Impuesto
tipoFactorstringObligatorioTipo de factor.c_TipoFactor
tasaOCuotanumberObligatorioTasa o cuota del impuesto.

Objeto: ConceptoRetencionDto

CampoTipoRequeridoDescripciónCatálogo SAT
basenumberObligatorioBase imponible para el cálculo del impuesto.
impuestostringObligatorioClave del impuesto.c_Impuesto
tipoFactorstringObligatorioTipo de factor.c_TipoFactor
tasaOCuotanumberObligatorioTasa o cuota del impuesto.