TF Fiscal
Documentation

Invoice e-mail

Send invoice e-mail

Accepts sending an authorized document to the customer by e-mail; delivery is asynchronous.

POST/openapi/v2/empresas/{empresaId}/emails
Requires the token, timestamp and sign signature headers, see Authentication.

Sends an already authorized document (NF-e, NFS-e, CT-e or DC-e) by e-mail, with the template body and, if requested, the PDF and XML attached. The call is asynchronous: HTTP 200 returns the emailId and the acceptance status; the outcome arrives through email.sent / email.failed or through the query. id is the idempotency key; while an e-mail of the same document is in flight, another send answers 409. The document is only sent when you call this endpoint: nothing goes out automatically on authorization.

Path parameters

empresaId*
stringCompany identifier

* Required field

Request body

id*
stringRequest identifier
tipoDocumento*
stringDocument type
documentoId*
stringDocument identifier
templateId
stringTemplate identifier
enviarPdf*
boolAttach PDF
enviarXml*
boolAttach XML
destinatarios
arrayRecipients

* Required field

200
Acceptance receipt. Keep the emailId for the query; follow the outcome through the webhook or the query.
emailId
stringE-mail identifier
id
stringRequest identifier
status
stringStatus at acceptance
tipoDocumento
stringDocument type
documentoId
stringDocument identifier
templateId
stringTemplate used
destinatarios
arrayEffective recipients
anexos
arrayRequested attachments

HTTP 200 is only the acceptance: the e-mail is built and sent afterwards by a platform task. The sender is the platform address (your own domain cannot be used); the display name is the company legal name and the reply-to is the company registered e-mail. The outcome arrives through email.sent / email.failed (explicit subscription, see Register webhook) or through the query.

Body and XML only

NFS-e with a chosen template and an explicit recipient; enviarPdf = false skips DANFSe generation. The attached XML is named NFSe-{chave}.xml.

json
{
"id": "mail-nfse-000123",
"tipoDocumento": "NFSe",
"documentoId": "PED-20260918-001",
"templateId": "2103150000000000002",
"enviarPdf": false,
"enviarXml": true,
"destinatarios": ["financeiro@cliente.com.br"]
}
id*
stringRequest identifier
tipoDocumento*
stringDocument type
documentoId*
stringDocument identifier
templateId
stringTemplate identifier
enviarPdf*
boolAttach PDF
enviarXml*
boolAttach XML
destinatarios
arrayRecipients

* Required field

PDF and XML to the e-mail on the document

Without destinatarios the platform uses the customer e-mail given at issuance; only NF-e and NFS-e carry it, CT-e and DC-e require destinatarios. Without templateId it uses the default template of the type. If the PDF or the XML is not available yet, the e-mail waits in Aguardando instead of going out incomplete.

json
{
"id": "email-pedido-8842-1",
"tipoDocumento": "NFe",
"documentoId": "pedido-8842",
"enviarPdf": true,
"enviarXml": true
}
id*
stringRequest identifier
tipoDocumento*
stringDocument type
documentoId*
stringDocument identifier
enviarPdf*
boolAttach PDF
enviarXml*
boolAttach XML

* Required field

São Paulo NFS-e waiting for the key

An NFS-e from the São Paulo municipal system gets its 50-digit key later, through the national environment. Until it arrives, the send is accepted as Aguardando with motivoEspera = chaveAcesso and rechecked every 30 seconds, for up to 120 minutes; after that it becomes Falha and motivoFalha says what was missing. The response below is the acceptance one.

json
{
"emailId": "2103160000000000002",
"id": "mail-sp-000045",
"status": "Aguardando",
"tipoDocumento": "NFSe",
"documentoId": "SP-20260928-045",
"templateId": "2103150000000000002",
"destinatarios": ["financeiro@cliente.com.br"],
"anexos": ["pdf", "xml"]
}
status*
stringStatus at acceptance

* Required field

Same document in flight: 409

While an e-mail of the same document (same company, tipoDocumento and documentoId) has not reached Enviado or Falha, a new send with another id is refused with HTTP 409 and 10021015; the message carries the emailId and status of the in-flight e-mail. Wait for the callback or query, then resend with a new id.

json
[
{
"codigo": "10021015",
"mensagem": "O e-mail anterior desta nota ainda não foi concluído: emailId=2103160000000000001 status=Enfileirado"
}
]

Idempotent replay

Repeating a call with the same id (within the same company) returns the original result without creating another e-mail, even if the body differs; status reflects the current state. To send the same document again use a new id after the terminal state.

json
{
"emailId": "2103160000000000001",
"id": "email-pedido-8842-1",
"status": "Enviado",
"tipoDocumento": "NFe",
"documentoId": "pedido-8842",
"templateId": "2103150000000000001",
"destinatarios": ["comprador@exemplo.com"],
"anexos": ["pdf", "xml"]
}
status*
stringStatus at acceptance

* Required field