> ## Documentation Index
> Fetch the complete documentation index at: https://docs.contafy.com.mx/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload Invoice

> Upload a CFDI XML invoice file

## Authentication

This endpoint requires authentication. Include your access token in the Authorization header.

```
Authorization: Bearer YOUR_ACCESS_TOKEN
```

## Request Body

This endpoint expects a multipart/form-data request with the following fields:

<ParamField body="xml" type="file" required>
  XML file containing the CFDI invoice. The file must be a valid Mexican CFDI XML.
</ParamField>

<ParamField body="profileId" type="string" required>
  Profile ID to associate the invoice with. The system automatically determines if the invoice is an income (factura) or expense (gasto) based on the RFC in the XML.
</ParamField>

## Response

<ResponseField name="message" type="string">
  Success message
</ResponseField>

<ResponseField name="data" type="Invoice">
  The created invoice object

  <Expandable title="Invoice">
    <ResponseField name="id" type="string">
      Unique identifier for the invoice
    </ResponseField>

    <ResponseField name="profile_id" type="string">
      Profile ID this invoice belongs to
    </ResponseField>

    <ResponseField name="uuid" type="string">
      CFDI UUID (Folio Fiscal)
    </ResponseField>

    <ResponseField name="fecha" type="string">
      Invoice date in ISO format
    </ResponseField>

    <ResponseField name="mes" type="number">
      Month extracted from invoice date (1-12)
    </ResponseField>

    <ResponseField name="año" type="number">
      Year extracted from invoice date
    </ResponseField>

    <ResponseField name="total" type="number">
      Total amount of the invoice
    </ResponseField>

    <ResponseField name="subtotal" type="number">
      Subtotal before taxes
    </ResponseField>

    <ResponseField name="iva" type="number">
      IVA percentage rate
    </ResponseField>

    <ResponseField name="iva_amount" type="number" optional>
      IVA transferred amount
    </ResponseField>

    <ResponseField name="retencion_iva_amount" type="number" optional>
      IVA withholding amount
    </ResponseField>

    <ResponseField name="retencion_isr_amount" type="number" optional>
      ISR withholding amount
    </ResponseField>

    <ResponseField name="tipo" type="enum">
      Payment type: `PUE`, `PPD`, or `COMPLEMENTO_PAGO`
    </ResponseField>

    <ResponseField name="rfc_emisor" type="string">
      RFC of the issuer
    </ResponseField>

    <ResponseField name="nombre_emisor" type="string">
      Name of the issuer
    </ResponseField>

    <ResponseField name="regimen_fiscal_emisor" type="string" optional>
      Tax regime code of the issuer
    </ResponseField>

    <ResponseField name="rfc_receptor" type="string">
      RFC of the recipient
    </ResponseField>

    <ResponseField name="nombre_receptor" type="string">
      Name of the recipient
    </ResponseField>

    <ResponseField name="regimen_fiscal_receptor" type="string" optional>
      Tax regime code of the recipient
    </ResponseField>

    <ResponseField name="concepto" type="string" optional>
      Invoice concept or description
    </ResponseField>

    <ResponseField name="pagos" type="array">
      Array of payment records
    </ResponseField>

    <ResponseField name="complemento_pago" type="object" optional>
      Payment complement information (for COMPLEMENTO\_PAGO type)
    </ResponseField>

    <ResponseField name="validacion" type="object">
      Validation results for the uploaded invoice
    </ResponseField>

    <ResponseField name="created_at" type="string">
      Creation timestamp in ISO format
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      Last update timestamp in ISO format
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="validacion" type="object">
  Validation state of the uploaded invoice

  <Expandable title="ValidationState">
    <ResponseField name="rfcVerificado" type="boolean">
      Whether RFC was verified against profile
    </ResponseField>

    <ResponseField name="regimenFiscalVerificado" type="boolean">
      Whether tax regime was verified
    </ResponseField>

    <ResponseField name="uuidDuplicado" type="boolean">
      Whether this UUID already exists in the system
    </ResponseField>

    <ResponseField name="advertencias" type="string[]">
      Array of warning messages that don't prevent upload
    </ResponseField>

    <ResponseField name="errores" type="string[]">
      Array of error messages (empty if valid)
    </ResponseField>

    <ResponseField name="valido" type="boolean">
      Overall validation status
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="tipo" type="enum">
  Classification of the invoice: `factura` (income) or `gasto` (expense)
</ResponseField>

## Example Request

```bash theme={null}
curl -X POST "https://api.contafy.com/api/invoices/upload" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "xml=@invoice.xml" \
  -F "profileId=prof_123"
```

```javascript theme={null}
const formData = new FormData();
formData.append('xml', file);
formData.append('profileId', 'prof_123');

const response = await fetch('https://api.contafy.com/api/invoices/upload', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  },
  body: formData
});

const data = await response.json();
```

## Example Response

```json theme={null}
{
  "message": "Factura procesada exitosamente",
  "data": {
    "id": "inv_abc123",
    "profile_id": "prof_123",
    "uuid": "12345678-90AB-CDEF-1234-567890ABCDEF",
    "fecha": "2026-03-15T10:30:00Z",
    "mes": 3,
    "año": 2026,
    "total": 11600.00,
    "subtotal": 10000.00,
    "iva": 16,
    "iva_amount": 1600.00,
    "tipo": "PUE",
    "rfc_emisor": "XAXX010101000",
    "nombre_emisor": "Empresa Ejemplo SA de CV",
    "regimen_fiscal_emisor": "601",
    "rfc_receptor": "BAXX010101000",
    "nombre_receptor": "Cliente Ejemplo",
    "regimen_fiscal_receptor": "612",
    "concepto": "Servicios de consultoría",
    "pagos": [],
    "complemento_pago": null,
    "validacion": {
      "rfcVerificado": true,
      "regimenFiscalVerificado": true,
      "uuidDuplicado": false,
      "advertencias": [],
      "errores": [],
      "valido": true
    },
    "created_at": "2026-03-15T10:35:00Z",
    "updated_at": "2026-03-15T10:35:00Z"
  },
  "validacion": {
    "rfcVerificado": true,
    "regimenFiscalVerificado": true,
    "uuidDuplicado": false,
    "advertencias": [],
    "errores": [],
    "valido": true
  },
  "tipo": "factura"
}
```

## Error Responses

<ResponseField name="401 Unauthorized">
  ```json theme={null}
  {
    "error": "Unauthorized",
    "message": "Invalid or missing access token"
  }
  ```
</ResponseField>

<ResponseField name="400 Bad Request">
  ```json theme={null}
  {
    "error": "Bad Request",
    "message": "Invalid XML file or missing required fields"
  }
  ```
</ResponseField>

<ResponseField name="409 Conflict">
  ```json theme={null}
  {
    "error": "Conflict",
    "message": "Invoice with this UUID already exists",
    "validacion": {
      "uuidDuplicado": true,
      "valido": false
    }
  }
  ```
</ResponseField>

<ResponseField name="422 Unprocessable Entity">
  ```json theme={null}
  {
    "error": "Unprocessable Entity",
    "message": "Invalid CFDI XML format",
    "validacion": {
      "errores": ["Invalid XML structure"],
      "valido": false
    }
  }
  ```
</ResponseField>

<ResponseField name="500 Internal Server Error">
  ```json theme={null}
  {
    "error": "Internal Server Error",
    "message": "An unexpected error occurred"
  }
  ```
</ResponseField>
