Fiscal Document Capture (DFe Inbound) Architecture — NF-e, CT-e and NFS-e
| Product | NFE.io Fiscal Document Capture (dfetech-distribution-api) — NF-e Inbound, CT-e Inbound and NFS-e Inbound |
| Document | 1 of 3 — Architecture design |
| Version | 1.1 — 2026-09-24 |
| Audience | Customers, architecture teams, IT, information security and tax teams |
| Related documents | 2 of 3 — Processing flows · 3 of 3 — Processing details and polling-frequency rules · Versão em português |
1. Summary
NFE.io Fiscal Document Capture automatically receives the electronic fiscal documents that third parties issue against the customer's CNPJ (Brazilian company tax ID). It queries the national distribution environments run by the Brazilian tax authorities, stores the XML files, extracts the metadata, makes the files available through a REST API, and notifies the customer's system through webhooks.
The service is made up of three independent sub-products that share the same platform:
| Sub-product | Documents captured | Government source | Source protocol |
|---|---|---|---|
| NF-e Inbound | NF-e (model 55, goods invoice) and its events | NF-e National Environment — NFeDistribuicaoDFe web service | SOAP with mutual TLS |
| CT-e Inbound | CT-e (model 57, transport document) and its events | CT-e National Environment — CTeDistribuicaoDFe web service | SOAP with mutual TLS |
| NFS-e Inbound | National Standard NFS-e (service invoice), DPS and events | National Data Environment (ADN) of the National NFS-e System | REST with mutual TLS |
Each sub-product is enabled per company (CNPJ) and runs in isolation. A failure or outage in one government environment does not stop the others.
2. Architecture principles
- Separation by document type. Each sub-product has its own capture process (worker), its own queues and its own consumption limits. A high NF-e volume does not compete for resources with NFS-e capture.
- Asynchronous, message-driven processing. Capture, per-document processing and notification are separate stages connected by message queues. Any stage can be reprocessed without redoing the previous ones.
- NSU-based cursor. Capture progress is driven by the NSU (Unique Sequential Number) that the national environment assigns to each document addressed to the CNPJ. The last processed NSU is stored per company, and the next query starts from it.
- Disciplined use of government services. The routine-capture polling and waiting rules defined in the Technical Notes (Notas Técnicas) are implemented in the capture engine itself, together with automatic pauses and blocks in response to rejections and shutdowns. Document 3 has the details.
- Idempotency. Every document has a deterministic identifier (company + access key, company + event identifier, or company + NSU). Reprocessing a document overwrites the existing record instead of duplicating it.
- Automatic gap recovery. A daily routine checks the continuity of the NSU sequence and recovers, one by one, any document that was not persisted.
- End-to-end observability. All components emit distributed tracing, metrics and structured logs, and expose health checks.
3. Overview (context diagram)
4. Component view
4.1 Component responsibilities
| Component | Responsibility |
|---|---|
| HTTPS gateway | Terminates TLS and routes the public Fiscal Document Capture routes (/v2/companies/...) to the API. |
| Fiscal Document Capture REST API | Enables and disables capture per company, queries documents and events, serves XML, PDF and JSON, and accepts manifestation and reprocessing requests. Authenticates with API keys and authorizes by product profile. Runs on-demand NFS-e capture by access key. Scales horizontally based on CPU usage. |
| NF-e Inbound worker | Schedules and runs the NFeDistribuicaoDFe query, processes each NSU (summary, full NF-e, events), schedules the automatic Awareness of Operation for after the waiting time set by the company (the only manifestation sent automatically), sends manifestations to the event environment (the National Environment's NFeRecepcaoEvento4; Tax Reform events through the corresponding event environment), and runs the daily NSU reconciliation. |
| CT-e Inbound worker | Schedules and runs the CTeDistribuicaoDFe query, processes each NSU (CT-e and events), applies the event and interested-party filters, provides item and batch reprocessing and consolidation, and runs the daily NSU reconciliation. |
| NFS-e Inbound worker | Schedules and runs the ADN query, decodes and classifies each document (NFS-e, DPS, events), generates the DANFSe (NFS-e PDF), applies the cutoff date and history release, sends taker (tomador) manifestations to Sefin Nacional, and runs the daily NSU reconciliation. |
| Message broker | Carries messages between stages. There are dedicated queues per product and per stage, dead-letter queues, and delayed retry scheduling. |
| Document database | Stores each company's settings, the NSU cursors, document and event metadata, reprocessing controls and the notification audit trail. |
| Object storage | Stores the original XML files received from the government, the response batches, the generated PDFs, and the request and response records of the queries. |
| Distributed cache | Provides distributed locks (one capture per company at a time, one instance per daily routine), per-company concurrency limits, the control of the NF-e and CT-e point-query limit (20 queries that return a document per hour per CNPJ), and operational parameters that can be tuned at runtime. If the cache becomes unavailable, point queries proceed without the control, and a cStat 656 still blocks the company through the record kept in the database. |
| Companies and Certificates | NFE.io platform service that keeps the company registry and holds the A1 digital certificates. Fiscal Document Capture fetches the certificate for each query and keeps it only in memory. |
| Notifications (Webhooks) | NFE.io platform service that delivers events to the endpoint configured by the customer. |
| Usage recording | Records operations for billing. |
| NFS-e PDF generation | Generates the DANFSe from the NFS-e XML. |
| Observability | Collects traces, metrics and logs through OpenTelemetry. An external heartbeat alerts the team if any worker stops responding. |
4.2 Technology stack
| Layer | Technology |
|---|---|
| Language and runtime | .NET (C#), ASP.NET Core |
| Runtime platform | Containers on Kubernetes, continuous delivery through Helm and GitOps |
| Messaging | RabbitMQ with the Rebus framework |
| Database | MongoDB |
| Cache and locks | Redis-compatible cache |
| File storage | S3-compatible object storage |
| SEFAZ integration | Library for the NF-e and CT-e web services (SOAP, XML signature, mutual TLS) |
| National NFS-e integration | HTTP client with mutual TLS and resilience policies (exponential retry and circuit breaker) |
| Queries | REST with pagination, and OData for NF-e and CT-e |
| Observability | OpenTelemetry and external heartbeat monitoring |
5. Deployment
- The four components (API and three workers) are deployed as independent applications, each with its own container image and release cycle.
- The API runs multiple replicas with horizontal autoscaling. The workers scale parallelism internally, per queue.
- All applications expose readiness checks, which verify the database, cache, broker, storage and dependent services, and liveness checks. Kubernetes takes an instance that is not ready out of load balancing and automatically restarts an instance that stops responding.
- Shutdown is graceful: an instance stops taking new messages and finishes the ones in progress before exiting.
- Credentials (connection strings, keys and service certificates) are kept in a secrets vault and injected at runtime. No credential is stored in source code.
- Scheduled routines (daily NSU reconciliation) run inside the workers, with leader election through a distributed lock. Only one instance runs each cycle.
6. Customer integration
6.1 REST API
- Production address:
https://api.nfse.io - Authentication: the NFE.io account API key, with authorization by product profile (NF-e, CT-e and NFS-e) or by the general Nota Fiscal key.
- Data model: account → company (CNPJ) → capture configuration per product. Document routes are scoped by company:
/v2/companies/{companyId}/inbound/....
| Product | Main resources |
|---|---|
| NF-e | Enable, read and disable capture (.../inbound/productinvoices); list and view NF-e (.../inbound/nfe); download XML and PDF (DANFE); query events; register manifestations; OData queries (.../inbound/odata/ProductInvoices and ProductInvoiceEvents); resend webhooks. |
| CT-e | Enable, read and disable capture (.../inbound/transportationinvoices); download XML, JSON and PDF (DACTE); configure the webhook interested-party filter; reprocess items, batches and webhooks; OData queries (.../inbound/odata/TransportationInvoices and TransportationInvoiceEvents). |
| NFS-e | Enable capture (POST /v2/companies/inbound/nfse) and read, change or disable the configuration (.../inbound/nfse/details); list and view documents (.../inbound/nfse); download XML, PDF (DANFSe) and JSON; on-demand capture by access key; register taker manifestations; reprocess and resend webhooks. |
XML and PDF downloads are served through a temporary signed URL (usually by HTTP redirect) or directly in the response body, as with the CT-e PDF. Signed URLs expire within an hour and must not be stored; request a new one from the endpoint when needed.
6.2 Webhooks
Each captured document or event produces a notification to the endpoint registered by the customer on the NFE.io notification platform.
| Product | Event type | Actions |
|---|---|---|
| NF-e | product_invoice_inbound (full document and events) and product_invoice_inbound_summary (summaries) | issued_successfully (document received), outbound_successfully (document issued by the company itself), event_raised_successfully (event), input_event_raised_successfully (recipient manifestation) |
| CT-e | transportation_invoice_inbound | issued_successfully, outbound_successfully, event_raised_successfully |
| NFS-e | service_invoice_inbound | issued_successfully (NFS-e received), outbound_successfully (NFS-e issued by the company itself, when that capture is on), event_raised_successfully (events and registered manifestations). The body also carries an eventName field in the inbound.serviceInvoice.* format |
Delivery is at-least-once. The customer system must handle repeated notifications idempotently, using the access key, the event identifier or the NSU. Webhook signature validation follows the official NFE.io webhook documentation.
6.3 Console
The app.nfe.io console uses the same API to enable capture, query documents, download files and register manifestations. The data is the same in the console and in the API.
7. Security and privacy
| Topic | How it is handled |
|---|---|
| Digital certificate | Capture uses the company's own A1 certificate (ICP-Brasil), held by the NFE.io certificate service. The certificate is fetched for each query and loaded only in memory. Certificates whose private key is held in an HSM are not yet supported by Fiscal Document Capture, which uses the A1 certificate (file) for the mutual TLS required by the distribution environments. |
| Channel to the government | All calls to the national environments use HTTPS with mutual authentication (TLS 1.2 or higher). For NFS-e, each request opens its own connection, which isolates one company's certificate from the others. |
| Channel to the customer | HTTPS at the gateway, API key authentication and authorization by product profile. |
| Tenant isolation | Logical isolation: every record and every query carries the account and company identifier. One account cannot see another account's documents. |
| Downloads | Signed URLs with a short validity period. |
| Internal credentials | Kept in a secrets vault, with authenticated communication between platform services. |
| Audit | Every notification sent is recorded (acceptance time and reach), with 365-day retention. For CT-e, the request and response of every government query are archived; for NF-e, the queries that return documents or rejections. |
| LGPD (Brazilian data protection law) | Captured documents contain third-party data (issuers, carriers, service providers). NFE.io acts as the processor of this data on behalf of the customer, who is the legitimate recipient of the documents under the government distribution rules. |
8. Resilience
| Mechanism | Description |
|---|---|
| Queues with retries | Every stage that fails is redelivered automatically. Messages that exhaust their attempts go to error queues and can be redriven by the operations team. |
| Message deduplication | Each message has a stable identifier, and the consumer discards duplicates within a time window. |
| Cursor saved after persistence | For CT-e, the NSU cursor only advances after the batch has been persisted. For NF-e and NFS-e, persistence failures are recorded for reprocessing and covered by the daily reconciliation. |
| Pauses during government outages | When the national environment reports a service shutdown, capture is paused for a defined period and resumes on its own (details in document 3). |
| Point-query limit | For NF-e and CT-e, queries by NSU or by access key honor the limit of 20 queries that return a document per hour per CNPJ. Queries with no slot available are deferred without consuming an attempt, with random spacing so that the retries are not concentrated. |
| Circuit breaker | NFS-e has global and per-certificate circuit breakers. For NF-e, a query that fails repeatedly is stopped after the attempt limit so that it does not consume the government service indefinitely. |
| Daily NSU reconciliation | Every day at 11 p.m. (Brasília time), each product checks the NSU sequence of the last 3 days and recovers any missing NSU. |
| External heartbeat | An external monitor receives periodic signals from each worker and alerts the team if any of them stops sending them. |
9. Government references
- National NF-e Portal — Technical Note 2014.002 (DF-e Distribution Web Service for NF-e Stakeholders) and the
distDFeIntandretDistDFeIntschemas: https://www.nfe.fazenda.gov.br/portal - National NF-e Portal — Technical Note 2020.001 (Recipient Manifestation) and Technical Note 2025.002 (Consumption Tax Reform events).
- National CT-e Portal — Technical Note 2015.002 (DF-e Distribution Web Service for CT-e Stakeholders): https://www.cte.fazenda.gov.br/portal
- National NFS-e System — Taxpayer Manual: Guide to the ADN APIs: https://www.gov.br/nfse/pt-br/biblioteca/documentacao-tecnica/documentacao-atual
- CONFAZ — Ajuste SINIEF 07/05 (NF-e): https://www.confaz.fazenda.gov.br/legislacao/ajustes/2005/AJ007_05