Multi-City NFS-e, One Spreadsheet:Batch Without Municipal Templates

Brazil has 5,570 municipalities. A consulting firm with service providers in 10 of them doesn't get one NFS-e (Nota Fiscal de Serviços Eletrônica) format. It gets 10 — each with a different ISS (Imposto Sobre Serviços) rate between 2% and 5%, a different field layout, and a different municipal tax authority behind it. Processing these one by one isn't just slow. It hides the reconciliation patterns that only a batch-level view reveals.

Batch extract data from Brazilian municipal NFS-e service invoices into one Excel spreadsheet

Key Takeaways

  1. You can calculate the time cost of manually typing each NFS-e — but the real cost hides in ISS withholding penalties, missed rate anomalies, and compliance gaps that only become visible when every invoice sits in one table.
  2. ISS Retido na Fonte legally transfers the tax remittance burden to your company, and across 30 invoices from 5 cities, a document-by-document approach guarantees at least one obligation will be missed.
  3. ImageToTable.ai processes every municipality's NFS-e in one batch and surfaces ISS discrepancies, withholding obligations, and per-city totals in a single spreadsheet — so your job shifts from typing numbers to verifying them.

Why Batch Processing of NFS-e Is a Different Problem from Single-Document Extraction

If you have read the single-NFS-e extraction guide, you know the core mechanism: semantic extraction reads an NFS-e by understanding what each field means — locating the 14-digit CNPJ do Prestador (service provider corporate tax ID) next to the label "Prestador," the ISS base de cálculo (taxable base) under the ISS section, the alíquota ISS (ISS rate) wherever the municipality printed it. One document, one set of column definitions, one output row. The problem of municipal variation is solved at the document level.

Batch processing introduces a different class of challenges that single-document extraction doesn't surface. When you drop 30 NFS-e documents from providers in São Paulo (ISS 5% for IT consulting), Rio de Janeiro (ISS 5% for the same service), Belo Horizonte (ISS 3%), Curitiba (ISS 4%), and six other cities into one processing queue, three things happen that never happen with a single document:

First, cross-city ISS rate verification becomes necessary. A single NFS-e at 3% ISS looks fine in isolation. But when you see that the same service code (item 1.01 — Análise e desenvolvimento de sistemas, or IT analysis and development) appears at 5% from São Paulo, 5% from Rio, and 3% from Belo Horizonte in the same batch, the Belo Horizonte rate immediately stands out. Maybe it is correct — Belo Horizonte sets its own rates. Maybe the provider applied the wrong municipal rate. A batch-level view is the only way to spot this.

Second, ISS Retido na Fonte (ISS withheld at source) tracking becomes a batch-scale compliance task. When an NFS-e is marked "ISS Retido na Fonte = Sim," the obligation to remit ISS shifts from the service provider to the service taker — you. Each occurrence requires a separate payment to the relevant prefeitura (municipality), each with its own due date and payment system. Across 10 documents from multiple cities, tracking which invoices trigger this obligation and which do not is not manageable as a manual checklist.

Third, the data itself is more valuable in aggregate. Per-provider ISS totals, per-city service spend, the ratio of tax withheld vs. tax paid by provider — none of these are visible from one document at a time. They only emerge when the entire batch is in one spreadsheet.

This is not about doing the single-document workflow faster. It is about doing something the single-document workflow cannot do at all.

What Makes Cross-Municipality NFS-e Processing Fundamentally Different from Standard Invoice Batch

Standard batch invoice processing — 50 PDFs from 50 suppliers across the US or Europe — is primarily a volume problem. The invoices look different, but the underlying tax logic is consistent: VAT at the national rate, sales tax by state, and the fields are in broadly predictable positions with broadly predictable labels.

Brazilian NFS-e batch processing adds a structural layer that standard invoice batch does not have. Because ISS is a municipal tax governed by Lei Complementar 116/2003, and because each municipality operates its own tax system, the same logical field — "the ISS rate" — can carry a different value for each document in the batch, and that value determines whether the tax on that document was correctly calculated.

This is where template-based extraction — the approach most document extraction tools use — becomes structurally unworkable. A template defines a rectangular zone for each field: "CNPJ do Prestador is at pixel position (x=150, y=320)." That works for one municipality. It breaks for the next. Maintaining a template library for every city your providers happen to operate in is not practical when the number of possible cities is 5,570 and the number of cities actively updating their layouts — São Paulo released version 3.2 of its NFS-e manual in August 2025 — is constantly growing.

The alternative is semantic extraction: instead of defining where a field sits on the page, you tell the extraction engine what you are looking for — "the 14-digit CNPJ labeled Prestador" — and it reads the document to find it. The position does not matter because the engine understands the document's content, not its coordinates. A São Paulo NFS-e and a Porto Alegre NFS-e in the same batch are processed with the same column definitions, because the AI is looking for meaning, not matching a position.

This is the architectural difference: template-based tools scale by adding more templates — one per city, per layout revision. Semantic extraction scales by understanding more document content. When you add a 10th city's NFS-e to the batch, the cost is effectively zero. When you add a 10th city's template, the cost is building, testing, and maintaining that template — and updating it every time the prefeitura changes its layout.

For the full breakdown of how semantic extraction handles individual NFS-e fields — CNPJ matching, LC 116 service code classification, the ISS tax breakdown — see the single-NFS-e extraction guide. The batch workflow inherits all of that and adds the multi-document layer.

How Semantic Extraction Handles 10 Cities' NFS-e in One Batch

The extraction workflow for batch NFS-e processing centers on Custom Column Extraction: you type the field names you want into your output — "Provider CNPJ," "Service Code (LC 116)," "ISS Rate," "ISS Amount," "ISS Retained (Retido na Fonte)," "NFS-e Number" — and the AI locates each value on every document by understanding what the label means. These column names become your spreadsheet headers. You define them once. They work across every municipality in the batch.

But batch NFS-e processing benefits from going beyond direct extraction. Two additional column modes make the cross-city reconciliation possible at extraction time, not in a separate spreadsheet exercise:

Computed columns let you define validation logic that runs during extraction. For NFS-e batch processing, the most useful computed column is an ISS verification: "ISS Rate × ISS Taxable Base = ISS Amount?" When the computed total matches the extracted ISS amount, the column outputs "OK." When it doesn't, it outputs the discrepancy — flagging, at the batch level, which documents need a second look before you import the data into your ERP. On a single document, this check takes 30 seconds. Across 50 documents, a computed column does it automatically — and you see the result in the same spreadsheet as the extracted data.

Inferred columns let the AI classify or label documents based on their content. Add a column named "Municipality (extracted from document)" with no specific field reference, and the AI reads the prefeitura (city hall) identifier from the NFS-e and fills in the city name. Now your batch output has a sortable municipality column — making per-city ISS totals and per-city tax reporting a pivot table away instead of a manual cross-reference exercise.

These three column types — direct extraction, computed, and inferred — operate together in a single batch run. You do not extract first and validate later. The validation happens during extraction, and the results land in the same spreadsheet.

Step-by-Step: From Multi-City NFS-e Stack to One Spreadsheet

Here is the practical workflow for batch-processing NFS-e documents from multiple Brazilian municipalities into a single Excel file. You perform this setup once per batch — the same column definitions process every document regardless of which city it came from.

1
Collect all NFS-e documents in one upload. Drag all PDFs or XMLs from your Brazilian service providers into the upload area. The tool accepts DANFSE (Documento Auxiliar da NFS-e, printed version), XML files, and even screenshots of NFS-e documents. Documents from different cities and in different formats go into the same batch — the extraction engine processes each independently.
2
Define your extraction columns once. Type the field names you need as column headers. For cross-municipality NFS-e batch processing, include: "Provider CNPJ (CNPJ Prestador)," "Taker CNPJ (CNPJ Tomador)," "NFS-e Number," "Issue Date," "Service Code (LC 116)," "Service Description (Discriminação)," "ISS Taxable Base (Base de Cálculo)," "ISS Rate (Alíquota)," "ISS Amount (Valor ISS)," "ISS Retained (Retido na Fonte)," "Total Amount," "Municipality (inferred)." For ISS validation, add a computed column: "ISS Check (Rate × Base = Amount?)."
3
Process the batch. Start the extraction. The AI reads each document independently, matching your column names to the corresponding values by understanding document content — not by relying on a fixed layout. A São Paulo NFS-e and a Belo Horizonte NFS-e in the same batch are processed with identical column definitions. Processing takes approximately 5 to 10 seconds per page, so a batch of 30 documents completes in roughly 3 to 5 minutes.
4
Review batch-level results and export. In the output spreadsheet, sort by the ISS Retained column to identify every invoice where you — not the provider — have the tax remittance obligation. Sort by the ISS Check column to find documents where the extracted ISS amount doesn't match the rate × base calculation. Sort by Municipality to see per-city ISS totals. Export as XLSX — the data is ready for ERP import, accounting software integration (ContaAzul, Omie, TOTVS), or direct reconciliation against your provider's monthly service summaries.
PDF/XML/PNG AI Extraction

Files are processed securely and not stored.

Cross-Municipality ISS Reconciliation: The Batch-Only View

The single most valuable output of batch NFS-e processing is not the time saved — though going from 3 minutes per document to 5-10 seconds per page is an 18x improvement. The most valuable output is the reconciliation view that only exists when all the documents are in one table.

Here is what that view lets you do that single-document processing cannot:

Per-City ISS Totals

Group the output by municipality and sum the ISS amount. What you get is the total ISS that was applied to your service purchases in each city — data that matters for two reasons. First, it tells you whether the total ISS across all providers in a given city aligns with your internal cost allocation for that jurisdiction. Second, if you are the ISS withholding agent on any of these invoices, the per-city total is the number you need to reconcile against your municipal tax remittance records. Dentons' global tax guide notes that "conflicts between different municipalities where both are claiming the ISS are quite common" — a batch-level view is your audit trail if a second municipality comes asking.

ISS Retido na Fonte Tracking

When an NFS-e carries the "ISS Retido na Fonte = Sim" (ISS withheld at source) flag, your company — not the service provider — is responsible for remitting the ISS to the provider's municipality. This is not a data entry note; it is a tax compliance action item with a deadline and a payment system that differs per city. In a batch output, sorting by the ISS Retained column gives you a complete, single-view list of every invoice requiring your action. No searching through 30 individual PDFs to find the three that had the flag.

The legal framework around ISS withholding has been tested at Brazil's highest court. In 2020, the Brazilian Supreme Federal Court (STF) ruled in RE 1167509 that municipalities cannot impose ISS withholding obligations on service takers when the provider is not registered in that municipality — overturning São Paulo's Cadastro de Prestadores de Outros Municípios (CPOM) registration requirement. But withholding obligations established by federal law, where the service type and municipality combination trigger legitimate retention, remain in force. Knowing which invoices carry a valid withholding obligation requires seeing the batch.

ISS Rate Variance Detection

LC 116/2003 establishes ISS rates between 2% and 5% per municipality and service type. But municipalities compete on rates to attract businesses — the UNDP's diagnostic review of the Brazilian tax system notes "a predatory war on ICMS and ISS tax incentive awards." A provider might apply a 2% rate for a service code that São Paulo taxes at 5% because the provider is registered in a municipality that lowered its rate to attract businesses. Whether that rate is valid is a tax determination your accounting team makes. But spotting it requires seeing the batch. A single document at 2% looks normal. Ten documents at 5% and one at 2%, all for the same service code — that is a variance worth investigating.

What the National NFS-e Standard Means for Batch Processing

The Sistema Nacional da NFS-e (SNNFS-e, National NFS-e System) is Brazil's effort to unify service invoice formats across municipalities. As of August 2025, 1,463 municipalities had signed on — but adoption is voluntary, and major cities like São Paulo have publicly confirmed they will retain their own systems. The result is a hybrid landscape: some of your providers issue NFS-e under the national XML standard, others under their city's own system, and you do not control which.

From a batch processing perspective, this hybrid landscape reinforces the value of layout-independent extraction. Template-based tools now need templates for both the pre-standard city layouts and the SNNFS-e standard — plus update paths when cities migrate from one to the other. Semantic extraction reads whatever is on the document, regardless of which standard produced it. A national-standard NFS-e and a São Paulo custom-format NFS-e land in the same batch, define the same columns, and produce the same output. The standardization process changes the document contents, not the extraction approach.

The 2026 tax reform — which will gradually replace ISS with IBS (Imposto sobre Bens e Serviços) through 2033 — adds another layer. During the transition, NFS-e documents may carry both legacy ISS fields and new IBS/CBS fields. The extraction approach adapts by adding new column names — "IBS Amount," "CBS Amount" — alongside the existing ISS columns. No template redesign required.

If your organization also processes Brazilian goods invoices, the NF-e XML extraction workflow is covered in the NF-e extraction guide. The two document types can coexist in the same batch when your column definitions are broad enough, though NFS-e-specific fields like the LC 116 code will be blank for NF-e documents — which is expected and does not cause errors.

FAQ: Batch NFS-e Processing

Can I batch-process NFS-e documents from providers in different cities together?

Yes — and this is the primary use case. Semantic extraction reads each document independently by understanding the content, not by matching a specific city's layout. An NFS-e from São Paulo (ISS 5%), one from Belo Horizonte (ISS 3%), and one from Curitiba (ISS 4%) in the same batch are all processed with the same column definitions. The AI locates the CNPJ do Prestador, ISS base de cálculo, and demás fields on each document regardless of where they appear on the page.

How is ISS Retido na Fonte handled in batch output?

The "ISS Retained" field is extracted as a dedicated column — typically containing "Sim" (yes) or "Não" (no). In the batch output spreadsheet, sorting by this column gives you a complete list of every invoice where your company is the withholding agent. From there, you calculate the amount to remit (the ISS rate × base on each flagged invoice) and route each to the correct prefeitura's payment system. The extraction tool provides the data. The tax remittance itself remains a separate compliance step that your accounting team performs through each municipality's payment portal.

What if a provider issues an NFS-e with layout errors or missing fields?

The extraction engine reads what is on the document. If a mandatory field — the CNPJ for example — is missing or illegible, that cell in the output will be blank. This is actually useful: a blank cell in the batch output immediately identifies which document needs follow-up with the provider, whereas manually entering 30 documents might cause you to miss one blank field among the rest. The batch view makes omissions visible.

Can I mix NFS-e documents with international service invoices in the same batch?

Yes. If your column definitions cover both document types — such as "Invoice Number," "Vendor Name," "Total Amount," "Tax Amount" — international invoices and NFS-e documents can coexist in the same batch. NFS-e-specific columns like "LC 116 Service Code" or "ISS Rate" will be blank for non-Brazilian documents, and international-specific columns like "VAT Number" will be blank for NFS-e documents. Both behaviors are expected and do not cause errors.

Does the extraction engine handle the 2026 tax reform fields (IBS/CBS) on NFS-e documents?

Yes — when a municipality updates its NFS-e layout to include IBS or CBS fields, you add the corresponding column names (e.g., "IBS Amount," "CBS Amount") to your batch definition. The extraction engine locates these new fields by understanding the document content, the same way it locates existing ISS and CNPJ fields. No template reconfiguration is required. During the transition period through 2033, you may run batches containing NFS-e documents with both ISS and IBS fields — define columns for both, and the output will populate whichever fields are present on each document.

How does batch processing compare to integrating each municipality's API directly?

Municipal API integration requires building and maintaining a separate connection for each city your providers operate in — each with its own authentication method, schema, and update schedule. The SNNFS-e national standard simplifies this for participating municipalities, but major cities like São Paulo have declined to join. Semantic batch extraction processes the documents you already receive — PDFs, XMLs, DANFSE prints — without requiring API access to any municipal system. It is not an alternative to API integration for outbound NFS-e issuance. It is the receiving-side solution for when you are the service taker (tomador), not the issuer.

For a broader look at batch document extraction beyond NFS-e, see how batch invoice extraction to Excel works across document types and currencies.

From Per-Municipality Typing to Per-Batch Reconciliation

The NFS-e was designed to make tax collection efficient for the government — and it does. Every service invoice you receive was validated by a municipal tax authority before it reached your inbox. The CNPJ was checked. The ISS rate was verified against the service code. The invoice number was assigned. That data exists. It is accurate. It has been through a government validation step that most international invoices never see.

The inefficiency is entirely on the receiving end: retyping validated fields from documents that vary by city into a spreadsheet that needs to be correct for SPED reconciliation. Batch semantic extraction closes that gap not by making the typing faster but by removing it — and in doing so, gives you the cross-municipality view that manual entry could never produce.

The next time you receive a stack of NFS-e from providers across São Paulo, Rio, Belo Horizonte, and beyond, try processing them as one batch. Define your columns once. Let the extraction run. Then sort by municipality and check the ISS totals. See if the batch view reveals something the individual documents didn't.

Batch Process Your NFS-e to Excel

No sign-up required for your first 50 pages.

📮 contact email: [email protected]