TF Fiscal
Documentação

E-mail de notas

Envie NF-e / NFS-e / CT-e / DC-e autorizadas por e-mail ao cliente: modelos e variáveis, HTML do corpo e imagens, anexos e links de download, regras do remetente, estados, idempotência e 409, eventos de webhook, modelo de erros e checklist de integração.

Visão geral e fluxo de integração

PassoEndpointObservações
1 Salvar modeloPOST /openapi/v2/emails/templatesDo integrador, compartilhado por todas as empresas; pode haver vários por tipo de documento, padrao marca o padrão
2 Registrar callbackPOST /openapi/v1/webhooksInclua email.sent e email.failed em eventos; sem assinatura só resta a consulta
3 EnviarPOST /openapi/v2/empresas/{empresaId}/emailsDevolve o emailId na aceitação; a entrega é assíncrona
4 ConsultarGET /openapi/v2/empresas/{empresaId}/emails/{emailId}Status, motivo da espera, motivo da falha e o que foi enviado
ApoioGET .../emails/templates · GET .../emails/templates/{templateId}Lista e detalhe dos modelos; o detalhe traz a lista de variáveis permitidas

A autenticação é a mesma dos demais endpoints: cabeçalhos token / timestamp / sign, veja Autenticação. O e-mail só sai quando você chama o endpoint de envio; nada é enviado automaticamente na autorização.

Modelos e envio

  • O modelo pertence ao integrador, não a uma empresa; qualquer empresa registrada usa qualquer modelo.
  • Cada modelo tem um tipo de documento (tipoDocumento) e um idioma (idioma) fixos. Pode haver vários por tipo, por exemplo um por idioma.
  • Cada tipo de documento tem no máximo um modelo padrão (padrao = true), independentemente do idioma. O envio sem templateId usa esse; sem padrão devolve 10021012. Para usar outro modelo, informe templateId no envio.
  • Marcar um modelo como padrão tira o padrão anterior do mesmo tipo; um modelo desativado (ativo = false) não serve para o envio nem pode ser padrão.
  • Salvar substitui o modelo inteiro: com templateId, reenvie todos os campos; campo opcional omitido volta ao valor padrão.
  • No envio o modelo precisa estar ativo e ser do tipo da nota, senão 10021002.

Variáveis

Escreva {{nome}} no assunto ou no corpo; o nome começa com letra e aceita letras, dígitos, sublinhado e ponto, com espaços opcionais dentro das chaves. Ao salvar, cada nome é conferido contra a lista do tipo de documento; nome desconhecido devolve 10021003. Ao renderizar, variável sem valor vira texto vazio. No corpo o valor é escapado como HTML; no assunto, não.

Comuns aos quatro tipos:

VariávelSignificado
numeroNúmero do documento
serieSérie
chaveAcessoChave de acesso, 44 ou 50 dígitos
dataEmissaoData de emissão, fuso de São Paulo
valorTotalValor total: total da NF-e, valor do serviço da NFS-e, valor total da prestação do CT-e, valor declarado da DC-e
emitente.nomeRazão social do emitente
emitente.cnpjCNPJ do emitente
cliente.nomeNome do destinatário da nota: comprador da NF-e, tomador da NFS-e e do CT-e, destinatário da DC-e
cliente.documentoDocumento do destinatário, CPF ou CNPJ
linkPdfLink de download do PDF
linkXmlLink de download do XML autorizado; vazio se o XML ainda não foi arquivado

Próprias de cada tipo:

TipoVariávelSignificado
NFSecodigoVerificacaoCódigo de verificação da NFS-e
NFSemunicipioNome do município do emitente
NFSedescricaoServicoDescrição do serviço
NFSevalorIssValor do ISS
CTeremetente.nomeNome do remetente da carga
CTedestinatario.nomeNome do destinatário da carga
CTevalorFreteValor total da prestação
DCemarketplace.siteSite do marketplace, do cadastro de DC-e do emitente

Valores e datas seguem o idioma do modelo: pt / es usam 1.234,56 e dd/MM/yyyy HH:mm; en / zh usam 1,234.56 e yyyy-MM-dd HH:mm. A hora é sempre a de São Paulo. O campo variaveisDisponiveis de Consultar modelo é a lista completa do tipo.

HTML do corpo e imagens

O corpo é recusado, não limpo: qualquer item fora da lista devolve 10021004 ao salvar, com a posição. Tags permitidas: p, div, span, br, hr, h1 a h6, strong, b, em, i, u, s, ul, ol, li, blockquote, table, thead, tbody, tr, th, td, a, img; atributos permitidos: style, href, src, alt, width, height, align, colspan, rowspan. style não pode conter url(, expression(, position: nem behavior:; href só aceita https:, mailto:, {{linkPdf}} ou {{linkXml}}; o corpo tem no máximo 64 KB.

Imagens só por endereço https. A plataforma não tem upload de imagens; hospede o logotipo num endereço público seu. Imagem http é marcada como conteúdo misto pelos clientes de e-mail e imagem inline data: não aparece em alguns webmails; as duas são recusadas ao salvar. Um exemplo completo com logotipo e botões está em Salvar modelo de e-mail.

  • enviarPdf = true anexa o comprovante em PDF (DANFE / DANFSe / DACTE / DACE) e enviarXml = true anexa o XML autorizado; os arquivos se chamam {tipo}-{chave}.pdf / .xml.
  • Se o comprovante ou o XML ainda não estiver disponível, o e-mail não sai incompleto: fica em Aguardando (motivoEspera = pdf ou xml), reconferido a cada 30 segundos por até 120 minutos; depois vira Falha.
  • Mesmo sem anexar, o corpo pode trazer os links {{linkPdf}} / {{linkXml}}; a validade segue a configuração de links de arquivo do integrador, 7 dias por padrão.

Remetente e destinatários

  • O endereço do remetente é o da plataforma; não é possível usar um e-mail ou domínio próprio. O nome exibido é a razão social do emitente e o responder-para é o e-mail cadastrado da empresa, então respostas do cliente chegam à empresa.
  • destinatarios aceita até 5 endereços; omitido, usa o e-mail do cliente informado na emissão, que só NF-e e NFS-e têm; CT-e e DC-e exigem destinatarios. Sem nenhum, 10021013.
  • Endereços repetidos são unificados e o domínio vira minúsculo; o destinatarios da aceitação e da consulta é a lista efetiva já normalizada.

Estados

text
Aguardando ──► Enfileirado ──► Enviando ──┬──► Enviado (terminal)
└──► Falha (terminal)
StatusSignificadoTerminal
AguardandoAceito, aguardando dados da nota; motivoEspera = chaveAcesso / pdf / xmlNão
EnfileiradoNa fila, dados completosNão
EnviandoRenderizando e enviandoNão
EnviadoAceito pelo serviço de envioSim
FalhaFalha definitiva, motivoFalha explicaSim

Aguardando só existe enquanto falta a chave (a chave de 50 dígitos da NFS-e de São Paulo volta depois pelo ambiente nacional), o PDF ou o XML, e não consome tentativas. Falha na saída é reenviada com espera crescente, até 5 tentativas; esgotadas, vira Falha. Outras causas de Falha: nota que deixou de estar autorizada, modelo desativado depois da aceitação, comprovante que não pode ser emitido.

Idempotência e 409

  • id é a chave de idempotência, única dentro da empresa. Repetir o mesmo id devolve a aceitação original sem criar outro e-mail, mesmo com corpo diferente; o status da resposta é o estado atual.
  • Enquanto o e-mail anterior da mesma nota (mesma empresa, tipoDocumento e documentoId) não chega ao estado terminal, um envio com outro id devolve HTTP 409 e 10021015, com emailId e status do e-mail em andamento na mensagem. Espere Enviado / Falha pelo callback ou pela consulta e reenvie com um id novo.

Eventos de webhook

Inclua email.sent e email.failed em eventos ao registrar o webhook; os dois só são entregues a quem os assina explicitamente. O payload é o envelope de evento, com os campos de data em snake_case:

json
{
"version": "1.0",
"event_id": "1950000000000006",
"event_type": "email.sent",
"occurred_at": "2026-09-28T12:00:31Z",
"data": {
"email_id": "2103160000000000001",
"id": "email-pedido-8842-1",
"tipo_documento": "NFe",
"documento_id": "pedido-8842",
"chave": "35241204893402000113650010000117691017244265",
"destinatarios": ["comprador@exemplo.com"],
"status": "Enviado",
"motivo_falha": null
}
}
EventoQuandodata.status
email.sentO serviço de envio aceitou a mensagemEnviado
email.failedFalha definitiva, data.motivo_falha explicaFalha

email.sent significa que o serviço de envio aceitou a mensagem, não que ela chegou à caixa do destinatário. A descrição completa dos campos está em Webhooks.

Modelo de erros

Os endpoints devolvem um array simples:

json
[{"codigo": "10021013", "mensagem": "Sem destinatário: destinatarios não informado e o documento não tem e-mail do cliente"}]
CódigoHTTPSignificadoO que fazer
10001001400Falha de validação de camposCorrija conforme a mensagem
10003000404Empresa não encontradaConfira empresaId
10021001404Modelo não encontrado ou de outro integradorConfira templateId
10021002400Modelo desativado ou de tipo diferente da notaTroque o modelo ou reative-o
10021003400Modelo usa variáveis fora da lista permitidaCorrija os nomes apontados na mensagem
10021004400HTML do modelo com conteúdo proibido ou acima de 64 KBCorrija as posições apontadas na mensagem
10021005400Tipo de documento não suportadoUse só NFe / NFSe / CTe / DCe
10021010404Nota não encontrada ou de outra empresaConfira documentoId e tipoDocumento
10021011400Nota ainda não autorizadaEnvie depois da autorização
10021012400Tipo sem modelo padrãoInforme templateId ou marque um padrão
10021013400Sem destinatárioInforme destinatarios
10021015409E-mail anterior da mesma nota em andamentoEspere o estado terminal e reenvie com id novo
10021020404E-mail não encontrado ou de outra empresaConfira emailId

Erros de autenticação e autorização (10009xxx) estão em Autenticação; a tabela completa em Códigos de erro.

Checklist de integração

  1. Salve um modelo NFe com padrao = true e confira que variaveisDisponiveis na resposta tem 11 itens.
  2. Escreva de propósito {{codigoVerificacao}} no corpo e confira 10021003; troque a imagem por um endereço http e confira 10021004.
  3. Inclua email.sent e email.failed em eventos do webhook.
  4. Envie uma NF-e autorizada (enviarPdf e enviarXml em true, sem destinatarios); confira aceitação Enfileirado, depois email.sent, e assunto e enviadoEm preenchidos na consulta.
  5. Antes do estado terminal, envie a mesma nota com outro id e confira 409 com 10021015; repita com o mesmo id e confira o mesmo emailId.
  6. Envie uma NFS-e de São Paulo e confira aceitação Aguardando com motivoEspera = chaveAcesso, passando a Enviado sozinha quando a chave chegar.