Machine translation, not yet reviewed.
NFS-e document and event reconciliation
The documents (/inbound/documentos) and events (/inbound/eventos) endpoints operate independently. The client consumes each one in its own…
How-to Guide — This document guides the integrator in building the reconciliation logic between inbound NFS-e documents and events consumed via the REST API.
1. Introduction
The documents (/inbound/documentos) and events (/inbound/eventos) endpoints operate independently. The client consumes each one in its own polling loop, with separate tokens and filters. However, documents and events are related: a cancellation event, for example, only makes sense when associated with the document it cancels.
Reconciliation is the client-side logic that connects these two flows. Since the order of arrival is unpredictable — an event may arrive before the corresponding document, and vice versa — the client needs to handle both scenarios resiliently.
2. Prerequisites
- The client already implements the incremental synchronization loop for the documents endpoint (as described in the inbound NFS-e document synchronization guide).
- The client already implements the incremental synchronization loop for the events endpoint (as described in the inbound NFS-e event synchronization guide).
- The client has a local database where documents and events are persisted as they are consumed.
3. Model overview
The client maintains two independent polling loops, each with its own nextToken and filters. Both loops write the received records to the local database. Reconciliation happens after each write, using the access key as the link.
┌──────────────────────┐ ┌──────────────────────┐
│ Loop de Documentos │ │ Loop de Eventos │
│ /inbound/documentos │ │ /inbound/eventos │
└────────┬─────────────┘ └────────┬─────────────┘
│ │
▼ ▼
Salva documento Salva evento
na base local na base local
│ │
▼ ▼
Busca eventos pendentes Busca documento
pela chave de acesso pela chave de acesso
│ │
▼ ▼
Encontrou? Encontrou?
├─ Não → fim ├─ Não → fim
└─ Sim → reconcilia └─ Sim → reconcilia
Access key
The access key (chave de acesso) is the identifier that connects a document to its event(s):
| Source | Field |
|---|---|
Document (/inbound/documentos) | id (item root) |
Event (/inbound/eventos) | infEvento.id |
The client should index its local database by this field to enable efficient lookups during reconciliation.
4. When receiving a document
When the documents loop returns a new item:
- Save the document to the local database, regardless of whether associated events already exist.
- Search the local database for all events whose
infEvento.idmatches theidof the newly saved document. - If no event is found, finish processing this item. The events may not have arrived yet — they will be reconciled when the events loop consumes them.
- If one or more events are found, associate each event with the document and perform the action corresponding to the event type. For example, if a cancellation event is found, mark the document as cancelled in the local database.
5. When receiving an event
When the events loop returns a new item:
- Save the event to the local database, regardless of whether the associated document already exists.
- Search the local database for the document whose
idmatches theinfEvento.idof the newly saved event. - If the document is not found, finish processing this item. The document may not have arrived yet — it will be reconciled when the documents loop consumes it.
- If the document is found, associate the event with the document and perform the action corresponding to the event type. For example, if it is a cancellation event, mark the document as cancelled in the local database.
6. Considerations
Unpredictable order of arrival
There is no guarantee that the document will arrive before its events, nor the other way around. The client must handle both scenarios with the same logic: save first, reconcile afterwards.
Idempotency
The reconciliation logic must be idempotent. If the same document-event pair is reconciled more than once (for example, after a client restart), the final result must be the same. This means that marking a document as cancelled twice must not cause unwanted side effects.
Events without a document
An event may remain without an associated document for an extended period — for example, if the document has not yet been processed by the API or if the client started consuming events with a createdFrom earlier than that used for documents. The client should treat unreconciled events as a normal state, not as an error.
Documents without events
Not every document will have associated events. A document that was never cancelled, manifested or subjected to any subsequent action simply will not have events. The absence of events for a document is the default scenario.