# LatAm E-Invoice Parser: DIAN, CFDI 4.0 and NF-e to JSON (`ceibadata/latam-einvoice-parser`) Actor

Turn Latin American electronic invoice XML (Colombia DIAN UBL 2.1 and AttachedDocument, Mexico CFDI 3.3/4.0 with Pagos 2.0, Brazil NF-e 4.00) into clean, normalized JSON with totals, taxes, withholdings, line items and validation status. Accepts XML or ZIP URLs and raw XML.

- **URL**: https://apify.com/ceibadata/latam-einvoice-parser.md
- **Developed by:** [Ceiba Data](https://apify.com/ceibadata) (community)
- **Categories:** Developer tools, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 parsed documents

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## LatAm E-Invoice Parser: DIAN, CFDI 4.0 and NF-e to JSON

Turn Latin American electronic invoice XML into clean, normalized JSON in one call. One schema for **Colombia (DIAN UBL 2.1)**, **Mexico (CFDI 3.3 and 4.0)** and **Brazil (NF-e 4.00)**: seller and buyer tax IDs, totals, taxes and withholdings, line items, and whether the tax authority validated the document.

| Country | Documents | Highlights |
|---|---|---|
| 🇨🇴 Colombia | Factura electrónica (Invoice), nota crédito, nota débito, documento soporte, and the **AttachedDocument** container that suppliers email | CUFE/CUDE, NIT with check digit, IVA, INC, ICA, ReteIVA, ReteRenta, ReteICA, DIAN authorization range, and the DIAN validation result inside the AttachedDocument |
| 🇲🇽 Mexico | CFDI 3.3 and 4.0: ingreso, egreso, traslado, nómina, pago | UUID and Timbre Fiscal Digital, RFC, régimen and uso CFDI, IVA/IEPS/ISR transfers and withholdings, **Pagos 2.0** payments with related invoices |
| 🇧🇷 Brazil | NF-e and NFC-e 4.00 (nfeProc or bare NFe) | 44-digit access key, CNPJ/CPF, NCM, CFOP, ICMS/IPI/PIS/COFINS per item and totals, payment method (PIX, boleto…), SEFAZ authorization status |

### Why use it

- **Accounts payable automation**: read the invoices your suppliers send and load them into your ERP or spreadsheet without retyping.
- **Colombian email ZIPs work as they arrive**: pass the ZIP link and the Actor finds the XML, unwraps the AttachedDocument and reads the DIAN's "Documento validado por la DIAN" response.
- **One schema for three countries**: build your pipeline once for CO, MX and BR.
- **AI agents**: give an agent a reliable tool for invoice data instead of asking it to read XML. Works through the Apify MCP server.

No website is scraped. The Actor only downloads the files you link to (or reads the XML you send) and parses them.

### How to use it

1. Add links to `.xml` or `.zip` files in **XML or ZIP file URLs**, or send raw XML in **Raw XML** from the API.
2. Keep **Include line items** on if you need products and services; turn on **One row per line item** for a spreadsheet-friendly table.
3. Run the Actor and export the dataset as JSON, CSV or Excel, or read it from the API.

Want to see the output first? Start the Actor with no input: it parses a built-in sample CFDI for free (the row has `"demo": true`).

### Output example (Colombia, AttachedDocument)

```json
{
  "source": "https://example.com/FE1023.zip#FE1023.xml",
  "status": "ok",
  "country": "CO",
  "format": "DIAN_UBL_2.1",
  "documentType": "invoice",
  "number": "FE1023",
  "uniqueId": "cufe-sha384…",
  "issueDate": "2026-10-20T10:15:30-05:00",
  "currency": "COP",
  "seller": { "taxId": "900123456", "taxIdCheckDigit": "8", "taxIdType": "NIT", "name": "Software Andino S.A.S.", "city": "Bogotá, D.C." },
  "buyer": { "taxId": "901234567", "taxIdCheckDigit": "7", "taxIdType": "NIT", "name": "Distribuciones El Ceibo S.A.S.", "city": "Medellín" },
  "totals": { "subtotal": 1200000, "taxes": 228000, "withholdings": 48000, "total": 1428000, "payable": 1428000 },
  "taxes": [
    { "type": "IVA", "code": "01", "rate": 19, "base": 1200000, "amount": 228000, "withheld": false },
    { "type": "ReteRenta", "code": "06", "rate": 4, "base": 1200000, "amount": 48000, "withheld": true }
  ],
  "validation": { "status": "validated", "code": "02", "message": "Documento validado por la DIAN" },
  "warnings": []
}
```

Mexican documents report `validation.status` as `stamped` or `not_stamped` (Timbre Fiscal Digital), and Brazilian ones as `authorized` with the SEFAZ `cStat` and protocol number.

### Use cases

- **Accounts payable**: turn supplier XML invoices into rows for your ERP or spreadsheet.
- **Accounting firms**: consolidate DIAN, CFDI and NF-e documents from clients in several countries in one schema.
- **Expense and tax tools**: read totals, taxes and line items without writing three parsers.
- **AI agents**: give an agent the invoice XML and get structured JSON back to reason about.

### Use with AI agents (MCP)

Every Apify Actor is also a tool for AI agents. Add this Actor to Claude, Cursor, VS Code or any MCP client with the Apify MCP server:

```text
https://mcp.apify.com?tools=ceibadata/latam-einvoice-parser
```

Or run it locally:

```bash
npx -y @apify/actors-mcp-server --tools ceibadata/latam-einvoice-parser
```

Then just ask, for example:

> Parse this electronic invoice XML and give me the issuer, total, taxes and line items: https://example.com/invoices/factura-001.xml

#### Example input (API / AI agents)

```json
{
  "xmlUrls": [
    "https://example.com/invoices/factura-001.xml"
  ],
  "includeLines": true
}
```

From code, one call returns the results:

```bash
curl -X POST "https://api.apify.com/v2/acts/ceibadata~latam-einvoice-parser/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' -d @input.json
```

### Pricing

You pay per document parsed successfully, whatever its number of lines. Files that cannot be downloaded or are not supported invoices are free.

### FAQ

**Does it validate the digital signature?** No. It reads what the document and the tax authority response say (DIAN ApplicationResponse, SAT Timbre Fiscal Digital, SEFAZ protocol). It does not query the tax authority's servers.

**Can I send PDFs?** No, only the XML. The PDF is a printed copy; the XML is the legal document. ZIP files with both are fine: the PDF is skipped.

**Is my data stored?** Only in your own Apify storage. Ceiba Data never sees your invoices.

**What if a field is missing?** You get `null` for that field and, when it matters, a note in `warnings` (for example a CFDI without Timbre Fiscal Digital).

***

### En español / Em português

**Lector de facturas electrónicas a JSON**: factura electrónica DIAN (incluido el AttachedDocument que llega por correo, con CUFE, NIT, IVA, ReteFuente y validación de la DIAN), CFDI 4.0 del SAT con complemento de pagos, y NF-e de Brasil. **Leitor de NF-e para JSON**: chave de acesso, CNPJ, NCM, CFOP, ICMS, IPI, PIS, COFINS e status de autorização da SEFAZ.

***

Built and maintained by **Ceiba Data**, a studio that publishes Latin American data tools on Apify. Ceiba Data is operated with AI. Missing a document type or country? Open an issue on this Actor and we will answer within 24 hours.

# Actor input Schema

## `xmlUrls` (type: `array`):

Links to electronic invoice files. Each can be an .xml or a .zip (for example the ZIP a Colombian supplier emails with the AttachedDocument and the PDF); every XML inside a ZIP is parsed.

## `xmlStrings` (type: `array`):

Invoice XML passed directly as text, one document per item. Useful when calling the Actor from code or from an AI agent.

## `includeLines` (type: `boolean`):

Return every product or service line with quantity, unit price, totals and taxes.

## `flattenLines` (type: `boolean`):

Output one dataset row per line, repeating the invoice fields, which is handy for spreadsheets. You are still charged per document, not per line.

## `maxDocuments` (type: `integer`):

Stop after this many documents in one run.

## Actor input object example

```json
{
  "xmlUrls": [],
  "includeLines": true,
  "flattenLines": false,
  "maxDocuments": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

One row per document: country, format, documentType, number, uniqueId (CUFE, UUID or NF-e access key), dates, seller, buyer, totals, taxes, line items, validation status and warnings. Files that fail have status "error" and an error message.

## `summary` (type: `string`):

JSON record with parsed, failed and stoppedEarly (true when maxDocuments or the maximum cost per run was reached).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "xmlUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("ceibadata/latam-einvoice-parser").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "xmlUrls": [] }

# Run the Actor and wait for it to finish
run = client.actor("ceibadata/latam-einvoice-parser").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "xmlUrls": []
}' |
apify call ceibadata/latam-einvoice-parser --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ceibadata/latam-einvoice-parser"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Au4UT5NhtCrsl9gLe/builds/CvkeTf9PQTK8zhyan/openapi.json
