POST /api/invoices/upload
Uploads and processes a CFDI XML file (invoice or expense), performs fiscal validations, and saves it to the database.Authentication
Requires Bearer token authentication. The token must be included in theAuthorization header.
Rate Limiting
- Limit: 300 requests per 5 minutes per user
- Error Message: “Demasiadas solicitudes para procesar XML. Intenta nuevamente en unos minutos.”
Request
XML file containing the CFDI invoice. Must have
.xml extension.UUID of the profile to associate the invoice with. The profile must belong to the authenticated user.
Validation Rules
- File must have
.xmlextension - Profile must belong to authenticated user
- RFC must match profile (either as emisor or receptor)
- UUID must not be duplicated in the database
- Fiscal regime validation (if enabled in profile settings)
- For PPD invoices: applies existing payment complements automatically
Response
Success message: “Factura guardada exitosamente” or “Gasto guardado exitosamente”
The saved invoice or expense record
UUID of the saved record
UUID of the associated profile
Fiscal UUID from the CFDI
Invoice date (ISO 8601 format)
Month (1-12)
Year
Total amount including taxes
Subtotal before taxes
IVA amount
Transferred IVA amount
IVA withholding amount
ISR withholding amount
Payment type: “PUE” (paid in one payment), “PPD” (paid in installments), or “COMPLEMENTO_PAGO” (payment complement)
RFC of the issuer
Name of the issuer
Fiscal regime code of the issuer (3-digit SAT code)
RFC of the recipient
Name of the recipient
Fiscal regime code of the recipient
Description or concept of the invoice
Array of partial payments (for PPD invoices)
Payment complement data (if applicable)
Validation results
Whether RFC was verified
Whether fiscal regime was verified
Whether UUID is duplicated
Array of validation warnings
Array of validation errors
Whether the invoice passed all validations
Payment status information
Payment state: “PAGADO”, “PAGO_PARCIAL”, or “NO_PAGADO”
Total invoice amount
Total amount paid
Outstanding balance
Percentage paid (0-100)
Whether the invoice is fully paid
Whether payment complements exist
Whether manual payments exist
Validation state (same structure as above)
Record type: “factura” (invoice) or “gasto” (expense)
Error Codes
Bad Request
- Missing or invalid
profileId - No XML file provided
- File is not XML format
- CFDI doesn’t correspond to the profile
- CFDI failed fiscal validations
Unauthorized - User not authenticated
Not Found - Profile not found or doesn’t belong to user
Conflict - UUID already exists in database (duplicate CFDI)
Too Many Requests - Rate limit exceeded (300 requests per 5 minutes)
Internal Server Error - Unexpected error processing XML
Example Request
Example Response (Success)
Example Response (Error - Duplicate)
Example Response (Error - Validation Failed)
Notes
- The endpoint automatically determines if the CFDI is an invoice (ingreso) or expense (gasto) based on whether the profile’s RFC matches the emisor or receptor
- For PPD (installment payment) invoices, the system automatically applies any existing payment complements
- Payment complements (COMPLEMENTO_PAGO) are processed but not saved as invoices/expenses - they are used to update payment status of related invoices
- Validation rules can be customized per profile using the
validaciones_habilitadasconfiguration