Processing, Resilience, Idempotency and Contingency in Detail: NF-e, NFC-e, Taxes and Taxes Payment Forms
| Product | NFE.io Product Invoice Issuance (dfetech-product-invoice-api) |
| Document | 3 of 4: Detail of processing and of the resilience, idempotency and contingency rules |
| Version | 1.0 (2026-09-24) |
| Audience | Customers, architecture teams, IT, audit and tax departments |
| Related documents | 1 of 4: Architecture · 2 of 4: Processing flows · 4 of 4: Messaging and queues (Portuguese) · Versão em português |
Contents
- Executive summary
- Concepts
- Government rules that govern issuance
- NF-e
- NFC-e
- Taxes: tax calculation
- Taxes Payment Forms: tax payment slips
- Relationship between NF-e, NFC-e and Taxes
- Resilience rules
- Idempotency rules
- Contingency
- Customer responsibilities
- Government references
1. Executive summary
- Asynchronous issuance with an immediate response. The NF-e and the NFC-e accept the request, return the invoice identifier (
id) and continue issuance in the background. The result arrives by webhook and is available through the query endpoints. The NFC-e also has a synchronous mode, which returns the result in the same request within a 10-second limit for authorization processing. - Independent, resumable steps. Creation and tax calculation, numbering, signing, submission, query and notification are separate steps. Each invoice is persisted as a sequence of events (Event Sourcing), and any step resumes from the last recorded event.
- Resilience. Transient failures (SEFAZ down, timeout, internal service unavailable) trigger new attempts with increasing waits. Permanent failures (SEFAZ rejection, validation error, expired certificate) close the invoice with the reason, with no pointless retries. In synchronous NFC-e without offline contingency enabled, SEFAZ unavailability closes the invoice with an error, so the point of sale is not kept waiting.
- Idempotency. An invoice is never resent blindly: on a timeout or a duplicate, the platform queries the invoice by its access key. A per-invoice lock and an admission control guarantee a single execution per invoice and per operation, and the consumer discards repeated messages.
- Contingency. The NF-e uses EPEC (tpEmis 4), activated by the customer (strategy
Manual) or by NFE.io per UF (strategyStateTaxAuthorityStatusUnavailable). The NFC-e uses offline contingency (tpEmis 9), triggered automatically by a timeout or unavailability and, preventively, by a per-UF circuit breaker. - Relationship with Taxes. The NF-e and the NFC-e call Taxes while the invoice is created, before numbering, when the customer requests automatic calculation on the items. If the calculation cannot be done, the invoice waits or is refused: it is never issued with a presumed tax.
2. Concepts
| Term | Meaning |
|---|---|
| Access key | 44-character identifier of the NF-e/NFC-e. It includes the UF, the year and month of issuance, the issuer's CNPJ, the model, the series, the number and the issuance type (tpEmis). |
| cStat | Status code returned by SEFAZ. Examples: 100 (authorized), 150 (authorized after the deadline), 204 and 539 (duplicate), 217 (invoice not found in the database), 301, 302 and 303 (use denied). |
| tpEmis | Issuance type: 1 (normal), 4 (EPEC), 6 (SVC-AN), 7 (SVC-RS) and 9 (NFC-e offline contingency), among others. |
| dhCont and xJust | Date and time of entry into contingency and the justification, both mandatory on invoices issued in contingency. |
| EPEC | Evento Prévio de Emissão em Contingência (prior contingency issuance event). It registers the invoice in the National Environment when the home SEFAZ is unavailable. |
| Offline contingency | NFC-e mode in which the invoice is issued and delivered to the consumer without prior authorization and transmitted later. |
| State tax registration (IE) | In the NFE.io registry, each IE (inscrição estadual) of the company defines the document type (NF-e or NFC-e), the series, the environment (production or homologation), the NFC-e CSC and the contingency strategy. |
| CSC | Código de Segurança do Contribuinte (taxpayer security code), used in the NFC-e QR Code. |
| Event Sourcing | Persistence model in which the invoice state is the sum of its events, recorded in order and never overwritten. |
| Idempotency | Guarantee that repeating an operation does not produce a duplicate effect. |
| At-least-once | "At least once" delivery guarantee: a message or webhook may arrive more than once, but is never lost. |
3. Government rules that govern issuance
| Topic | Rule | Source |
|---|---|---|
| Layout and validation | Layout 4.00 of the NF-e and the NFC-e and the MOC 7.0 validation rules, updated by Technical Notes (NT) | MOC 7.0, Annex I |
| Consumption Tax Reform | IBS, CBS and IS groups in the layout, per the current version of NT 2025.002 | NT 2025.002 |
| NF-e contingency | Modes FS-IA, EPEC, FS-DA, SVC-AN and SVC-RS. Under EPEC, the NF-e must be transmitted to the home SEFAZ within 168 hours of issuance | MOC 7.0, Annex III; Ajuste SINIEF 07/05 |
| UF restriction for EPEC | From 2026-10-05, validation rule 2P10-20 prohibits EPEC for issuers in PR and PB | NT 2014.001 v1.41 |
| NFC-e contingency | An NFC-e in offline contingency must be transmitted by the end of the first business day (dia útil) after issuance. If rejected, it must be regenerated with the same number and series, without changing amounts, parties and dates. The numbering of an NFC-e issued in contingency cannot be disabled | Ajuste SINIEF 19/16; MOC 7.0, Annex IV |
| NF-e cancellation | Within 24 hours of authorization, provided the goods have not moved. Cancellation after the deadline is at the discretion of each UF | Ajuste SINIEF 07/05 |
| NFC-e cancellation | Within 24 hours, a deadline each UF may shorten | Ajuste SINIEF 19/16 |
| Correction letter (CC-e) | Event 110110, only after authorization. It does not correct amounts that determine the tax, sender or recipient data, or issuance or exit dates. The most recent CC-e replaces the previous ones and must contain all corrections. Up to 20 CC-e per invoice. Does not apply to the NFC-e | Ajuste SINIEF 07/05 |
| Number disablement (inutilização) | For numbers that will not be used, by the 10th day of the following month | Ajuste SINIEF 07/05 and 19/16 |
| Service status query | Anyone polling SEFAZ availability in a loop must respect a minimum interval of 3 minutes | MOC 7.0, General Overview |
4. NF-e
4.1 Prerequisites
- Company registered and active at NFE.io, with a valid A1 (ICP-Brasil) digital certificate.
- Active state tax registration of type NF-e, with series and environment (production or homologation) defined.
- API key with the Invoice profile.
- Optionally, a webhook registered for the
product_invoiceevent type.
4.2 Reception and validation (synchronous, in the API)
POST /v2/companies/{companyId}/productinvoices (or .../statetaxes/{statetaxId}/productinvoices, to choose the state tax registration) runs the following within the request:
- Authentication of the API key and authorization by the product profile.
- Payload conversion. A malformed payload returns 400 with the list of errors.
- Reading the company and applying the payload and registry validation rules (for example, mandatory fields of the layout, of the Tax Reform and of return, credit and debit invoices). A violation returns 400.
- Generation of the invoice identifier (
id) and storage of the original request. - Publication of the creation step to the issuance queue.
The response is 200 with the invoice resource and the id. From then on, processing is asynchronous. If publishing to the queue fails, the API responds 503 and no invoice is created, so the request can be resent safely.
Without statetaxId in the route, the platform uses the first state tax registration in the company's list. If it is not of type NF-e or is not active, the request is refused with 400. When the company has more than one state tax registration, provide the statetaxId.
4.3 Invoice creation and tax calculation (worker)
- The worker acquires the invoice lock (section 9.4).
- If the invoice already exists in the event store, the request is treated as a repetition and the flow resumes from the invoice's current step.
- It checks that the company and the state tax registration are active and that the IE is of type NF-e.
- It applies the business checks (IE contingency strategy, credit and debit invoice rules, Manaus Free Trade Zone, mandatory IBS/CBS, complementary invoice totals).
- It calculates the taxes in Taxes, when the customer requested it (section 8).
- It checks whether EPEC contingency is active for the IE or for the UF (section 11.2). If so, the invoice is created flagged for EPEC.
- It creates the aggregate and records the initial events. The invoice now exists with status
Created.
Any permanent failure in this step refuses the invoice: it is recorded with status Error and the customer receives product_invoice.issued_error with the reason.
4.4 Numbering
- If the request provided the series and the number, they are used as received.
- If not, the series comes from the state tax registration and the number comes from the numbering sequence kept by the NFE.io registry for that IE and series.
- A permanent numbering failure (for example, an unregistered series) refuses the invoice.
When the customer provides the number, the platform does not query the sequence. A number already used by another invoice of the same series is rejected by SEFAZ as a duplicate (cStat 539). If your system controls numbering, ensure uniqueness per series on your side.
4.5 Signing and authorization
- Generation of the access key and the numeric code.
- Retrieval of the company's A1 certificate from the custody service. The certificate validity is checked before signing: an expired or not-yet-valid certificate ends issuance with an error, with no call to SEFAZ.
- Generation of the XML in layout 4.00, digital signature and validation against the official XSD schemas. A schema failure ends issuance with an error.
- Storage of the signed XML.
- Submission to the authorization Web Service (
NFeAutorizacao4) of the authorizing SEFAZ for the issuer's UF, with synchronous processing (indSinc=1), over HTTPS with mutual TLS. The maximum time for each call is 120 seconds.
The authorizing SEFAZ is the UF's own or the Virtual SEFAZ that serves the UF (SVRS or SVAN), per the official list of Web Services on the NF-e National Portal. Issuers without a state tax registration (taxpayers, or contribuintes, liable only for IBS/CBS) are routed to SVRS.
4.6 Handling SEFAZ responses
| Response | Classification | What the platform does | What the customer sees |
|---|---|---|---|
| cStat 100 or 150 (authorized) | Success | Builds the nfeProc and notifies | Issued, issued_successfully |
| Batch received without a synchronous result | Inconclusive | Queries by access key | Waits |
| Timeout or inconclusive response | Inconclusive | Queries by access key. Never resends | Waits |
| 204 or 539 with this same invoice's key | Duplicate of the invoice itself | Queries by key and recovers the protocol | Issued, if authorized |
| 204 or 539 with another key | Rejection | Closes | Error, issued_error |
| No communication, SEFAZ unavailable | Transient | New submission attempt (section 9.1) | Waits |
| Validation rule rejection | Permanent | Stores the rejection XML and closes | Error, issued_error with cStat and reason |
| Use denied (301, 302, 303) | Permanent | Closes | IssueDenied (when identified in the query) or Error (when returned in the synchronous submission), always with issued_error and the denial cStat |
| Certificate refused in TLS | Permanent | Closes with no new attempts | Error, issued_error |
| Attempts exhausted | Permanent | Closes | Error, issued_failed |
Query by access key. The platform queries the invoice on the NFeConsultaProtocolo4 Web Service with increasing waits (section 9.1). If the invoice is authorized, the protocol is recovered and the flow continues normally. If SEFAZ responds 217 (invoice not found in the database), the query is repeated up to 8 times; if 217 persists, the invoice is closed with issued_error and cStat 217, and its number can be disabled.
4.7 Completion, files and notification
- The authorization protocol is attached to the XML, forming the distribution XML (
nfeProc), which is stored. - The invoice moves to
Issuedand the customer receivesproduct_invoice.issued_successfully, with the full invoice resource. - The query index is updated next, for listings.
- The DANFE is generated on the first request to
GET .../productinvoices/{id}/pdfand stored for subsequent requests. - The authorized XML, the rejection XML and the EPEC event XML are available at the routes
.../xml,.../xml/rejectionand.../xml-epec.
4.8 Cancellation
DELETE .../productinvoices/{id}?reason=responds 204 and processes in the background.- It is accepted only for an
Issuedinvoice. The justification (reason) must have 15 to 255 characters, counted after replacing characters that do not exist in the Latin-1 standard accepted by SEFAZ (Portuguese accents are kept); if omitted, the platform uses the default text "Erro de preenchimento". - The worker signs event 110111 and sends it to the events Web Service of the authorizing SEFAZ.
- cStat 135, 136 or 155: the invoice moves to
Cancelledand the customer receivescancelled_successfully. Rejection:cancelled_errorwith the reason. Unavailability: new attempts and, if exhausted,cancelled_failed. - The legal deadline is validated by SEFAZ (section 3).
4.9 Correction letter (CC-e)
PUT .../productinvoices/{id}/correctionletterwith the correction text in thereasonfield (15 to 1,000 characters) responds 204.- It is accepted only for an
Issuedinvoice. The worker signs event 110110 with the next sequence number and sends it to the authorizing SEFAZ. - Result:
cce_successfully,cce_errororcce_failed. The CC-e XML and PDF are at.../correctionletter/xmland.../correctionletter/pdf. - Each CC-e replaces the previous one and must carry all corrections (section 3).
4.10 Number disablement
| Mode | Route | Processing | Rules |
|---|---|---|---|
| Per refused invoice | POST .../productinvoices/{id}/disablement | Asynchronous (204) | The invoice must be in Error and have a number. Result by webhook (disabled_successfully, disabled_error, disabled_failed) |
| Per range | POST .../productinvoices/disablement | Synchronous | Provide environment, UF, series, start and end number and justification. Responses: 204 (cStat 102 or range already disabled, 206/563), 400 (data rejection), 404, 409 (same range in processing), 422 (other rejection), 503 (SEFAZ unavailable) |
Range disablement is idempotent: repeating the request for a range already disabled returns success.
4.11 Purposes and special documents
- Return, complementary, adjustment: issued through the same
POST, with the purpose provided in the payload and specific validations. - Credit invoice and debit invoice: issued through the same
POST. Credit invoices and debit invoices of types 01, 02, 03, 05 and 08 skip tax calculation. It is possible to link and list the credit invoices issued against an NF-e. - Tax Reform fiscal events (NT 2025.002): the
.../authority-eventsroute records the issuer events defined in the NT. It is released when the feature is enabled.
5. NFC-e
5.1 Prerequisites
- Active company, with a valid A1 certificate.
- Active state tax registration of type NFC-e, with series, environment and CSC (identifier and code) registered.
- IE authorizer switch strategy set to
Manual. Any other strategy is refused with error code40002: in synchronous issuance, with 400 in the request itself; in asynchronous issuance, the invoice is refused during processing and the customer receivesissued_error.
5.2 Asynchronous issuance
POST /v2/companies/{companyId}/consumerinvoices follows the same steps as the NF-e (sections 4.2 to 4.7), with these particularities:
- The issuance date and time (
dhEmi) is the processing time. - The XML includes the QR Code (version 2), generated with the CSC of the state tax registration.
- A timeout or SEFAZ unavailability triggers offline contingency when the IE is enabled (section 11.3).
- On 217 in the query by key made after a submission timeout, the NFC-e alternates query and resubmission for up to 10 cycles before closing with an error.
- Webhook event type:
consumer_invoice. Theissued_contingencyaction reports that the invoice was issued in offline contingency.
5.3 Synchronous issuance
POST /v2/companies/{companyId}/consumerinvoices/sync returns the result in the same request.
-
The API validates the payload, calculates the taxes (when requested) and creates the invoice.
-
The API triggers the worker through a direct internal call. The worker acquires the invoice lock, numbers, signs, generates the QR Code and sends the authorization to SEFAZ.
-
The deadline for the authorization call is calculated as follows:
SEFAZ deadline = the lesser of 8 s and (10 s − time already elapsed in the worker − 2 s reserve), with a minimum of 1 s.The 2-second reserve exists so that, if needed, the invoice can be issued in offline contingency within the total time.
-
Responses:
| Situation | HTTP | Invoice status |
|---|---|---|
| Authorized within the deadline | 200 | Issued |
| Deadline exceeded or SEFAZ unavailable, IE enabled for offline contingency | 200 | IssuedContingency (the invoice will be transmitted later) |
| Rejected by SEFAZ | 200 | Error, with the cStat and the reason |
| Invalid payload or registry | 400 | Not created |
| Tax calculation rejected | 422 (code 42201) | Error: the invoice is recorded as refused |
| Invoice still processing when the call ends (deadline exceeded or duplicate with an IE not enabled for offline, lock busy or internal failure) | 503 | Stays Processing in the worker, which completes the flow (for example, by querying the invoice by key) |
| SEFAZ unavailable, IE not enabled for offline | 200 | Error: the invoice is refused; the request can be resent and the refused invoice's number must be disabled |
| Tax calculation service unavailable | 503 | Not created; the request can be resent |
A 503 does not mean the invoice no longer exists: it is still being handled and the result arrives by webhook. Before resending, check the company's invoice listing. A new POST creates a new invoice, with a new id and a new number.
The 10-second limit applies to processing in the worker. Tax calculation and invoice creation, done in the API before this step, do not count toward it.
5.4 QR Code and NFC-e DANFE
- The QR Code uses version 2, with the CSC and its identifier registered on the IE. In offline contingency, the QR Code carries the data required for that mode (issuance day, total amount and digest value).
- The NFC-e DANFE is generated on the first request to
GET .../consumerinvoices/{id}/pdf. In offline contingency, the DANFE shows the contingency issuance indication.
5.5 Cancellation and number disablement
- Cancellation (
DELETE .../consumerinvoices/{id}?reason=): requires anIssuedinvoice, event 110111, same rules as the NF-e. An invoice inIssuedContingencynot yet transmitted can only be cancelled after it is authorized. - Number disablement per refused invoice or per range, as in the NF-e. The numbering of an NFC-e issued in contingency cannot be disabled (Ajuste SINIEF 19/16).
- The NFC-e has no correction letter.
5.6 Differences between NF-e and NFC-e
| Aspect | NF-e | NFC-e |
|---|---|---|
| Synchronous mode | No | Yes (/sync) |
| Contingency | EPEC (tpEmis 4) | Offline (tpEmis 9) |
| Contingency strategies accepted on the IE | Manual and StateTaxAuthorityStatusUnavailable | Manual only |
| QR Code and CSC | Not applicable | Mandatory |
| Issuance date | Can be provided in the request | Always the processing time |
| CC-e | Yes | No |
| Cycle on 217 | Up to 8 queries | Up to 10 query and resubmission cycles (after a submission timeout) |
| Webhook event type | product_invoice | consumer_invoice |
6. Taxes: tax calculation
6.1 Resources
| Route | Function |
|---|---|
POST /tax-rules/{tenantId}/engine/calculate | Calculates taxes per item |
/{tenantId}/products (POST) and /{tenantId}/products/{productId} (GET, PUT, PATCH) | Product tax registry |
GET /tax-codes/operation-code, .../acquisition-purpose, .../issuer-tax-profile, .../recipient-tax-profile | Code tables used in the calculation request |
tenantId is the customer account: if it does not match the API key's account, the response is 403.
6.2 How the calculation is done
The request provides the issuer and the recipient (tax regime, tax profile and UF), the operation type and, per item, the operation code, the acquisition purpose, the tax profiles, the SKU, the NCM, the CEST, the goods origin and the amounts (quantity, unit price, freight, insurance, discount and other expenses).
- For each item, Taxes looks up the product in the tax registry (by SKU and origin). A registered product that is not active, or an unregistered product without NCM, returns 400.
- Taxes checks whether there is a recent reusable calculation for the same scenario (section 6.3).
- For items without reuse, it queries the tax rules engine, which returns CFOP, CST/CSOSN, bases, reductions, rates and amounts.
- It applies the product's custom taxation (
customTax), when present (section 6.4). - It returns, per item: CFOP, CEST, tax benefit code (cBenef), ICMS (including ST, FCP, FCP-ST, deferral, exemption relief and single-phase), ICMS of the destination UF (DIFAL), IPI, PIS and COFINS, plus additional product information.
6.3 Calculation reuse and fallback during unavailability
- For eligible scenarios, a calculation result is stored per registered product (or, without a product, per NCM) and per scenario (operation type and code, regimes, profiles, origin and UFs), and reused for up to 500 hours. On reuse, bases and amounts are always recalculated with the current request's values; what is reused is the rule (CST, rates, reductions).
- Reuse applies to Simples Nacional issuers, to enabled accounts and to the calculation done in the product registry. It is restricted to simple taxation scenarios (for example, CST 00, 40, 41 and 60 and CSOSN 102, 400 and 500, without IPI and with PIS and COFINS without a rate) and to specific issuer and recipient profiles. All other scenarios always query the engine.
- If the rules engine fails, Taxes uses, in this order: (a) the stored result, even if expired, when reuse applies to the scenario and there is a result for all items; (b) when the engine is unavailable or found no rule, the ICMS CST 40 rule registered on the product (with CFOP and PIS and COFINS CST), when it covers all items. Without either, the calculation fails with the original error: nothing is presumed.
6.4 Custom taxation and tax benefit
- The product registry can carry its own rules (
customTax) per scenario (operation, regimes and profiles, intrastate or interstate operation). When the scenario matches, these rules replace the engine's: CFOP, CST/CSOSN, rates, base modality, base reduction, FCP, PIS and COFINS, tax benefit code and additional information. - When the custom taxation defines CST 40 or 41, the engine indicates a tax benefit code (cBenef) for the scenario and the product does not provide its own code (
benefitCode), Taxes responds 422 before issuance, avoiding the later SEFAZ rejection (cStat 930/931).
6.5 IBS and CBS
IBS and CBS are calculated by a dedicated NFE.io service, in a separate call made by the NF-e and the NFC-e for items that request the official calculation (ibscbs.calculationMode = OfficialService, with the tax classification code). The nominal rates follow the transition schedule of the Consumption Tax Reform.
6.6 Product registry
- The registry is validated asynchronously. A product without custom taxation is activated (
Active). A product with custom taxation goes throughCustomTaxPendingwhile the rules are registered and checked in the engine and, at the end, becomesActiveorError. - Status changes generate the
product_taxwebhook, with the actionscreated_successfully(active),custom_rules_requested(custom taxation under review) andcreation_failed(error).
6.7 Error responses
| HTTP | Situation |
|---|---|
| 400 | Invalid data, product not active, product without NCM, unsupported tax profile, data refused by the rules engine |
| 403 | Route account differs from the API key account |
| 422 | Tax rule not found for the scenario, rules engine error or missing mandatory cBenef |
| 500 | Unexpected failure or communication failure with the rules engine; on the public route, also temporary engine unavailability |
| 503 | Rules engine temporarily unavailable, on the internal call made by issuance (treated as a transient failure, section 8.4) |
7. Taxes Payment Forms: tax payment slips
- Purpose: generate the tax payment slip for the interstate DIFAL (
vICMSUFDest) from an authorized NF-e. - Input: the
idof an NF-e issued by NFE.io (POST /v1/tax-payment-forms/{accountId}/{companyId}/gnre, with payment date and due date) or thenfeProcXML (.../gnre/xml). TheaccountIdmust be the API key's. - Destination: DUA at SEFAZ-ES for operations destined to Espírito Santo; GNRE batch at the GNRE Portal for the other UFs. The SP destination is not supported.
- Validation: the operation must be interstate and have DIFAL greater than zero; otherwise, the request is refused with 400. The slip ends as unnecessary (
ErrorNotNeeded) when the total amount due is zero or when the portal reports an amount below the minimum. - Steps:
Created→Prepared→Transmitted→Generated, with the slip PDF at the end. Any processing failure triggers a new attempt every 10 seconds, up to 100 times. - Default payment date: the next business day, per the São Paulo holiday calendar. A payment date in the past is refused with 400.
- Notification:
tax_payment_formwebhook, with the actionscreated_successfully,creation_failedandcreation_not_needed. - Payment Forms is not called by NF-e or NFC-e issuance: the customer triggers it after the NF-e is authorized.
8. Relationship between NF-e, NFC-e and Taxes
8.1 How the customer requests the calculation
| Taxes | How to request it in the NF-e or NFC-e payload |
|---|---|
| ICMS, ICMS-ST, FCP, DIFAL, IPI, PIS and COFINS | Provide, on the item, the taxDetermination block (operation code, issuer and recipient tax profiles, origin and acquisition purpose). With this block, CFOP becomes optional |
| IBS and CBS | Provide, on the item, tax.ibscbs.calculationMode = OfficialService with the tax classification code |
Without these fields, the amounts provided in the payload are used as received and Taxes is not called.
8.2 When and where the calculation happens
| Product and mode | Where Taxes is called | When |
|---|---|---|
| NF-e | Worker | Creation step, before numbering and signing |
| Asynchronous NFC-e | Worker | Creation step |
| Synchronous NFC-e | API, within the customer's request | Before the invoice is created |
The result is applied to each item: CFOP (checked against the one the customer provided, if any), CST/CSOSN, bases, rates and amounts, cBenef and CEST (when the customer did not provide them). The additional product information is appended to the item's.
8.3 When calculation is skipped
- Credit invoices and debit invoices of types 01, 02, 03, 05 and 08 do not go through the engine.
- An issuer that is a taxpayer liable only for IBS/CBS (without a state tax registration) does not go through the ICMS, IPI, PIS and COFINS calculation, only the IBS and CBS one.
8.4 Calculation failures during issuance
| Taxes response | NF-e and asynchronous NFC-e | Synchronous NFC-e |
|---|---|---|
| Success | Issuance continues | Issuance continues |
| Rejection (4xx), for example, rule not found | Invoice refused (Error, issued_error) with "Error while calculating taxes" and the reason | 422 with code 42201; the invoice is recorded as refused |
| Unavailable (5xx, network failure or service credential failure) | New attempts with increasing waits for up to 50 attempts (about 2.5 hours). Once exhausted, the invoice is refused | 503; no invoice is created and the request can be resent |
| IBS/CBS with credential failure | Up to 5 new attempts | 503 |
| IBS/CBS with another failure | Invoice refused | 422 |
In addition, each call to Taxes has up to 2 internal retries, 5 seconds apart, on network failures, request timeout (408) and server errors, except 503.
9. Resilience rules
9.1 Retries per step
Each step that ends in a transient failure is rescheduled. The first execution of each step is immediate; each repetition waits for the next rung of this ladder, and the count restarts when the invoice changes step:
| Step | Wait between attempts |
|---|---|
| Submission to SEFAZ | 5 s, 10 s, 15 s, 1 min, 5 min and, from then on, 10 min |
| Query by access key | 30 s, 1 min, 2 min, 4 min, 8 min, 16 min, 32 min and, from then on, 64 min |
| Receipt query (asynchronous batch) | 5 s, 10 s, 1 min, 5 min, 10 min, 1 h and, from then on, 13 min |
| Retransmission of NFC-e in offline contingency | Every 10 min |
| Other steps (creation, numbering, notification, cancellation, CC-e, number disablement and transmission of EPEC invoices to the home SEFAZ) | 5 s up to the 10th attempt, 1 min up to the 20th, 5 min up to the 50th and, from then on, 10 min |
Exceptions: in the contingency flow (transmission of EPEC invoices), submission and receipt query follow the ladder of the other steps; in the query by key that has just resent the invoice in the cStat 217 cycle (NFC-e), the submission ladder applies.
9.2 Limits
| Limit | Value | Effect when reached |
|---|---|---|
| Business attempts per step (submission, query, cancellation, CC-e, number disablement) | 100 | The invoice ends with the _failed action (for example, issued_failed). For submission, this corresponds to about 16 hours of continuous unavailability |
| Queries with 217 (NF-e) | 8 | issued_error with cStat 217 |
| Query and resubmission cycles with 217 (NFC-e) | 10 | issued_error with cStat 217 |
| Attempts while tax calculation is unavailable | 50 (about 2.5 hours) | Invoice refused |
| Technical ceiling of attempts per step | 150 | The invoice is closed with an error and the reason is recorded in the events |
| Immediate redeliveries of a failed message | 10 | The message goes to the error queue, without changing the invoice, and can be reprocessed by the operations team |
9.3 Failure classification
| Type | Examples | Handling |
|---|---|---|
| Transient | SEFAZ unavailable, no communication, internal service unavailable, tax calculation unavailable | Repeats the same step with increasing waits |
| Inconclusive | Timeout, batch received without a result, duplicate of the invoice itself | Query by access key |
| Permanent | SEFAZ rejection, schema error, expired or refused certificate, inactive registry, tax calculation rejection | Closes the invoice with the reason |
9.4 Per-invoice lock
- Every step runs under a distributed per-invoice lock, valid for 5 minutes.
- If the lock is taken, the step is rescheduled with waits of 2, 5, 15, 30, 60 and, from then on, 120 seconds (with 20% random jitter, so resumptions do not cluster), without consuming the step's attempt counter. After 30 reschedules (about 52 minutes), the invoice is closed with an error and the reason is recorded.
- In the API, operations that also require the lock (for example, DANFE generation) respond 409 with the
Retry-After: 2header when the invoice is being processed.
9.5 Maximum times
| Call | Maximum time |
|---|---|
| SEFAZ Web Services | Up to 120 s per call |
| Authorization in synchronous NFC-e | Up to 8 s, within the 10 s total limit |
| Tax calculation (issuance call) | 260 s, with up to 2 retries of 5 s |
| Tax rules engine (Taxes call) | 200 s, with up to 2 retries of 5 s and short retries (up to 5, within 5 s) for transient responses |
9.6 Webhooks
- The notification step is repeated while the notification platform is unavailable.
- Delivery to the customer's endpoint is at-least-once, with automatic redelivery on network failure or a non-2xx response (up to 16 attempts over about 45 hours) and an HMAC signature. See the webhook event catalog (Portuguese).
- If the customer has no webhook registered, the platform records this in the invoice history; the result remains available through the query endpoints.
9.7 Infrastructure
- API replicas with horizontal autoscaling.
- Liveness and readiness checks, which verify the event store, storage, broker, cache and the registry and certificate services.
- Per-product error queues for messages that exhaust their redeliveries.
- External heartbeat monitor and end-to-end distributed tracing.
10. Idempotency rules
10.1 Platform guarantees
| Guarantee | How it is achieved |
|---|---|
| A single execution per invoice and per operation | Admission control: the entry of an operation on an invoice (cancellation, CC-e, number disablement, event, credit invoice link) writes a conditional record per invoice and operation; a record with no activity for 24 hours is considered abandoned. A request repeated while the execution is alive is discarded with no new SEFAZ call and no new webhook. Right after completion, a 5-minute window prevents immediate readmission of the same work. For issuance, the control protects internal re-publications; each customer POST creates a new invoice (section 10.2) |
| Message processed once | The consumer records each processed message and discards redeliveries within a 5-minute window |
| One step at a time | Distributed per-invoice lock (section 9.4) |
| Nothing is lost or overwritten | Event Sourcing with optimistic concurrency control: two processes cannot write the same invoice version |
| Safe resumption | A repeated step starts from the recorded state: creating an invoice that already exists resumes the flow; signing is not redone if the XML is already signed |
| No blind resubmission | Timeout and duplicate lead to a query by access key. SEFAZ guarantees access key uniqueness; cStat 204 or 539 with the invoice's own key leads to a query by access key, which recovers the protocol when the invoice is authorized |
| Repeated range disablement | Returns success when the range is already disabled |
| Repeated webhook | The X-Hook-Id header identifies the notification for idempotent handling on the customer side |
10.2 What the customer is responsible for
- Each issuance
POSTcreates a new invoice, with a newidand, if the number is not provided, a new number. The API has no idempotency key for the issuance request. - Keep the returned
idand use it as the reference for query, cancellation and reconciliation. - If the issuance request ends without a response (timeout or dropped connection), do not resend immediately: check the company's invoice listing to see whether the invoice was created.
- If your system provides the invoice number, ensure uniqueness per series: a repeated number is rejected by SEFAZ with cStat 539.
- Handle webhooks idempotently and respond 2xx quickly.
11. Contingency
11.1 Overview
| Product | Mode used | tpEmis | How it is triggered |
|---|---|---|---|
| NF-e | EPEC | 4 | By the customer (strategy Manual) or by NFE.io, per UF (strategy StateTaxAuthorityStatusUnavailable) |
| NFC-e | Offline contingency | 9 | Automatically, on timeout or SEFAZ unavailability, and preventively by a per-UF circuit breaker, for enabled state tax registrations |
The SVC-AN and SVC-RS modes (tpEmis 6 and 7) and the security form modes (FS-IA and FS-DA) are not used by the platform.
11.2 NF-e: EPEC
Configuration
The contingency strategy is defined per state tax registration, in the processingDetails.switchAuthorizerStrategy field of the IE registry (Companies API, creation or update of the state tax registration):
| Strategy | Who decides when contingency starts and ends | How |
|---|---|---|
Manual | The customer | POST /v2/companies/{company_id}/statetaxes/{state_tax_id}/switch-authorizer with {"authorizer": "EPEC", "reason": "<justification>"} to enter and {"authorizer": "Normal", "reason": "<justification>"} to exit. The response carries the previous authorizer, the new one, the justification and the date and time of the switch |
StateTaxAuthorityStatusUnavailable | NFE.io | When it identifies instability at a UF's SEFAZ, the NFE.io operations team activates contingency for that UF. All companies in the UF with this strategy start issuing in EPEC, and return to normal when NFE.io ends the UF contingency |
- Under the
Manualstrategy, the justification provided (reason, 15 to 256 characters to enter EPEC) becomes the invoice'sxJustand the date and time of the switch becomes thedhCont. - Under the
StateTaxAuthorityStatusUnavailablestrategy,xJustanddhContcome from the activation done by NFE.io for the UF. - The platform does not poll the SEFAZ status automatically: per-UF activation is a decision of the operations team, based on SEFAZ monitoring.
Application rules
- Contingency is applied when the invoice is created. Invoices created after activation are issued in EPEC.
- Invoices already in processing at the time of activation do not migrate to EPEC: they keep trying the home SEFAZ, under the retry rules of section 9, until SEFAZ is back.
- From 2026-10-05, validation rule 2P10-20 of NT 2014.001 v1.41 prohibits EPEC for issuers in PR and PB. The platform already has this check implemented, to be activated on the effective date: from then on, EPEC issuance for these issuers is refused with a reference to the rule.
Flow
- The NF-e is generated with tpEmis 4,
dhContandxJust. - The EPEC (110140) event is signed and sent to the National Environment's Event Reception Web Service.
- With the event registered, the invoice gets status
IssuedContingency, the event XML is available at.../xml-epecand the DANFE is printed with the contingency marking. The customer receivesproduct_invoice.issued_successfullywithstatusequal toIssuedContingency. - The goods can move with the EPEC DANFE.
Return to normal
- Contingency ends when the customer switches the authorizer to
Normal(strategyManual) or when NFE.io ends the UF contingency (strategyStateTaxAuthorityStatusUnavailable). New invoices are issued with tpEmis 1 again. - An NF-e issued in EPEC must be transmitted to the home SEFAZ within 168 hours of issuance (Ajuste SINIEF 07/05), keeping the same access key. The later transmission uses batch submission with receipt query; the invoice moves to
Issuedonce authorized. - The NFE.io operations team conducts the regularization of EPEC invoices when contingency ends. The customer follows the pending invoices through the
IssuedContingencystatus.
11.3 NFC-e: offline contingency
Configuration
| Parameter | Production value | Who defines it |
|---|---|---|
| Offline contingency enablement | Per state tax registration | NFE.io, at the customer's request |
| IE authorizer switch strategy | Manual only | Customer, in the IE registry |
| Consecutive failures (timeout or unavailability) to open the UF circuit breaker | 5 | NFE.io |
| Retransmission interval | 10 minutes | NFE.io |
| Total synchronous issuance time in the worker | 10 s | NFE.io |
| Maximum authorization call deadline (synchronous) | 8 s | NFE.io |
| Time reserve for contingency (synchronous) | 2 s | NFE.io |
Offline contingency is enabled per state tax registration. An IE that is not enabled does not issue in contingency: on a timeout, the invoice follows the normal query-by-access-key flow; on SEFAZ unavailability, asynchronous issuance retries and synchronous issuance refuses the invoice (Error), which the customer must resend.
Reactive mode
- Normal authorization (tpEmis 1) ends in a timeout or in SEFAZ unavailability.
- The platform records the failure in the UF circuit breaker.
- For an enabled IE, the invoice is regenerated with tpEmis 9: new access key,
dhContequal to the current date and time andxJustequal to "Intermitência na comunicação com a SEFAZ." ("Intermittent communication with SEFAZ."). The XML is signed again, with the contingency QR Code. The key of the normal attempt is kept as the "abandoned key". - The invoice moves to
IssuedContingency. In asynchronous mode, the customer receivesconsumer_invoice.issued_contingency; in synchronous mode, the response is 200 with this status. The NFC-e DANFE can be delivered to the consumer. - If regeneration fails, the contingency invoice is not recorded and the normal attempt follows the rules for a non-enabled IE (paragraph before Reactive mode).
Proactive mode (per-UF circuit breaker)
- Opening: 5 consecutive failures by timeout or unavailability in the same UF, on any state tax registration, open the circuit breaker for that UF.
- With the circuit breaker open: invoices of enabled IEs go straight to tpEmis 9, without trying normal authorization, with
dhContequal to the date and time the circuit breaker opened. This spares the consumer from waiting on a SEFAZ that is already failing. - Closing: any successful normal authorization in the UF or any authorized contingency retransmission closes the circuit breaker. As a safeguard, the circuit breaker state expires 24 hours after the last recorded failure.
- If the circuit breaker control is unreachable, the platform treats it as closed and proceeds with normal authorization.
Later transmission
- The first transmission is immediate and the following ones happen every 10 minutes, sending the already-signed offline XML.
- Authorized: the invoice moves to
Issued, the customer receivesissued_successfullyand the UF circuit breaker is closed. - Duplicate with the abandoned key: if SEFAZ reports that the original normal attempt (tpEmis 1) was authorized, the original invoice prevails: the platform reconciles the invoice to the tpEmis 1 key, queries the protocol and completes it as
Issued. - Timeout or unavailability: new transmission in the next cycle.
- Permanent rejection: the invoice ends with
Errorandissued_error. Under Ajuste SINIEF 19/16, the taxpayer must regenerate the invoice with the same number and series, without changing amounts, parties and dates, and obtain authorization. - Attempts exhausted: when the limit of 100 submission attempts is reached (section 9.2), the invoice ends with
issued_failedand requires handling.
The legal transmission deadline is the end of the first business day after issuance (Ajuste SINIEF 19/16). The 10-minute cycle exists to regularize the invoice well before that deadline as soon as SEFAZ is back.
Additional rules
- Cancellation is accepted only after the contingency invoice is authorized.
- The numbering of an NFC-e issued in contingency cannot be disabled.
- EPEC is not used for the NFC-e: the NFC-e IE strategy must be
Manual, and the available contingency is offline.
11.4 Configuration summary
| Parameter | Product | Where it is configured | Values |
|---|---|---|---|
processingDetails.switchAuthorizerStrategy | NF-e and NFC-e | State tax registration registry (Companies API) | Manual, StateTaxAuthorityStatusUnavailable (NF-e only) |
switch-authorizer (authorizer, reason) | NF-e | POST /v2/companies/{company_id}/statetaxes/{state_tax_id}/switch-authorizer | EPEC or Normal, with justification |
| Per-UF contingency | NF-e | NFE.io operations | Active or inactive, with justification and start |
| Per-IE offline contingency | NFC-e | NFE.io operations, at the customer's request | Enabled or not |
| Per-UF circuit breaker threshold | NFC-e | Platform configuration | 5 consecutive failures (timeout or unavailability) |
| Retransmission interval | NFC-e | Platform configuration | 10 minutes |
| Synchronous issuance deadlines | NFC-e | Platform configuration | 10 s total, 8 s for SEFAZ, 2 s reserve |
12. Customer responsibilities
- Keep the A1 certificate valid and the company and state tax registration data up to date (series, environment, NFC-e CSC, contingency strategy).
- Keep the
idof each invoice and do not resend requests without checking first (section 10.2). - Ensure numbering uniqueness per series when your system provides the number.
- Register webhooks and handle them idempotently, responding 2xx quickly.
- Under the NF-e
Manualstrategy, decide when EPEC contingency starts and ends and follow, through theIssuedContingencystatus, the regularization of the invoices within the legal deadline. - For NFC-e in offline contingency, deliver the NFC-e DANFE with the contingency indication to the consumer and regularize invoices that end in rejection.
- Respect the legal deadlines for cancellation, CC-e and number disablement.
13. Government references
- Portal Nacional da NF-e (NF-e National Portal), Manual de Orientação do Contribuinte (MOC, Taxpayer Guidance Manual) version 7.0: https://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=ndIjl+iEFdE%3D
- Anexo III, Manual de Contingência da NF-e (Annex III, NF-e Contingency Manual): https://www.confaz.fazenda.gov.br/legislacao/arquivo-manuais/moc7-anexo-iii-manual-contingencia-nf-e.pdf
- Anexo IV, Manual de Contingência da NFC-e (Annex IV, NFC-e Contingency Manual): https://www.confaz.fazenda.gov.br/legislacao/arquivo-manuais/moc7-anexo-iv-manual-contingencia-nfc-e.pdf
- Portal Nacional da NF-e, Notas Técnicas (Technical Notes) (NT 2025.002, Reforma Tributária do Consumo (Consumption Tax Reform); NT 2014.001, EPEC): https://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=04BIflQt1aY%3D
- Portal Nacional da NF-e, Relação de Serviços Web (Web Services list): https://www.nfe.fazenda.gov.br/portal/webServices.aspx?tipoConteudo=OUC/YVNWZfo%3D
- CONFAZ, Ajuste SINIEF 07/05 (NF-e): https://www.confaz.fazenda.gov.br/legislacao/ajustes/2005/AJ007_05
- CONFAZ, Ajuste SINIEF 19/16 (NFC-e): https://www.confaz.fazenda.gov.br/legislacao/ajustes/2016/AJ_019_16