TF Fiscal
Documentation

NF-e verification

XML verification

Submits the raw NF-e XML; returns the Tier-1 verdict and the parsed invoice and starts the SEFAZ verification.

POST/openapi/v3/consultas/nf-e/xml

Requires the token, timestamp and sign signature headers, see Authentication.

Submits the raw NF-e XML. Returns the Tier-1 verdict and the parsed invoice data synchronously; on Tier-1 pass, Tier-2 SEFAZ verification starts automatically and the final verdict arrives through the invoice.verify.completed webhook (see NF-e verification).

HTTP 200 means the request was accepted, not that the invoice passed. A well-formed XML that fails validation still returns 200; the verdict is in the validation block. Never branch on the HTTP status to decide validity.

Parameters

Headers

  • Content-Typestringrequired

    application/xml or text/xml.

  • forceRevalidatebooleanoptional

    Optional, default false. Send true to force re-verification even when a reusable terminal verdict exists. Not part of the signature. See Idempotency and re-verification below.

Responses

200

Request accepted. Parsed invoice data plus the validation block with the Tier-1 verdict. Includes failed validation: check validation.validationStatus and validation.errors.

  • tipostring

    Document type.

    Values:NF-eNFC-e
  • modelostring

    Document model.

    Values:5565
  • statusstring

    SEFAZ fiscal status.

    Values:AutorizadaCanceladaDenegadaInutilizadaNaoEncontradaDesconhecida
  • statusDescriptionstring

    Localized description of status, per request language (see Response localization in NF-e verification).

  • ambienteEmissaostring

    Environment the document was issued in.

    Values:ProducaoHomologacao
  • numerostring

    Invoice number nNF, no leading zeros.

  • seriestring

    Series number.

  • dataEmissaostring

    Issue time dhEmi, ISO-8601 with UTC offset, verbatim from the document (e.g. 2026-07-23T11:20:05-03:00).

  • chaveAcessostring

    44-digit access key.

  • emitenteobject

    Issuer.

  • destinatarioobject

    Recipient.

  • itensarray

    Invoice line items.

  • dataAutorizacaostring | null

    SEFAZ authorization time dhRecbto (ISO-8601); null when the submitted XML carries no protocol node.

  • protocoloobject | null

    Authorization protocol; null when there is no protocol node.

  • valorTotalnumber

    Invoice net total vNF (after discounts), 2 decimal places.

  • validationobject

    Tier-1 verdict block. Present on this endpoint only.

Errors

CodeHTTP
10015000400

Empty request body. Send the XML in the body.

10015001400

Body exceeds 1 MB. An authentic single NF-e never exceeds this; check that you are not wrapping or double-encoding.

10015002400

DTD detected (<!DOCTYPE). Strip DTDs; they are rejected as an XXE safeguard.

10015003400

Encoding is not UTF-8. Convert to UTF-8 before submitting.

Request body and signing

  • Preferred: the full nfeProc authorized document (including the protNFe protocol node). A bare NFe without the protocol node is also accepted: it produces a warning but is processed normally.
  • Hard limits: max 1 MB, UTF-8 only, DTD forbidden (any <!DOCTYPE is rejected outright).
  • Signing: the body participates in the signature after stripping every CR and LF, while the request body itself is sent unchanged:
text
sign = md5Hex(app_secret + "/openapi/v3/consultas/nf-e/xml" + xmlWithoutCrLf + timestamp)

The forceRevalidate header is not part of the signature. Full rules in Authentication.

Amount semantics

Line-level itens[].valorTotal is the gross line amount (vProd, before discount); root-level valorTotal is the net invoice total (vNF, after discount). The difference equals the total discount.

Tier-1 validation errors

Returned with HTTP 200 inside validation.errors[]. These are not transport errors: the request succeeded, the document failed. All are blocking (terminal REJECTED) except PROTOCOL_MISSING, which is a warning.

errors[].codeNumericMeaning
XML_MALFORMED10015100XML syntax invalid
XSD_INVALID10015101Does not conform to the NF-e 4.00 XSD layout
SIGNATURE_INVALID10015102Digital signature verification failed (content tampered, or certificate expired at signing time)
SIGNATURE_CERT_MISMATCH10015103Signing certificate CNPJ does not match the issuer
ACCESS_KEY_INVALID10015104chave structure / check digit invalid
ACCESS_KEY_MISMATCH10015105chave segments do not match the document fields
PROTOCOL_MISMATCH10015106Protocol block inconsistent with the document
PROTOCOL_MISSING10015107No protocol node (warning, non-blocking)
XML_VERSION_UNSUPPORTED10015108Layout version is not 4.00

Tier-2 outcomes (webhook)

Once Tier 1 passes, the final verdict arrives only through the invoice.verify.completed webhook; headers, payload and receiver requirements are in NF-e verification. These are not HTTP errors.

validationStatusTerminal?Action
VALIDATEDYesSafe to proceed (release goods, settle, etc.)
REJECTEDYesDo not proceed; reason explains the SEFAZ verdict (cancelled / denied / voided / not found / protocol mismatch)
VALIDATION_ERRORNoPlatform-side verification failure, not an invoice judgment; resubmit later with forceRevalidate: true

Idempotency and re-verification

  • XML verification is idempotent on the chave: resubmitting while a verification is in progress returns the current progress; terminal verdicts are reused for 24 hours (no duplicate verification cost).
  • Forced re-verification: send the header forceRevalidate: true (not part of the signature). The chave lookup has a fixed GET shape with no re-verification channel; to force a re-check, resubmit through this endpoint.
  • A Tier-1 blocking REJECTED has no Tier-2 record; re-verification requires resubmitting the XML.