# Conota — documentação completa Portal editorial inteiro, em um arquivo. Gerado automaticamente — a fonte são as páginas em https://docs.conota.dev. Para o contrato da API (endpoints, campos, tipos), veja llms-api.txt. Gerado em 2026-10-29. ============================================================================== # https://docs.conota.dev/docs/comecando/introducao ============================================================================== # Introdução ao Conota O **Conota** é uma plataforma de infraestrutura fiscal para desenvolvedores. A API concentra em uma única integração as operações necessárias para que sistemas, ERPs, plataformas SaaS e aplicações próprias trabalhem com documentos fiscais sem precisar implementar individualmente a comunicação com cada autorizador. A integração principal é feita por **API REST**, com requisições e respostas em JSON. O Conota também disponibiliza uma integração via **Model Context Protocol (MCP)**. Com ela, assistentes e agentes de IA compatíveis consultam informações fiscais, localizam emissões, analisam rejeições e executam fluxos suportados a partir de linguagem natural. ## Quatro superfícies, quatro papéis Nada aqui é redundante — cada endereço responde um tipo diferente de pergunta. | Onde | Para quê | |---|---| | **docs.conota.dev** (aqui) | como integrar: conceitos, fluxos, decisões | | **[api.conota.dev/docs](https://api.conota.dev/docs)** | o contrato exato: endpoints, campos, tipos, enums | | **[api.conota.dev/swagger](https://api.conota.dev/swagger)** | console para disparar chamadas com a sua chave | | **[mcp.conota.dev](https://mcp.conota.dev)** | as ferramentas publicadas para agentes de IA | Quando você precisar do **nome exato** de um endpoint, dos campos aceitos ou do schema de uma resposta, vá à Referência da API. Este portal não copia tabelas de campos: elas são geradas do código do gateway, e uma cópia manual envelheceria em silêncio. ## Endereço da API ```text https://api.conota.dev ``` ## Escolha seu caminho - **Quero integrar o Conota ao meu sistema:** siga para [Onboarding da integração](/docs/comecando/onboarding). - **Quero consultar os endpoints:** abra a [Referência da API](https://api.conota.dev/docs). - **Quero testar uma chamada agora:** abra o [Swagger](https://api.conota.dev/swagger). - **Quero conectar um assistente de IA:** veja o [Conota MCP](/docs/mcp/introducao). > **INFO — Onde termina a nossa responsabilidade** > O Conota valida estrutura, assina e executa a comunicação fiscal. A **definição tributária da > operação** — CFOP, CST/CSOSN, alíquotas, NCM — continua sendo da sua regra de negócio. Esta > documentação diz explicitamente onde essa fronteira passa, em vez de fingir que tributação é > genérica. ============================================================================== # https://docs.conota.dev/docs/comecando/onboarding ============================================================================== # Onboarding da integração Este roteiro apresenta a sequência recomendada para colocar uma integração em funcionamento sem pular etapas importantes. ## Ordem recomendada 1. Crie sua conta no Conota. 2. Gere uma **API Key** no painel. 3. Armazene a chave em um gerenciador de segredos ou variável de ambiente. 4. Faça uma primeira chamada de **consulta** para validar autenticação e conectividade. 5. Cadastre o **emitente** que utilizará a API. 6. Envie e valide o **certificado digital A1**. 7. Configure os dados fiscais do tipo de documento que será emitido. 8. Monte um primeiro payload seguindo a Referência da API. 9. Emita em **homologação**. 10. Guarde o `job_id` retornado e acompanhe o processamento até um estado final. 11. Implemente **webhooks** ou a estratégia de consulta adequada à sua operação. 12. Antes de escalar, valide rejeições, retentativas, idempotência, logs e armazenamento dos arquivos retornados. ## Antes da primeira emissão Confirme que você possui: - API Key válida; - emitente cadastrado; - certificado A1 válido; - dados fiscais necessários ao documento; - numeração e série corretas; - integração preparada para tratar uma **resposta assíncrona**; - forma de localizar a emissão depois, pelo `job_id` ou pela sua `referencia_externa`. ## Confira o número antes de emitir O Conota emite com o número que **você** enviar. Para saber em que ponto cada sequência está, existe uma rota dedicada: ```http GET /v1/empresas/numeracao ``` Ela devolve o número da **última nota autorizada** por empresa, tipo, série e ambiente. > **ATENÇÃO — Consulta não é reserva** > Entre você ler o último número e a nota sair, outra emissão pode ter usado o seguinte. Trate o > retorno como fotografia, não como garantia. Homologação e produção são sequências > **independentes**. ## Não comece pela emissão em massa Valide **uma** emissão completa de ponta a ponta: envio, processamento, autorização, consulta e recuperação de XML/PDF. Depois provoque uma rejeição controlada e veja seu código tratá-la. Só então aumente o volume. ## Próximos passos - [Ambientes](/docs/comecando/ambientes) - [Autenticação](/docs/comecando/autenticacao) - [Sua primeira requisição](/docs/comecando/primeira-requisicao) - [Empresas e emitentes](/docs/conceitos/empresas) ============================================================================== # https://docs.conota.dev/docs/comecando/ambientes ============================================================================== # Ambientes Operações fiscais têm comportamentos diferentes conforme o ambiente do autorizador. Antes de emitir, confirme se a empresa e o documento estão configurados para o ambiente correto. ## Duas coisas têm ambiente, não uma Esta é a origem mais comum de confusão na primeira integração: 1. **A sua API Key** é de produção **ou** de homologação — ela não alterna. É por isso que você recebe duas na criação da conta. 2. **A configuração de cada empresa** também tem ambiente (`PUT /v1/empresas/{cpf_cnpj}/nfe`, `/nfce`, `/nfse`). E o que acontece quando as duas discordam **depende do documento**: | Documento | Onde fica a configuração | Se a chave e a configuração discordam | |---|---|---| | **NF-e** | uma configuração por empresa | **`403`**, com a mensagem dizendo qual é qual | | **NFC-e** | uma configuração por empresa | **`403`**, igual à NF-e | | **NFS-e** | **uma configuração por ambiente** | não há conflito: **a chave escolhe** qual configuração vale | A mensagem do `403` é literal: > *Ambiente incompatível: sua API Key é de produção, mas o emitente está configurado para > homologação. Use uma API Key de homologação ou altere a configuração do emitente.* > **ATENÇÃO — O campo `ambiente` muda de tipo entre as rotas** > | Rota | Valor | > |---|---| > | `PUT /v1/empresas/{cpf_cnpj}/nfe` e `/nfce` | **número**: `1` produção, `2` homologação | > | `PUT /v1/empresas/{cpf_cnpj}/nfse` | **texto**: `"producao"` ou `"homologacao"` | > > É a divergência que mais causa erro na configuração inicial. Mandar `2` na rota de NFS-e não > configura homologação — é valor inválido. > **DICA — NFS-e: configurar produção não mexe em homologação** > Como a configuração de NFS-e é **por ambiente**, cada um tem a sua própria numeração de RPS e as > suas próprias credenciais de prefeitura. Configurar um não altera o outro — e emitir com a chave de > produção usa a configuração de produção, sempre. ## Homologação Use homologação durante todo o desenvolvimento. Documentos emitidos em homologação **não têm valor fiscal** e não devem ser tratados como documentos válidos da operação real da empresa. ## Produção Produção é o ambiente de documentos com **efeito fiscal real**. Uma nota autorizada aqui produz consequências tributárias. Antes de migrar: - valide autenticação; - valide o cadastro do emitente; - confira o certificado e a validade; - teste o fluxo de consulta após a emissão; - implemente tratamento de rejeições; - implemente proteção contra emissões duplicadas (ver [referência externa](/docs/conceitos/referencia-externa)); - confirme numeração e série. > **IMPORTANTE — Numeração não se mistura entre ambientes** > Cada ambiente tem a **própria sequência**. O último número autorizado em homologação não diz nada > sobre produção. `GET /v1/empresas/numeracao` devolve as duas separadas justamente por isso. ## Atenção à NFS-e A disponibilidade de homologação **depende do município ou provedor**. Nem todo ambiente municipal reproduz o comportamento da produção, e alguns simplesmente não oferecem ambiente de teste. Consulte [NFS-e](/docs/documentos/nfse/visao-geral) antes de assumir que um município possui ambiente de homologação. ============================================================================== # https://docs.conota.dev/docs/comecando/autenticacao ============================================================================== # Autenticação Toda chamada à API do Conota é autenticada por uma **API Key**, criada no painel em **Integração → Chaves de API**. Ela identifica a sua conta, carrega as permissões dela e vale até você revogá-la. ```http X-API-Key: sua_chave_aqui ``` Não existe passo de "obter um token" antes de chamar a API: a chave já é a credencial. > **ATENÇÃO — Na API REST é `X-API-Key`, e só** > Mandar a chave em `Authorization: Bearer` **não funciona** na API REST — a resposta é > `401 Token invalido ou expirado`, porque esse header é interpretado como sessão do painel. > > A exceção é o **[Conota MCP](/docs/mcp/conectar)**, que aceita a chave nos dois headers. Se o seu > cliente MCP só oferece "Bearer token", pode usar lá sem problema. O login por e-mail e senha existe, mas é do **painel**: cria uma sessão de pessoa, que expira e termina no logout. Não é caminho de integração — um programa num servidor não deveria depender de alguém digitar senha a cada 12 horas. ## Segurança da API Key > **IMPORTANTE — Nunca em código que roda no navegador** > Uma API Key do Conota dá poder de **emitir documento fiscal com efeito real**. Colocá-la em > JavaScript entregue ao navegador equivale a publicá-la. Nunca inclua uma chave em: - código publicado em repositório; - aplicações frontend executadas no navegador; - mensagens de suporte ou capturas de tela; - arquivos de configuração versionados sem proteção. Prefira variáveis de ambiente ou um serviço de gerenciamento de segredos. ## Uma chave representa acesso Qualquer aplicação com uma chave válida executa as operações permitidas para aquela credencial. Se houver suspeita de exposição, **revogue no painel** — Integração → Chaves de API — e gere outra. A revogação vale na hora. ## MCP usa a mesma chave O [Conota MCP](/docs/mcp/introducao) utiliza a **mesma API Key** da API REST, com as mesmas permissões. Não existe hoje uma chave só de leitura: quem conecta o MCP com a chave da conta recebe junto a capacidade de emitir. Ver [Segurança no MCP](/docs/mcp/seguranca). ============================================================================== # https://docs.conota.dev/docs/comecando/primeira-requisicao ============================================================================== # Sua primeira requisição Antes de emitir um documento fiscal, faça uma chamada simples para confirmar três coisas: 1. seu sistema alcança a API; 2. a API Key está sendo enviada corretamente; 3. sua aplicação consegue interpretar a resposta. Uma consulta de leitura é a melhor escolha para esse primeiro teste. ## Listar as empresas da conta ```bash curl -s https://api.conota.dev/v1/empresas \ -H "X-API-Key: $CONOTA_API_KEY" ``` Se voltar uma lista (mesmo vazia), autenticação e conectividade estão corretas. ## Consultar um CNPJ ```bash curl -s https://api.conota.dev/v1/cnpj/11222333000181 \ -H "X-API-Key: $CONOTA_API_KEY" ``` Aceita **CNPJ alfanumérico**. > **ATENÇÃO — Na URL, mande sem a barra** > A barra da máscara do CNPJ (`00.000.000/0001-91`) é **separador de caminho**: a URL vira > `/v1/cnpj/00.000.000/0001-91` e a rota não é encontrada — você recebe **404**. > > Em parâmetro de **caminho**, envie só os dígitos. Em **query string** e no **corpo** da > requisição, a máscara completa funciona normalmente. ## Se preferir clicar antes de codar Abra o [Swagger UI](https://api.conota.dev/swagger), clique em **Authorize**, cole a chave e execute o endpoint. É a forma mais rápida de ver a resposta real antes de escrever código. ## Depois que funcionar Não copie a requisição do Swagger direto para produção. Implemente no backend e configure: - timeout; - logs **sem** expor segredos; - tratamento por código HTTP; - retentativa apenas para falhas que realmente podem ser repetidas; - correlação entre a operação do seu sistema e a operação criada no Conota. > **INFO — Nem toda falha pode ser repetida** > Repetir uma **consulta** é inofensivo. Repetir uma **emissão** não é. Ver > [Referência externa e idempotência](/docs/conceitos/referencia-externa). ============================================================================== # https://docs.conota.dev/docs/comecando/primeira-emissao ============================================================================== # Sua primeira emissão Uma emissão fiscal **não é um `POST` que termina quando a API responde**. O Conota recebe a solicitação, cria uma operação de emissão e executa o processamento até existir um estado conclusivo ou uma situação que exija ação da sua integração. ## O que a API devolve A emissão responde **HTTP 202** com o identificador do trabalho: ```json { "job_id": "6f8dc295-...", "referencia_externa": "pedido_98231", "status": "pending", "mensagem": "NF-e enfileirada para emissão.", "consulta": "/v1/nfe/consultar/6f8dc295-...", "webhook": "configurado" } ``` **202 não significa autorizada.** Significa aceita para processamento. ## Fluxo ```text Seu sistema │ ├── POST /v1/nfe/emitir ──► 202 { job_id } │ ▼ Conota ├── valida e registra a operação ├── monta e assina o documento ├── transmite ao autorizador │ ▼ Resultado ├── autorizada ├── rejeitada (uma regra fiscal recusou) └── falha (não chegou a uma decisão fiscal) ``` ## Acompanhando ```bash curl -s https://api.conota.dev/v1/nfe/consultar/$JOB_ID \ -H "X-API-Key: $CONOTA_API_KEY" ``` A resposta traz `status`, `tentativas`, o bloco `nota` (número, série, chave de acesso, motivo) e `arquivos` com os links de download. Prefira [webhooks](/docs/conceitos/webhooks) a consultar em laço. ## Guarde os identificadores Ao criar uma emissão, armazene: - o `job_id` retornado; - a sua `referencia_externa`; - tipo de documento; - emitente; - data e hora da solicitação. São esses dados que permitem reconciliar seu sistema com o Conota quando uma conexão cai ou uma resposta não é persistida localmente. ## Não reenvie no escuro > **IMPORTANTE — Timeout não significa que nada aconteceu** > Se a conexão cair depois de você enviar a emissão, **não presuma que falhou**. Primeiro localize: > > ```http > GET /v1/jobs/localizar?ref=pedido_98231 > ``` > > Reenviar às cegas uma operação fiscal pode gerar duplicidade ou conflito de numeração. Melhor > ainda: envie `referencia_externa` desde o começo — reenviar a mesma referência devolve o job > existente em vez de emitir de novo. ## Antes de emitir de verdade, confira o payload Existe uma rota que confere os campos **sem emitir e sem consumir cota**: ```http POST /v1/nfe/verificar-campos ``` Ela pega o erro mais traiçoeiro dessa API: um campo com nome errado é **ignorado em silêncio** — `vlrProd` no lugar de `vProd` gera uma nota válida no schema com o produto a R$ 0,00. ## Próximos passos - [Processamento assíncrono](/docs/conceitos/assincrono) - [Status das emissões](/docs/conceitos/status) - [Erros e rejeições](/docs/conceitos/erros-rejeicoes) ============================================================================== # https://docs.conota.dev/docs/conceitos/empresas ============================================================================== # Empresas e emitentes Uma conta Conota pode operar documentos de **várias empresas**. Cada emitente mantém os próprios dados cadastrais, configurações fiscais, certificado e sequências de numeração. O CNPJ do emitente não é apenas um campo do payload: ele identifica a empresa responsável pelo documento e determina certificado, credenciais fiscais, numeração e comunicação com o autorizador. ## Rotas | Operação | Rota | |---|---| | Listar empresas da conta | `GET /v1/empresas` | | Cadastrar | `POST /v1/empresas` | | Detalhe | `GET /v1/empresas/{cpf_cnpj}` | | Atualizar | `PUT /v1/empresas/{cpf_cnpj}` | | Configurar NF-e / NFS-e / NFC-e | `PUT /v1/empresas/{cpf_cnpj}/nfe` · `/nfse` · `/nfce` | | Enviar certificado A1 | `PUT /v1/empresas/{cpf_cnpj}/certificado` | | Validade dos certificados | `GET /v1/empresas/certificados` | | Em que número cada série está | `GET /v1/empresas/numeracao` | O `{cpf_cnpj}` na URL aceita **CNPJ alfanumérico**. > **ATENÇÃO — Na URL, o CNPJ vai sem a barra** > A barra da máscara é **separador de caminho**. `/v1/empresas/11.222.333/0001-81` não é uma > rota válida — responde **404**. > > Use `11222333000181`. Ponto e hífen até passam (`11.222.333.0001-81`), mas só dígitos é mais > simples. **CPF com máscara funciona** (`125.244.567-90`), porque não tem barra. > > Em query string e no corpo, a máscara completa é aceita. ## Configuração é por tipo de documento Cadastrar a empresa não basta. Cada tipo de documento tem a própria configuração: - **NF-e** — ambiente, CRT, série; - **NFC-e** — exige **CSC** configurado, além da série; - **NFS-e** — município, inscrição municipal, regime, provedor e, em alguns municípios, credenciais da prefeitura. Emitir sem a configuração correspondente falha antes de chegar ao autorizador. ## Antes de emitir Garanta que os dados do emitente estejam atualizados e que as configurações do tipo de documento tenham sido concluídas. Mudanças de razão social, endereço, regime tributário ou credenciais municipais podem exigir atualização cadastral antes de novas emissões. > **INFO — CNPJ alfanumérico** > Desde 31/07/2026 o CNPJ pode ter **letras** nas 12 primeiras posições (os 2 dígitos verificadores > seguem numéricos). A API do Conota aceita o formato novo em todos os pontos que tratam documento. ============================================================================== # https://docs.conota.dev/docs/conceitos/certificado ============================================================================== # Certificado digital Documentos fiscais que exigem certificado usam o certificado digital da empresa para autenticação e assinatura durante a comunicação fiscal. O Conota trabalha com certificado **A1** (arquivo `.pfx`/`.p12` com senha). O A3, por depender de mídia física — token ou cartão —, não se aplica a uma emissão executada em servidor. ```http PUT /v1/empresas/{cpf_cnpj}/certificado ``` ## Validade é item operacional > **IMPORTANTE — Certificado vencido derruba TODAS as emissões da empresa** > Não é uma rejeição pontual: é uma parada total, e ela chega sem aviso no dia do vencimento. Monitore com: ```http GET /v1/empresas/certificados ``` A resposta traz, por empresa, o titular, o emissor, a validade e um `status`: `valido`, `expira_em_breve` (30 dias ou menos), `expirado` ou `sem_certificado` — além de `dias_para_expirar`. O Conota também envia **alertas por e-mail** quando um certificado se aproxima do vencimento. Ainda assim, tenha o seu próprio monitoramento: alerta que depende de um único canal é alerta frágil. ## Segurança O certificado e a senha são credenciais sensíveis. Nunca envie esses dados em tickets, logs, capturas de tela ou repositórios. ## Próximo passo Com o emitente configurado e o certificado válido, vá para [Sua primeira emissão](/docs/comecando/primeira-emissao). ============================================================================== # https://docs.conota.dev/docs/conceitos/assincrono ============================================================================== # Processamento assíncrono A autorização de um documento fiscal depende de sistemas externos — SEFAZ, Ambiente Nacional, prefeitura ou provedor municipal. O resultado definitivo raramente está disponível no mesmo instante em que sua aplicação envia a solicitação. Por isso a emissão devolve **202** com um `job_id`, e o resultado é acompanhado depois. ## O que sua aplicação deve fazer 1. enviar a emissão; 2. **salvar o `job_id`** (e a sua `referencia_externa`); 3. aguardar o [webhook](/docs/conceitos/webhooks) ou consultar o status; 4. só considerar a operação concluída ao atingir um **estado final**. ## Consultando ```http GET /v1/nfe/consultar/{job_id} GET /v1/nfce/consultar/{job_id} GET /v1/nfse/consultar/{job_id} ``` Para muitos jobs de uma vez, existe consulta em lote — até **200 ids** por chamada, resolvida em poucas queries, independente de N: ```http POST /v1/jobs/consultar-lote ``` ```json { "job_ids": ["6f8dc295-...", "8881bac5-..."] } ``` ## Evite polling agressivo > **ATENÇÃO — Consultar em laço não acelera o autorizador** > Um `GET` a cada segundo não faz a SEFAZ responder mais rápido: só gasta a sua cota e a sua banda. Recomendação: - **webhook** como mecanismo principal; - **polling** como recuperação, com intervalo crescente (por exemplo 5s, 15s, 30s, 60s); - **consulta em lote** quando precisar reconciliar muitos jobs. ## Estado final Ver [Status das emissões](/docs/conceitos/status) para saber quais estados encerram o ciclo e quais ainda pedem espera. ============================================================================== # https://docs.conota.dev/docs/conceitos/referencia-externa ============================================================================== # Referência externa e idempotência O sistema que chama o Conota precisa conseguir relacionar uma operação fiscal ao registro correspondente na própria base. Para isso, envie uma **referência externa única** na emissão. ```json { "referencia_externa": "pedido_98231", "cpf_cnpj": "11222333000181", "nota": { "...": "..." } } ``` Até 120 caracteres, letras e números — um UUID serve bem. ## O que ela garante > **INFO — Reenviar a mesma referência não emite outra nota** > A `referencia_externa` é **idempotente por conta**. Reenviar a mesma referência devolve o job já > existente, com `HTTP 200` e `"idempotente": true`, em vez de emitir de novo. ```json { "job_id": "6f8dc295-...", "referencia_externa": "pedido_98231", "idempotente": true, "status": "completed", "mensagem": "Emissão já registrada para esta referencia_externa — retornando o job existente..." } ``` Repare na diferença de código HTTP: **202** é emissão nova, **200** é a mesma de antes. ## Por que isso importa Imagine que sua aplicação envie uma emissão e a conexão caia antes da resposta chegar. Sem uma referência própria, ela fica em dúvida entre três hipóteses: - a emissão nunca chegou; - está sendo processada; - o documento já foi autorizado. Com a referência persistida **antes** do envio, você localiza a operação em vez de adivinhar: ```http GET /v1/jobs/localizar?ref=pedido_98231 ``` A busca por referência é exata e dispensa informar período. ## Para reemitir corrigido, use uma referência NOVA Se a nota falhou e você corrigiu o payload, **não reutilize a mesma referência** — ela devolveria o job antigo em vez de emitir a versão corrigida. Gere uma nova, mantendo no seu banco o vínculo entre as duas tentativas. ## Sem a referência, ainda dá para achar `GET /v1/jobs/localizar` também aceita atributos de negócio: emitente, destinatário, valor exato e período. É o caminho de reconciliação quando o `job_id` se perdeu e não havia referência. ============================================================================== # https://docs.conota.dev/docs/conceitos/status ============================================================================== # Status das emissões > **ATENÇÃO — Não modele com `sucesso = true/false`** > Uma emissão fiscal tem etapas e desfechos diferentes. Reduzir tudo a um booleano faz sua aplicação > tratar uma **rejeição fiscal** — que exige correção de dados — igual a uma **falha de rede** — que > pede nova tentativa. São ações opostas. Existem **dois eixos** de estado, e eles respondem perguntas diferentes. ## 1. O estado do job — o processamento O job é a unidade de trabalho criada quando você chama a emissão. | Status | Significado | |---|---| | `pending` | aceito e enfileirado; ainda não começou | | `processing` | em execução | | `completed` | o processamento terminou **sem erro técnico** | | `failed` | o processamento não chegou ao fim | | `cancelled` | o trabalho foi cancelado antes de concluir | > **IMPORTANTE — `completed` não quer dizer autorizada** > Significa apenas que o Conota concluiu o trabalho e obteve uma resposta do autorizador. Essa > resposta pode ter sido uma **rejeição**. Para saber o desfecho fiscal, olhe o bloco `nota`. ## 2. O estado da nota — o desfecho fiscal | Status | Significado | |---|---| | `autorizada` | o autorizador aceitou; o documento produz efeitos fiscais | | `rejeitada` | o documento chegou ao autorizador e foi recusado por uma regra | | `denegada` | recusado por situação irregular do emitente ou destinatário | | `cancelada` | foi autorizada e depois cancelada | | `inutilizada` | a faixa de numeração foi inutilizada | A consulta traz os dois eixos: ```json { "job_id": "6f8dc295-...", "status": "completed", "tentativas": "1/3", "nota": { "numero": 25, "serie": 1, "chave_acesso": "...", "status": "autorizada", "codigo_status": 100, "motivo_status": "Autorizado o uso da NF-e" }, "arquivos": { "xml": { "...": "..." }, "pdf": { "...": "..." } }, "erro": null } ``` ## Como decidir no seu código ```text job.status == failed -> falha de processamento: analise `erro` job.status == completed └─ nota.status == autorizada -> concluído com sucesso └─ nota.status == rejeitada -> corrija os dados e emita de novo (com uma NOVA referencia_externa) └─ nota.status == denegada -> problema cadastral; não adianta repetir igual ``` > **INFO — Rejeitada não consome numeração** > Uma nota rejeitada **não** consome o número. Não avance a numeração automaticamente só porque uma > tentativa falhou — consulte `GET /v1/empresas/numeracao` antes de decidir. Os nomes exatos e eventuais novos valores estão sempre na [Referência da API](https://api.conota.dev/docs). Esta página explica o significado, não substitui os enums. ============================================================================== # https://docs.conota.dev/docs/conceitos/erros-rejeicoes ============================================================================== # Erros e rejeições A distinção mais importante de uma integração fiscal é separar **erro técnico** de **rejeição fiscal**. Elas pedem reações opostas. ## As quatro categorias ### 1. Erro de requisição O Conota não aceitou a chamada como enviada. Autenticação inválida, campo obrigatório ausente, formato incompatível, cota esgotada. Chega como **4xx**, de forma síncrona. Repetir a mesma chamada sem mudar nada dá o mesmo resultado. ### 2. Falha de processamento O job foi criado, mas alguma etapa anterior à autorização não pôde ser concluída — indisponibilidade do autorizador, erro de comunicação, certificado inválido. Aparece como `status: "failed"` com a mensagem em `erro`. Muitas dessas **podem** ser repetidas. ### 3. Rejeição fiscal O documento chegou ao autorizador e foi **recusado por uma regra fiscal**. Vem com `codigo_status` e `motivo_status` do próprio autorizador. Repetir igual dá rejeição igual: é preciso corrigir os dados. Motivos comuns envolvem cadastro do destinatário, NCM, CFOP, CST/CSOSN, tributação, numeração, inconsistência entre totais e regras específicas do município. ### 4. Documento autorizado A emissão foi aceita e passou a produzir efeitos fiscais. > **ATENÇÃO — Rejeição não é a API fora do ar** > Uma rejeição prova o contrário: o documento chegou até o autorizador. Tratá-la como erro de > infraestrutura leva ao pior comportamento possível — reenviar em laço. ## Reconciliação em lote Para achar o que falhou num período, sem varrer o histórico: ```http GET /v1/jobs/erros?de=2026-09-01&ate=2026-09-03 # jobs com falha GET /v1/jobs/rejeitadas?de=2026-09-01&ate=2026-09-03 # notas rejeitadas ``` Ambas aceitam `formato=resumo` para agrupar por motivo — útil para descobrir que 80% das rejeições da semana são a mesma causa. A janela é de **no máximo 90 dias**; sem datas, os últimos 7. Para entender uma rejeição item a item: ```http GET /v1/jobs/{job_id}/itens ``` Ela marca **qual item** provocou a rejeição, com os grupos tributários de cada um. ## O que registrar no seu sistema - identificador da operação (`job_id`); - `referencia_externa`; - tipo de documento e emitente; - data e hora; - código e mensagem retornados; - ambiente; - status final conhecido. > **IMPORTANTE — Nunca registre segredo em log** > API Key, senha de certificado e o próprio certificado não podem aparecer em log, APM ou ticket. ============================================================================== # https://docs.conota.dev/docs/conceitos/limites ============================================================================== # Limites e cotas Os planos do Conota definem cotas de consumo **por tipo de operação**. As cotas existentes hoje cobrem `nfe`, `nfse`, `nfce`, `cep`, `cnpj` e assinatura eletrônica — além dos documentos de transporte, quando disponíveis. > **INFO — Os números ficam no painel, não aqui** > Valores de cota variam por plano e mudam comercialmente. Consulte o consumo da sua conta no painel; > esta página descreve o **comportamento**, não os limites. ## O que consome cota | Operação | Consome | |---|---| | Emitir NF-e / NFC-e / NFS-e | sim, 1 por emissão | | Consultar CEP / CNPJ | sim | | Consultar emissão, listar notas, relatórios | não | | `POST /v1/nfe/verificar-campos` | **não** | | `POST /v1/nfe/preparar` (emissão assistida) | **não** — só o `confirmar` | | Baixar XML/PDF | não | Reenvio idempotente da mesma `referencia_externa` **não** debita de novo: não houve emissão nova. ## Boas práticas - acompanhe o consumo no painel; - respeite os códigos HTTP e nunca entre em retentativa infinita; - não faça polling agressivo — ver [processamento assíncrono](/docs/conceitos/assincrono); - use **consulta em lote** (`POST /v1/jobs/consultar-lote`) em vez de N chamadas; - use `verificar-campos` para validar payload sem gastar cota; - não repita uma emissão apenas para descobrir o estado dela — use [`/v1/jobs/localizar`](/docs/conceitos/referencia-externa). ## Janela dos relatórios As rotas por período (`/v1/jobs/erros`, `/v1/jobs/rejeitadas`) aceitam **no máximo 90 dias** por consulta. Sem datas, retornam os últimos 7 dias. Acima de 90 dias, a resposta é `400` — pagine por períodos em vez de pedir o histórico inteiro. ============================================================================== # https://docs.conota.dev/docs/conceitos/paginacao ============================================================================== # Paginação Endpoints de listagem retornam resultados paginados para manter as respostas previsíveis mesmo em contas com grande volume. O padrão nas rotas de listagem é `limite` e `pagina`, e a resposta traz o total do filtro: ```http GET /v1/notas?tipo=nfe&status=autorizada&limite=50&pagina=2 ``` ```json { "notas": [ "..." ], "total": 1287, "pagina": 2, "limite": 50 } ``` Os relatórios por data usam `por_pagina` e `pagina`, e devolvem também `paginas`. > **INFO — Os limites exatos estão na Referência** > Tamanho padrão, máximo por página e nomes dos parâmetros de cada rota vivem no > [OpenAPI](https://api.conota.dev/docs). Eles não são iguais em todas as rotas, e copiá-los aqui > criaria uma segunda verdade. ## Evite varrer o histórico > **ATENÇÃO — Listar tudo para achar um documento é o caminho mais caro** > Se você tem o `job_id`, a `referencia_externa`, a chave de acesso ou os atributos da operação, use > a busca direcionada. | Você tem | Use | |---|---| | `job_id` | `GET /v1/nfe/consultar/{job_id}` | | vários `job_id` | `POST /v1/jobs/consultar-lote` (até 200) | | `referencia_externa` | `GET /v1/jobs/localizar?ref=...` | | chave de acesso | `GET /v1/notas/{chave}` | | só atributos de negócio | `GET /v1/jobs/localizar` com emitente, valor, período | ============================================================================== # https://docs.conota.dev/docs/conceitos/webhooks ============================================================================== # Webhooks Webhooks avisam sua aplicação quando uma operação muda de estado, reduzindo a necessidade de consultas repetidas. Informe a URL na própria emissão: ```json { "cpf_cnpj": "11222333000181", "webhook_url": "https://seu-sistema.com.br/webhooks/conota", "nota": { "...": "..." } } ``` ## Fluxo ```text 1. Seu sistema envia a emissão -> 202 { job_id } 2. O Conota processa 3. O Conota chama o seu webhook (POST, JSON) 4. Seu sistema responde 2xx rapidamente 5. Seu sistema persiste o novo estado ``` ## Headers da notificação ```http POST /webhooks/conota Content-Type: application/json X-Qualyfiscal-Signature: sha256= X-Qualyfiscal-Job-Id: 6f8dc295-... X-Qualyfiscal-Tentativa: 1 ``` > **INFO — Por que o header não se chama `X-Conota-*`** > Esses nomes são **contrato**, não marca. O código dos clientes já lê `X-Qualyfiscal-Signature` para > conferir a assinatura; renomear quebraria a validação de toda integração existente — e a falha > apareceria do lado deles, silenciosamente. Se um dia mudar, os dois nomes conviverão por bastante > tempo antes. ## Validando a assinatura A assinatura é um **HMAC-SHA256 do corpo bruto**, em hexadecimal, prefixado por `sha256=`. ```js const crypto = require('crypto') function assinaturaValida(corpoBruto, headerRecebido, segredo) { const esperado = 'sha256=' + crypto .createHmac('sha256', segredo) .update(corpoBruto) .digest('hex') const a = Buffer.from(esperado) const b = Buffer.from(headerRecebido || '') // timingSafeEqual exige mesmo tamanho — compare o tamanho antes. return a.length === b.length && crypto.timingSafeEqual(a, b) } ``` > **ATENÇÃO — Use o corpo BRUTO, não o JSON reserializado** > `JSON.parse` seguido de `JSON.stringify` pode reordenar chaves e mudar espaçamento — e a assinatura > deixa de bater. Guarde o body cru antes do parse. ## Retentativas Se o seu endpoint não responder, o Conota tenta de novo: | | | |---|---| | Tentativas | **3** no total | | Timeout por tentativa | **10 segundos** | | Intervalos | 30s, depois 60s | O número da tentativa vem em `X-Qualyfiscal-Tentativa`. ## O que o endereço precisa cumprir Estas não são recomendações: **o destino que não atender é recusado antes da conexão**, e a notificação não sai. A nota fiscal não é afetada — o que falha é a entrega. | Exigência | Por quê | |---|---| | **`https://`, na porta 443** | a notificação carrega **links assinados do XML e do PDF**, válidos por 1 hora. Em `http://` isso viaja em claro | | **endereço público** | destino que resolve para rede interna, loopback, link-local ou faixa privada é recusado | | **nome de host, não IP** | endereço com IP literal é recusado | | **sem redirecionamento** | resposta `3xx` conta como falha de entrega — cadastre o endereço final | | **sem usuário e senha na URL** | `https://user:senha@destino` é recusado | A recusa fica registrada no histórico do webhook com o motivo, e **não é reagendada**: destino recusado é falha determinística, e tentar três vezes daria o mesmo "não". ## Seu endpoint deve - responder **rápido** (menos de 10s) e processar o trabalho pesado de forma assíncrona; - **validar a assinatura** antes de confiar no conteúdo; - ser **idempotente** — o mesmo evento pode chegar mais de uma vez; - registrar o `job_id` para auditoria; - devolver um corpo pequeno — lemos no máximo 64 KB da sua resposta. > **INFO — Contas criadas a partir de 05/09/2026 cadastram o destino antes** > Nessas contas, o endereço precisa estar cadastrado no painel, em **Integração → Destinos de > webhook**, e o `webhook_url` da emissão precisa ser igual a um cadastro **ativo do mesmo ambiente**. > > Se não estiver, a emissão é recusada com **`422 webhook_destino_nao_autorizado`** — antes de emitir > e **sem consumir cota**. Nenhuma nota é gerada. > > Contas anteriores a essa data seguem como sempre: o `webhook_url` é livre, e só as exigências de > endereço acima valem. ## Webhook não substitui consulta > **IMPORTANTE — Uma notificação perdida não pode travar a sua operação** > Se o seu servidor estiver fora do ar durante as três tentativas, a notificação se perde. Sua > aplicação precisa conseguir reconciliar o estado mesmo assim. Mantenha uma rotina de recuperação que varra jobs sem estado final e consulte `POST /v1/jobs/consultar-lote`. Webhook é o caminho rápido; a consulta é a rede de segurança. ============================================================================== # https://docs.conota.dev/docs/documentos ============================================================================== # Documentos fiscais O Conota oferece uma interface consistente para integrar diferentes documentos fiscais **sem esconder as particularidades de cada modelo**. Os fluxos compartilham conceitos — emitente, processamento assíncrono, autorização, arquivos — mas cada documento tem regras próprias, definidas pelos respectivos autorizadores. ## Disponíveis hoje | Documento | Modelo | Autorizador | |---|---|---| | **[NF-e](/docs/documentos/nfe/visao-geral)** | 55 | SEFAZ estadual | | **[NFC-e](/docs/documentos/nfce/visao-geral)** | 65 | SEFAZ estadual | | **[NFS-e](/docs/documentos/nfse/visao-geral)** | — | Ambiente Nacional ou provedor municipal | | **[CT-e](/docs/documentos/cte/visao-geral)** | 57 e 67 | SEFAZ estadual | | **[MDF-e](/docs/documentos/mdfe/visao-geral)** | 58 | SEFAZ estadual | Novos modelos entram na navegação quando o suporte estiver disponível para clientes — não antes. ## O que é igual nos três - emitente cadastrado e configurado por tipo de documento; - certificado A1 válido; - emissão devolve `202` com `job_id`; - acompanhamento por consulta ou webhook; - XML e PDF disponíveis após a autorização; - `referencia_externa` para idempotência e reconciliação. ## O que muda | | NF-e | NFC-e | NFS-e | |---|---|---|---| | Destinatário | obrigatório e identificado | consumidor, muitas vezes sem identificação | tomador do serviço | | Configuração extra | série, CRT | **CSC** obrigatório | município, inscrição municipal, provedor | | Impresso | DANFE A4 | cupom com QR Code | DANFSe | | Homologação | sempre | sempre | **depende do município** | > **ATENÇÃO — Não reaproveite payload entre modelos** > Parte dos campos é parecida, e é exatamente isso que induz ao erro. NFC-e tem regras de pagamento, > consumidor e QR Code que a NF-e não tem; NFS-e tem uma estrutura completamente diferente. ============================================================================== # https://docs.conota.dev/docs/documentos/nfe/visao-geral ============================================================================== # NF-e A **Nota Fiscal Eletrônica (modelo 55)** documenta operações com mercadorias. Pelo Conota, sua aplicação integra o ciclo completo sem implementar os serviços da SEFAZ. ## Fluxo 1. cadastre e valide o emitente; 2. mantenha o certificado A1 válido; 3. configure série e ambiente (`PUT /v1/empresas/{cpf_cnpj}/nfe`); 4. monte os dados da operação e dos produtos; 5. envie a emissão (`POST /v1/nfe/emitir`); 6. acompanhe o processamento; 7. trate autorização ou rejeição; 8. armazene os arquivos e identificadores. ## Rotas | Operação | Rota | |---|---| | Emitir | `POST /v1/nfe/emitir` | | Consultar | `GET /v1/nfe/consultar/{job_id}` | | Baixar arquivo | `GET /v1/nfe/{job_id}/file/{tipo}` | | Cancelar | `POST /v1/nfe/cancelar` | | Conferir payload sem emitir | `POST /v1/nfe/verificar-campos` | | Emissão em dois passos | `POST /v1/nfe/preparar` → `POST /v1/nfe/confirmar` | ## Atenção à tributação > **IMPORTANTE — Campo tributário não é para satisfazer schema** > CFOP, CST/CSOSN, NCM e alíquotas representam **regras fiscais da operação**. Preenchê-los com um > valor qualquer que passe na validação produz uma nota autorizada e **errada** — e o erro só aparece > numa fiscalização. O Conota valida estrutura, assina e executa a comunicação fiscal. A determinação tributária — regime, produto, CFOP, destino, legislação aplicável — continua sendo da sua regra de negócio. ## Reforma tributária (IBS/CBS) O grupo IBS/CBS já é aceito no payload e transmitido no XML. Como em qualquer campo tributário, a **classificação** correta é responsabilidade da integração. ## Próximos passos - [Emitir NF-e](/docs/documentos/nfe/emitir) - [Consultar emissão](/docs/documentos/nfe/consultar) - [Arquivos: XML e DANFE](/docs/documentos/nfe/arquivos) - [Cancelamento](/docs/documentos/nfe/cancelamento) ============================================================================== # https://docs.conota.dev/docs/documentos/nfe/emitir ============================================================================== # Emitindo uma NF-e ```http POST /v1/nfe/emitir ``` A estrutura completa do payload está na [Referência da API](https://api.conota.dev/docs) — esta página trata do **fluxo e das decisões**, não do schema. ## Forma da chamada ```json { "cpf_cnpj": "11222333000181", "referencia_externa": "pedido_98231", "webhook_url": "https://seu-sistema.com.br/webhooks/conota", "nota": { "identificacao": { "nNF": 1234, "serie": 1, "natOp": "Venda de mercadoria" }, "destinatario": { "CNPJCPF": "11222333000181", "xNome": "Cliente Exemplo Ltda" }, "produtos": [ { "cProd": "SKU-1", "xProd": "Produto exemplo", "NCM": "84713012" } ], "total": { "vNF": 1500.00 } } } ``` Exemplo **simplificado**: os blocos de imposto, endereço e transporte foram omitidos. Use a Referência para o conjunto real de campos. Resposta: `202` com `job_id` — ver [Sua primeira emissão](/docs/comecando/primeira-emissao). ## Informações complementares (OBS) O texto livre da nota — o quadro *Informações complementares* do DANFE — vai em `nota.informacoes_adicionais.infCpl` (também aceito como `info_complementar` ou `informacoes_complementares`). O de interesse do Fisco vai em `infAdFisco`. ```json "informacoes_adicionais": { "infCpl": "ENDERECO DE ORIGEM: Galpao, Pedro Leopoldo - MG\nENDERECO DE DESTINO: Lages - SC" }, "danfe_config": { "quebrar_linha_obs": true } ``` O XML da NF-e **não aceita quebra de linha** nesse campo. Cada quebra (`\n`) que você enviar vira `; ` no XML autorizado — o texto inteiro chega à SEFAZ, numa linha só. Para o DANFE voltar a quebrar a linha nesses pontos, envie `danfe_config.quebrar_linha_obs: true`; sem ela, o quadro mostra o texto corrido, com os `;`. Limite: 5000 caracteres. > **NOTA** > `danfe_config` vai **dentro** de `nota`, ao lado de `informacoes_adicionais`. Com > `quebrar_linha_obs` ligado, todo `;` do texto vira quebra de linha no DANFE, inclusive os que você > escreveu como pontuação. ## Confira antes de emitir > **IMPORTANTE — Campo com nome errado é ignorado em silêncio** > O conversor repassa chave desconhecida como veio. `vlrProd` no lugar de `vProd` gera uma NF-e > **válida no schema**, com o produto a R$ 0,00 — sem um único aviso, e nem a validação do > autorizador pega, porque o campo ignorado não chega ao XML. Existe uma rota para isso, que **não consome cota**: ```http POST /v1/nfe/verificar-campos ``` Ela confere os nomes dos campos e, se você informar `cpf_cnpj`, roda também a validação contra o schema oficial. ## Checklist - [ ] Emitente cadastrado e ativo - [ ] Certificado A1 válido (`GET /v1/empresas/certificados`) - [ ] Ambiente correto - [ ] Série correta - [ ] Número conferido (`GET /v1/empresas/numeracao`) - [ ] CFOP revisado - [ ] NCM de todos os itens - [ ] CST/CSOSN coerente com o regime - [ ] IBS/CBS quando aplicável - [ ] Totais coerentes com a soma dos itens - [ ] `referencia_externa` única - [ ] Payload passou em `verificar-campos` ## Emissão em dois passos Para fluxos com **aprovação humana** — em especial os conduzidos por agentes de IA — existe a emissão assistida: ```http POST /v1/nfe/preparar -> token + resumo legível (não emite, não consome cota) POST /v1/nfe/confirmar -> emite ``` O `preparar` só devolve token se o payload passar na verificação, aplica um **teto de valor por conta** e prende a `referencia_externa` ao token. O `confirmar` é de **uso único**: repetir devolve o mesmo job em vez de emitir outra nota. Existe também `POST /v1/nfe/preparar-de`, que parte de uma nota **que já existe** — útil para corrigir uma rejeitada ou copiar uma anterior. Ver [Segurança no MCP](/docs/mcp/seguranca). > **INFO — O teto vale só na emissão assistida** > `POST /v1/nfe/emitir` não tem limite de valor: lá o dado vem do ERP do cliente. O teto existe onde > uma pessoa aprova um resumo — porque atenção humana falha, e o teto não depende dela. ============================================================================== # https://docs.conota.dev/docs/documentos/nfe/consultar ============================================================================== # Consultando uma emissão ## Pelo `job_id` ```bash curl -s https://api.conota.dev/v1/nfe/consultar/$JOB_ID \ -H "X-API-Key: $CONOTA_API_KEY" ``` A resposta traz os dois eixos de estado — o do processamento e o fiscal. Ver [Status das emissões](/docs/conceitos/status). ## Em lote Até **200 ids** por chamada, resolvidos em poucas queries: ```http POST /v1/jobs/consultar-lote ``` ```json { "job_ids": ["6f8dc295-...", "8881bac5-..."] } ``` Id inexistente ou de outra conta volta como `"status": "nao_encontrado"` — sem `404`, e sem vazar a existência de dados de terceiros. ## Quando o `job_id` se perdeu ```http GET /v1/jobs/localizar?ref=pedido_98231 ``` Ou por atributos de negócio — emitente, destinatário, valor exato, período: ```http GET /v1/jobs/localizar?cpf_cnpj=11222333000181&valor=1500.00&de=2026-09-01&ate=2026-09-03 ``` > **INFO — Zero resultado é informação** > Nenhum resultado é forte indício de que **a emissão nunca aconteceu**. É essa a pergunta que você > precisa responder antes de reenviar depois de um timeout. ## Pela chave de acesso ```http GET /v1/notas/{chave} ``` ## Investigando uma rejeição ```http GET /v1/jobs/{job_id}/itens ``` Devolve os itens com os grupos tributários (ICMS, PIS/COFINS, IBS/CBS) e **marca qual item provocou a rejeição** — em vez de deixar você conferir item por item. ============================================================================== # https://docs.conota.dev/docs/documentos/nfe/arquivos ============================================================================== # Arquivos: XML e DANFE Depois da autorização, os arquivos ficam disponíveis por `job_id`. ```http GET /v1/nfe/{job_id}/file/{tipo} ``` | `tipo` | Conteúdo | |---|---| | `xml` | XML autorizado (com o protocolo) | | `pdf` | DANFE em A4 | | `xml_cancelamento` | XML do evento de cancelamento, quando houver | | `log` | log técnico do processamento | Existem também rotas genéricas por job, válidas para qualquer tipo de documento: ```http GET /v1/jobs/{job_id}/arquivos # o que existe para este job GET /v1/jobs/{job_id}/file/{tipo} # baixa o arquivo GET /v1/jobs/{job_id}/download/{tipo} # devolve a URL assinada, sem baixar ``` > **DICA — Não sabe o que o job produziu? Pergunte** > `GET /v1/jobs/{job_id}/arquivos` lista o que existe, com tamanho e URL pronta. Um job de > cancelamento, por exemplo, tem `xml_cancelamento` e `log`, mas **não** tem `xml` — pedir o `xml` > dele devolve `404`. ## Guarde o XML > **IMPORTANTE — O XML é o documento fiscal — o PDF é só a representação** > A obrigação de guarda recai sobre o **XML autorizado**. O DANFE pode ser regerado a partir dele; o > contrário não é verdade. A retenção dos arquivos no Conota depende do plano. Sua operação deve armazenar os XMLs no próprio ambiente — não trate a API como arquivo definitivo. ## Pacotes mensais Para fechamento contábil, o Conota gera pacotes ZIP com os XMLs do mês anterior: ```http GET /v1/arquivos/zips # o que está disponível GET /v1/arquivos/zip-mensal?tipo=nfe&competencia=2026-08 # baixa ``` Os pacotes são gerados no dia 1º de cada mês e o download vem por URL assinada, com validade curta. ============================================================================== # https://docs.conota.dev/docs/documentos/nfe/cancelamento ============================================================================== # Cancelamento ```http POST /v1/nfe/cancelar ``` ```json { "cpf_cnpj": "11222333000181", "job_id": "6f8dc295-...", "justificativa": "Erro de digitacao no valor do item" } ``` Informe `job_id` **ou** `chave`. A justificativa tem **mínimo de 15 caracteres** — exigência do autorizador, não nossa. Assim como a emissão, o cancelamento é assíncrono: devolve `202` com um novo `job_id`. ## Só se cancela o que foi autorizado | Situação da nota | Cancelamento | |---|---| | `autorizada` | possível, dentro do prazo | | `rejeitada` | **não existe o que cancelar** — a nota nunca chegou a valer | | `denegada` | não cancelável | | já `cancelada` | nada a fazer | > **ATENÇÃO — O prazo é da SEFAZ, não do Conota** > O cancelamento tem prazo legal contado a partir da autorização (24 horas para NF-e na maioria das > UFs). Passado o prazo, o autorizador recusa — e a saída deixa de ser técnica: vira nota de devolução > ou outro procedimento fiscal, conforme o caso. ## Nota rejeitada e numeração Uma nota rejeitada **não consome o número**. Você pode corrigir e emitir de novo com o mesmo número — mas use uma **`referencia_externa` nova**, senão a idempotência devolve o job antigo. Se um número ficou realmente sem uso e não será aproveitado, o procedimento é a **inutilização** da faixa, não o cancelamento. ============================================================================== # https://docs.conota.dev/docs/documentos/nfe/referencia-de-campos ============================================================================== # Referência de campos da NF-e Todos os campos que o Conota aceita dentro do objeto `nota`, para **NF-e (modelo 55)** e **NFC-e (modelo 65)**. > **INFO — Esta página é gerada, não escrita** > Ela sai de duas fontes, direto do que roda em produção: > > - **o conversor** — quais nomes você pode enviar e em que campo do layout cada um vira; > - **os XSD oficiais** — tipo, tamanho, valores permitidos e a descrição de cada campo. > > Por isso ela não diverge do sistema: se um campo muda no código, muda aqui. E por isso os textos da > coluna *"O que é"* são os oficiais, não uma reescrita nossa. > > São **175 campos** em **21 grupos**, 90 deles com descrição > oficial. ## Como ler O corpo da emissão tem esta forma: ```json { "cpf_cnpj": "11222333000181", "nota": { "identificacao": { "...": "..." }, "emitente": { "...": "..." }, "destinatario": { "...": "..." }, "produtos": [ { "...": "..." } ], "total": { "...": "..." }, "pagamentos": [ { "...": "..." } ] } } ``` Cada seção abaixo é um desses blocos. A coluna **Vira** é o nome do campo no layout oficial, útil quando o fisco devolve uma rejeição citando o nome dele. > **DICA — Um campo pode aceitar mais de um nome** > 18 campos aceitam nomes alternativos. Quando existem, aparecem como *"também:"* na > primeira coluna — qualquer um funciona. > **ATENÇÃO — Campo com nome errado não dá erro** > O conversor repassa chave desconhecida como veio, e o emissor a ignora: um `vlrProd` no lugar de > `vProd` gera uma nota **válida** com o produto valendo R$ 0,00. > > Antes da primeira emissão, passe o seu payload em > [`POST /v1/nfe/verificar-campos`](/docs/documentos/nfe/emitir) — ele aponta o campo desconhecido e > sugere o certo, sem emitir e sem consumir cota. ## `nota.identificacao` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `natureza_operacao`
_também:_ `nat_op` | `natOp` | `TString` | 60 | | Descrição da Natureza da Operação | | `modelo` | `mod` | `string` | | `55` `65` | | | `serie` | `serie` | `string` | | | | | `numero` | `nNF` | `string` | | | | | `data_emissao` | `dhEmi` | `string` | | | Data e Hora de emissão do Documento Fiscal (AAAA-MM-DDThh:mm:ssTZD) ex.: 2012-09-01T13:00:00-03:00 | | `data_saida` | `dhSaiEnt` | `string` | | | Data e Hora da saída ou de entrada da mercadoria / produto (AAAA-MM-DDTHH:mm:ssTZD) | | `tipo_nota` | `tpNF` | `string` | | `0` `1` | Tipo do Documento Fiscal (0 - entrada; 1 - saída) | | `destino_operacao` | `idDest` | `string` | | `1` `2` `3` | Identificador de Local de destino da operação (1-Interna;2-Interestadual;3-Exterior) | | `tipo_ambiente` | `tpAmb` | `string` | | `1` `2` | Identificação do Ambiente: 1 - Produção 2 - Homologação | | `tipo_impressao` | `tpImp` | `string` | | `0` `1` `2` `3` `4` `5` | Formato de impressão do DANFE (0-sem DANFE;1-DANFe Retrato; 2-DANFe Paisagem;3-DANFe Simplificado; 4-DANFe NFC-e;5-DANFe NFC-e em mensagem eletrônica) | | `tipo_emissao` | `tpEmis` | `string` | | `1` `2` `3` `4` `5` `6` `7` `9` | Forma de emissão da NF-e 1 - Normal; 2 - Contingência FS 3 - Regime Especial NFF (NT 2021.002) 4 - Contingência DPEC 5 - Contingência FSDA 6 - Contingência SVC - AN 7 - Contingência SVC - RS 9 - Contingência off-line NFC-e | | `finalidade` | `finNFe` | `string` | | `1` `2` `3` `4` `5` `6` | Finalidade da emissão da NF-e: 1 - NFe normal 2 - NFe complementar 3 - NFe de ajuste 4 - Devolução/Retorno 5 - Nota de crédito 6 - Nota de débito | | `consumidor_final` | `indFinal` | `string` | | `0` `1` | Indica operação com consumidor final (0-Não;1-Consumidor Final) | | `presenca` | `indPres` | `string` | | `0` `1` `2` `3` `4` `5` `9` | Indicador de presença do comprador no estabelecimento comercial no momento da oepração (0-Não se aplica (ex.: Nota Fiscal complementar ou de ajuste;1-Operação presencial;2-Não presencial, internet;3-Não presencial, teleatendimento;4-NFC-e entrega em domicílio;5-Operação presencial, fora do estabelecimento;9-Não presencial, outros) | | `processo_emissao` | `procEmi` | `string` | | `0` `1` `2` `3` | Processo de emissão utilizado com a seguinte codificação: 0 - emissão de NF-e com aplicativo do contribuinte; 1 - emissão de NF-e avulsa pelo Fisco; 2 - emissão de NF-e avulsa, pelo contribuinte com seu certificado digital, através do site do Fisco; 3- emissão de NF-e pelo contribuinte com aplicativo fornecido pelo Fisco. | | `municipio_fg` | `cMunFG` | `string` | | | | ## `nota.emitente` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão Social ou Nome do emitente | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome fantasia | | `inscricao_estadual`
_também:_ `ie` | `IE` | `string` | 14 | | IE do emitente da NF de Produtor | | `regime_tributario`
_também:_ `crt` | `CRT` | `string` | | `1` `2` `3` `4` | Código de Regime Tributário. Este campo será obrigatoriamente preenchido com: 1 – Simples Nacional; 2 – Simples Nacional – excesso de sublimite de receita bruta; 3 – Regime Normal. 4 - Simples Nacional - Microempreendedor individual - MEI | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `codigo_uf` | `cUF` | `string` | | `11` `12` `13` `14` `15` `16` `17` `21` `22` `23` `24` `25` … | Código da UF do emitente do Documento Fiscal. Utilizar a Tabela do IBGE. | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `cep` | `CEP` | `string` | | | CEP | | `codigo_pais` | `cPais` | `string` | | `1058` | | | `pais` | `xPais` | `TString` | 60 | `Brasil` `BRASIL` | Nome do país | | `telefone` | `Fone` | | | | _campo do emissor, sem descrição no layout_ | | `cnae` | `CNAE` | `string` | | | CNAE Fiscal | | `im` | `IM` | `TString` | 15 | | | | `iest` | `IEST` | `string` | 14 | | Inscricao Estadual do Substituto Tributário | ## `nota.destinatario` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão Social ou nome do destinatário | | `indicador_ie`
_também:_ `ind_ie_dest` | `indIEDest` | `string` | | `1` `2` `9` | Indicador da IE do destinatário: 1 – Contribuinte ICMSpagamento à vista; 2 – Contribuinte isento de inscrição; 9 – Não Contribuinte | | `inscricao_estadual`
_também:_ `ie` | `IE` | `string` | 14 | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `cep` | `CEP` | `string` | | | CEP | | `codigo_pais` | `cPais` | `string` | | `1058` | | | `pais` | `xPais` | `TString` | 60 | `Brasil` `BRASIL` | Nome do país | | `telefone` | `Fone` | | | | _campo do emissor, sem descrição no layout_ | | `id_estrangeiro` | `idEstrangeiro` | `string` | | | Identificador do destinatário, em caso de comprador estrangeiro | ## `nota.produtos[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `codigo`
_também:_ `codigo_produto` | `cProd` | `TString` | 60 | | Código do produto ou serviço. Preencher com CFOP caso se trate de itens não relacionados com mercadorias/produto e que o contribuinte não possua codificação própria Formato ”CFOP9999”. | | `ean` | `cEAN` | `string` | | | GTIN (Global Trade Item Number) do produto, antigo código EAN ou código de barras | | `ean_tributavel` | `cEANTrib` | `string` | | | GTIN (Global Trade Item Number) da unidade tributável, antigo código EAN ou código de barras | | `descricao` | `xProd` | `TString` | 120 | | Descrição do produto ou serviço | | `ncm` | `NCM` | `string` | | | Código NCM (8 posições), será permitida a informação do gênero (posição do capítulo do NCM) quando a operação não for de comércio exterior (importação/exportação) ou o produto não seja tributado pelo IPI. Em caso de item de serviço ou item que não tenham produto (Ex. transferência de crédito, crédito do ativo imobilizado, etc.), informar o código 00 (zeros) (v2.0) | | `cest` | `CEST` | `string` | | | Codigo especificador da Substuicao Tributaria - CEST, que identifica a mercadoria sujeita aos regimes de substituicao tributária e de antecipação do recolhimento do imposto | | `cfop` | `CFOP` | `string` | | | | | `unidade` | `uCom` | `TString` | 6 | | Unidade comercial | | `quantidade` | `qCom` | `string` | | | Quantidade Comercial do produto, alterado para aceitar de 0 a 4 casas decimais e 11 inteiros. | | `valor_unitario` | `vUnCom` | `string` | | | Valor unitário de comercialização - alterado para aceitar 0 a 10 casas decimais e 11 inteiros | | `valor_total` | `vProd` | `string` | | | | | `unidade_tributavel` | `uTrib` | `TString` | 6 | | | | `quantidade_tributavel` | `qTrib` | `string` | | | | | `valor_unitario_tributavel` | `vUnTrib` | `string` | | | Valor unitário de tributação - alterado para aceitar 0 a 10 casas decimais e 11 inteiros | | `valor_frete` | `vFrete` | `string` | | | Valor Total do Frete | | `valor_seguro` | `vSeg` | `string` | | | Valor Total do Seguro | | `valor_desconto` | `vDesc` | `string` | | | | | `valor_outros` | `vOutro` | `string` | | | | | `indicador_total` | `indTot` | `string` | | `0` `1` | Este campo deverá ser preenchido com: 0 – o valor do item (vProd) não compõe o valor total da NF-e (vProd) 1 – o valor do item (vProd) compõe o valor total da NF-e (vProd) | | `info_adicional` | `infAdProd` | `TString` | 500 | | Informações adicionais do produto (norma referenciada, informações complementares, etc) | | `numero_pedido` | `xPed` | `TString` | 15 | | | | `item_pedido` | `nItemPed` | `string` | | | Número do Item do Pedido de Compra - Identificação do número do item do pedido de Compra | ## `nota.total` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `valor_bc_icms` | `vBC` | `string` | | | | | `valor_icms` | `vICMS` | `string` | | | | | `valor_bc_icms_st` | `vBCST` | `string` | | | | | `valor_icms_st` | `vST` | `string` | | | Valor Total do ICMS ST | | `valor_produtos` | `vProd` | `string` | | | | | `valor_frete` | `vFrete` | `string` | | | Valor Total do Frete | | `valor_seguro` | `vSeg` | `string` | | | Valor Total do Seguro | | `valor_desconto` | `vDesc` | `string` | | | | | `valor_ii` | `vII` | `string` | | | | | `valor_ipi` | `vIPI` | `string` | | | | | `valor_pis` | `vPIS` | `string` | | | | | `valor_cofins` | `vCOFINS` | `string` | | | | | `valor_outros` | `vOutro` | `string` | | | | | `valor_nota` | `vNF` | `string` | | | Valor Total da NF-e | | `valor_tributos` | `vTotTrib` | `string` | | | Valor estimado total de impostos federais, estaduais e municipais | ## `nota.transportador` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `modalidade_frete`
_também:_ `mod_frete` | `modFrete` | `string` | | `0` `1` `2` `3` `4` `9` | Modalidade do frete 0- Contratação do Frete por conta do Remetente (CIF); 1- Contratação do Frete por conta do destinatário/remetente (FOB); 2- Contratação do Frete por conta de terceiros; 3- Transporte próprio por conta do remetente; 4- Transporte próprio por conta do destinatário; 9- Sem Ocorrência de transporte. | | `cnpj`
_também:_ `cnpj_cpf` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão Social ou nome do transportador | | `inscricao_estadual`
_também:_ `ie` | `IE` | `string` | 14 | | | | `endereco` | `xEnder` | `TString` | 60 | | Endereço completo | | `municipio` | `xMun` | `TString` | 60 | | | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `placa` | `Placa` | | | | _campo do emissor, sem descrição no layout_ | | `uf_placa` | `UFPlaca` | | | | _campo do emissor, sem descrição no layout_ | | `rntc` | `RNTC` | `TString` | 20 | | Registro Nacional de Transportador de Carga (ANTT) | ## `nota.volumes[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `quantidade` | `qVol` | `string` | | | Quantidade de volumes transportados | | `especie` | `esp` | `TString` | 60 | | Espécie dos volumes transportados | | `marca` | `Marca` | | | | _campo do emissor, sem descrição no layout_ | | `numeracao` | `nVol` | `TString` | 60 | | Numeração dos volumes transportados | | `peso_liquido` | `pesoL` | `TString` | 9 | | | | `peso_bruto` | `pesoB` | `TString` | 9 | | | ## `nota.fatura` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `numero` | `nFat` | `TString` | 60 | | Número da fatura | | `valor_original` | `vOrig` | `string` | | | Valor original da fatura | | `valor_desconto` | `vDesc` | `string` | | | | | `valor_liquido` | `vLiq` | `string` | | | Valor líquido da fatura | ## `nota.duplicatas[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `numero` | `nDup` | `TString` | 60 | | Número da duplicata | | `vencimento` | `dVenc` | `string` | | | Data de vencimento da duplicata (AAAA-MM-DD) | | `valor` | `vDup` | `string` | | | Valor da duplicata | ## `nota.pagamentos[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `tipo`
_também:_ `tipo_pagamento` | `tPag` | `string` | | | Forma de Pagamento: | | `valor` | `vPag` | `string` | | | Valor do Pagamento. Esta tag poderá ser omitida quando a tag tPag=90 (Sem Pagamento), caso contrário deverá ser preenchida. | | `indicador` | `indPag` | `string` | | `0` `1` | Indicador da Forma de Pagamento:0-Pagamento à Vista;1-Pagamento à Prazo; | | `descricao` | `xPag` | `TString` | 60 | | Descrição do Meio de Pagamento | | `troco` | `vTroco` | `string` | | | Valor do Troco. | | `tipo_integracao` | `tpIntegra` | `string` | | `1` `2` | Tipo de Integração do processo de pagamento com o sistema de automação da empresa: 1 - Pagamento integrado com o sistema de automação da empresa (Ex.: equipamento TEF, Comércio Eletrônico, POS Integrado); 2 - Pagamento não integrado com o sistema de automação da empresa (Ex.: equipamento POS Simples). | | `cnpj_credenciadora` | `CNPJ` | `string` | 14 | | | | `bandeira` | `tBand` | `string` | | | Bandeira da operadora de cartão | | `autorizacao` | `cAut` | `TString` | 128 | | Número de autorização da operação com cartões, PIX, boletos e outros pagamentos eletrônicos | ## `nota.informacoes_adicionais` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `info_fisco`
_também:_ `informacoes_fisco` | `infAdFisco` | `TString` | 2000 | | Informações adicionais de interesse do Fisco (v2.0) | | `info_complementar`
_também:_ `informacoes_complementares` | `infCpl` | `TString` | 5000 | | Informações complementares de interesse do Contribuinte | ## `nota.responsavel_tecnico` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj` | `CNPJ` | `string` | 14 | | | | `contato` | `xContato` | `TString` | 60 | | Informar o nome da pessoa a ser contatada na empresa desenvolvedora do sistema utilizado na emissão do documento fiscal eletrônico. | | `email` | `email` | `TString` | 60 | | | | `telefone` | `fone` | `string` | | | | ## `nota.icms` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `origem` | `orig` | `string` | | `0` `1` `2` `3` `4` `5` `6` `7` `8` | | | `cst` | `CST` | `string` | | `00` | | | `csosn` | `CSOSN` | `string` | | `101` | | | `modalidade_bc` | `modBC` | `string` | | `0` `1` `2` `3` | Modalidade de determinação da BC do ICMS: 0 - Margem Valor Agregado (%); 1 - Pauta (valor); 2 - Preço Tabelado Máximo (valor); 3 - Valor da Operação. | | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pICMS` | `string` | | | | | `valor` | `vICMS` | `string` | | | | | `reducao_bc` | `pRedBC` | `string` | | | Percentual de redução da BC | | `modalidade_bc_st` | `modBCST` | `string` | | `0` `1` `2` `3` `4` `5` `6` | | | `mva_st` | `pMVAST` | `string` | | | | | `reducao_bc_st` | `pRedBCST` | `string` | | | | | `valor_bc_st` | `vBCST` | `string` | | | | | `aliquota_st` | `pICMSST` | `string` | | | | | `valor_st` | `vICMSST` | `string` | | | | | `valor_desonerado` | `vICMSDeson` | `string` | | | | | `motivo_desoneracao` | `motDesICMS` | `string` | | `3` `9` `12` | | | `credito_sn_aliquota` | `pCredSN` | `string` | | | Alíquota aplicável de cálculo do crédito (Simples Nacional). (v2.0) | | `credito_sn_valor` | `vCredICMSSN` | `string` | | | Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) (v2.0) | ## `nota.ipi` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cst` | `CST` | `string` | | `00` | | | `enquadramento` | `cEnq` | `TString` | 3 | | Código de Enquadramento Legal do IPI (tabela a ser criada pela RFB) | | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pIPI` | `string` | | | Alíquota do IPI | | `valor` | `vIPI` | `string` | | | | ## `nota.pis` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cst` | `CST` | `string` | | `00` | | | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pPIS` | `string` | | | | | `valor` | `vPIS` | `string` | | | | ## `nota.cofins` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cst` | `CST` | `string` | | `00` | | | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pCOFINS` | `string` | | | | | `valor` | `vCOFINS` | `string` | | | | ## `nota.is_` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cst` | `CSTIS` | `string` | | | Código Situação Tributária do Imposto Seletivo | | `classificacao` | `cClassTribIS` | `string` | | | | | `valor_bc` | `vBCIS` | `string` | | | Valor do BC | | `aliquota` | `pIS` | `string` | | | Alíquota do Imposto Seletivo (percentual) | | `valor` | `vIS` | `string` | | | | ## `nota.ibscbs` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cst` | `CST` | `string` | | `00` | | | `classificacao` | `cClassTrib` | `string` | | | | ## `nota.ibs_uf` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pIBSUF` | `string` | | | Aliquota do IBS de competência das UF (em percentual) | | `valor` | `vIBSUF` | `string` | | | | ## `nota.ibs_mun` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pIBSMun` | `string` | | | Aliquota do IBS Municipal (em percentual) | | `valor` | `vIBSMun` | `string` | | | | ## `nota.cbs` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `valor_bc` | `vBC` | `string` | | | | | `aliquota` | `pCBS` | `string` | | | Aliquota da CBS (em percentual) | | `valor` | `vCBS` | `string` | | | | ## Grupos que passam direto Em 7 grupos o campo vai para o layout com o mesmo nome, sem tradução: `is_total` · `ibscbs_total` · `issqn` · `ibs` · `cbs` · `uf` · `mun` São os grupos da Reforma Tributária e do ISSQN. Use os nomes do layout oficial. ## O que esta página não cobre Ela lista **quais campos existem e o que cada um aceita**. Ela não diz **quando** cada grupo é exigido — isso depende de UF, município, regime tributário e da operação, e está nos guias de emissão. Um payload que passa por esta referência ainda pode ser rejeitado por regra fiscal. ============================================================================== # https://docs.conota.dev/docs/documentos/nfce/visao-geral ============================================================================== # NFC-e A **Nota Fiscal de Consumidor Eletrônica (modelo 65)** atende vendas ao consumidor final nos estados onde o modelo é utilizado. A integração compartilha conceitos com a NF-e, mas as diferenças são importantes o bastante para merecerem atenção própria. ## Antes de emitir: o CSC > **IMPORTANTE — Sem CSC configurado, a NFC-e não sai** > O **Código de Segurança do Contribuinte** é fornecido pela SEFAZ da UF e é o que permite gerar o QR > Code do cupom. Ele é configurado por empresa: > > ```http > PUT /v1/empresas/{cpf_cnpj}/nfce > ``` ## O que o Conota preenche por você Ao emitir por `POST /v1/nfce/emitir`, são aplicados automaticamente: | Campo | Valor | Por quê | |---|---|---| | `mod` | 65 | é o modelo da NFC-e | | `tpImp` | 4 | DANFE NFC-e | | `idDest` | 1 | operação interna (NFC-e é sempre dentro do estado) | | `indPres` | 1 | operação presencial | Isso reduz a chance de erro nos campos que **não têm outra escolha válida**. ## O que muda em relação à NF-e - **Destinatário** costuma ser opcional; abaixo de um limite de valor, o consumidor pode não ser identificado; - **formas de pagamento** são obrigatórias e detalhadas; - **QR Code e URL de consulta** compõem o cupom; - **regras estaduais** variam mais do que na NF-e; - é sempre **operação interna** — venda interestadual ao consumidor não é NFC-e. > **ATENÇÃO — Não reaproveite um payload de NF-e** > Parte dos campos é parecida, e é justamente isso que engana. Monte o payload de NFC-e a partir da > Referência da API e das regras da UF do emitente. ## Rotas | Operação | Rota | |---|---| | Emitir | `POST /v1/nfce/emitir` | | Consultar | `GET /v1/nfce/consultar/{job_id}` | | Baixar arquivo | `GET /v1/nfce/{job_id}/file/{tipo}` | | Cancelar | `POST /v1/nfce/cancelar` | ============================================================================== # https://docs.conota.dev/docs/documentos/nfce/emitir ============================================================================== # Emitindo uma NFC-e ```http POST /v1/nfce/emitir ``` O fluxo é o mesmo da NF-e — `202` com `job_id`, acompanhamento por consulta ou webhook, arquivos depois da autorização. As diferenças estão nos **pré-requisitos** e no **conteúdo**. ## Pré-requisitos - [ ] CSC configurado (`PUT /v1/empresas/{cpf_cnpj}/nfce`) - [ ] Certificado A1 válido - [ ] Série de NFC-e definida - [ ] Ambiente correto - [ ] Formas de pagamento no payload - [ ] Itens com NCM e CFOP de operação interna ## O cupom O arquivo `pdf` da NFC-e é o **cupom** com QR Code, não um DANFE A4: ```http GET /v1/nfce/{job_id}/file/pdf ``` O QR Code é gerado a partir do CSC. É por isso que um CSC errado não falha no cadastro — falha na emissão, ou pior, gera um cupom cujo QR Code não valida na consulta pública. ## Contingência Indisponibilidade da SEFAZ é mais sensível no varejo, onde a venda não pode parar. As regras de contingência variam por UF; consulte a legislação estadual do emitente antes de desenhar esse fluxo. ## Cancelamento ```http POST /v1/nfce/cancelar ``` Mesmas regras da [NF-e](/docs/documentos/nfe/cancelamento), com prazos que podem ser **mais curtos** conforme a UF. ============================================================================== # https://docs.conota.dev/docs/documentos/nfce/consultar ============================================================================== # Consultando uma emissão de NFC-e ## Pelo `job_id` ```bash curl -s https://api.conota.dev/v1/nfce/consultar/$JOB_ID \ -H "X-API-Key: $CONOTA_API_KEY" ``` A resposta traz os dois eixos de estado — o do processamento e o fiscal. Ver [Status das emissões](/docs/conceitos/status). > **DICA — Esta consulta não consome cota** > Ela lê o que já guardamos, não vai à SEFAZ. Pode consultar à vontade enquanto espera o resultado. ## Em lote A rota de lote é a mesma para todos os documentos — até **200 ids** por chamada: ```http POST /v1/jobs/consultar-lote ``` ```json { "job_ids": ["6f8dc295-...", "8881bac5-..."] } ``` Id inexistente ou de outra conta volta como `"status": "nao_encontrado"` — sem `404`, e sem vazar a existência de dados de terceiros. ## Quando o `job_id` se perdeu ```http GET /v1/jobs/localizar?ref=pedido_98231 ``` Também aceita período, CNPJ do emitente, documento do destinatário e valor. É o caminho de reconciliação quando a sua aplicação perdeu o `job_id` — ver [Referência externa](/docs/conceitos/referencia-externa). ## O caixa não pode esperar a consulta > **ATENÇÃO — NFC-e é venda no balcão, e isso muda o desenho** > Na NF-e o cliente costuma tolerar alguns segundos até a autorização. No PDV, não: alguém está na > fila. > > A emissão devolve `202` na hora, e a autorização vem depois. Duas saídas, e a escolha é sua: > > - **webhook** — o Conota chama o seu sistema quando termina, e o cupom sai sozinho. É o caminho que > não faz o caixa esperar por *polling*. Ver [Webhooks](/docs/conceitos/webhooks); > - **contingência offline** — quando a SEFAZ está indisponível, a legislação prevê emissão em > contingência. Isso é decisão da sua operação, não da API. > > Se você fizer *polling*, faça com intervalo — consultar em laço apertado não acelera a SEFAZ. ## Consultar não é o mesmo que ter o cupom Depois de `autorizada`, o cupom e o XML saem por [Arquivos](/docs/documentos/nfce/arquivos). A consulta diz **se** a nota valeu; os arquivos são **o** documento. ============================================================================== # https://docs.conota.dev/docs/documentos/nfce/arquivos ============================================================================== # Arquivos: XML e DANFE NFC-e Depois da autorização, os arquivos ficam disponíveis por `job_id`. ```http GET /v1/nfce/{job_id}/file/{tipo} ``` | `tipo` | Conteúdo | |---|---| | `xml` | XML autorizado, com o protocolo | | `pdf` | **DANFE NFC-e em cupom de 80 mm** | | `xml_cancelamento` | XML do evento de cancelamento, quando houver | | `log` | log técnico do processamento | As rotas genéricas por job também servem, e são as mesmas para qualquer documento: ```http GET /v1/jobs/{job_id}/arquivos # o que existe para este job GET /v1/jobs/{job_id}/file/{tipo} # baixa o arquivo GET /v1/jobs/{job_id}/download/{tipo} # devolve a URL assinada, sem baixar ``` > **DICA — Não sabe o que o job produziu? Pergunte** > `GET /v1/jobs/{job_id}/arquivos` lista o que existe, com tamanho e URL pronta. Um job de > cancelamento, por exemplo, tem `xml_cancelamento` e `log`, mas **não** tem `xml` — pedir o `xml` > dele devolve `404`. ## O DANFE NFC-e não é o DANFE da NF-e > **ATENÇÃO — Cupom de 80 mm, não A4** > O `pdf` da NFC-e é o **DANFE NFC-e**: layout de cupom para impressora térmica de 80 mm, com o > **QR Code** que o consumidor usa para consultar a nota no portal da SEFAZ. > > Se a sua aplicação imprime o PDF da NF-e hoje, ela **não** serve para a NFC-e sem ajuste: são > tamanhos de papel diferentes, e mandar um cupom para a bandeja A4 desperdiça a folha inteira. O QR Code depende do **CSC** configurado para a empresa (`PUT /v1/empresas/{cpf_cnpj}/nfce`). Sem CSC não há QR Code válido, e a SEFAZ rejeita a nota antes de chegar ao PDF. ## Guarde o XML > **IMPORTANTE — O XML é o documento fiscal — o cupom é só a representação** > A obrigação de guarda recai sobre o **XML autorizado**. O cupom pode ser regerado a partir dele; o > contrário não é verdade. > > Vale igual para a NFC-e, mesmo ela sendo entregue ao consumidor em papel térmico — que desbota. A retenção dos arquivos no Conota depende do plano. Sua operação deve armazenar os XMLs no próprio ambiente — não trate a API como arquivo definitivo. ## Pacotes mensais Para fechamento contábil, o Conota gera pacotes ZIP com os XMLs do mês anterior: ```http GET /v1/arquivos/zips # o que está disponível GET /v1/arquivos/zip-mensal?tipo=nfce&competencia=2026-08 # baixa ``` Repare no `tipo=nfce`: cada tipo de documento tem o seu pacote. Os ZIPs são gerados no dia 1º de cada mês e o download vem por URL assinada, com validade curta. ============================================================================== # https://docs.conota.dev/docs/documentos/nfce/cancelamento ============================================================================== # Cancelando uma NFC-e O cancelamento usa o **mesmo evento** da NF-e, identificado pela chave de acesso. ```http POST /v1/nfce/cancelar ``` ```json { "cpf_cnpj": "11222333000181", "job_id": "6f8dc295-...", "justificativa": "Cancelamento solicitado pelo cliente no caixa" } ``` Informe `job_id` **ou** `chave`. A justificativa tem **mínimo de 15 caracteres** — exigência do autorizador, não nossa. Assim como a emissão, o cancelamento é assíncrono: devolve `202` com um novo `job_id`, e **consome cota de NFC-e**. ## Só se cancela o que foi autorizado | Situação da nota | Cancelamento | |---|---| | `autorizada` | possível, dentro do prazo | | `rejeitada` | **não existe o que cancelar** — a nota nunca chegou a valer | | `denegada` | não cancelável | | já `cancelada` | nada a fazer | ## O prazo é o problema prático da NFC-e > **IMPORTANTE — Costuma ser bem mais curto que o da NF-e** > A NF-e tem, na maioria das UFs, **24 horas** para cancelamento. Para a **NFC-e o prazo é definido > por cada UF e costuma ser muito menor** — em vários estados, minutos. > > Consulte a regra da sua UF. Não assuma o prazo da NF-e: no varejo, a diferença entre cancelar e não > poder mais cancelar acontece dentro do mesmo expediente. Passado o prazo, a saída deixa de ser técnica. Conforme o caso, vira **nota de devolução** ou outro procedimento fiscal — e isso é decisão do seu contador, não da API. ## O cupom já está com o cliente Diferente da NF-e, a NFC-e é entregue **no ato**. Quando você cancela, o consumidor pode já ter saído com o cupom impresso na mão, e o QR Code dele passa a mostrar a nota como cancelada ao ser consultado no portal da SEFAZ. Vale desenhar o fluxo do PDV pensando nisso: cancelar depois que o cliente saiu resolve o lado fiscal, mas não o lado do atendimento. ## Nota rejeitada e numeração Uma nota rejeitada **não consome o número**. Você pode corrigir e emitir de novo com o mesmo número — mas use uma **`referencia_externa` nova**, senão a idempotência devolve o job antigo. Se um número ficou realmente sem uso, o procedimento é a **inutilização** da faixa, não o cancelamento. ## Depois do cancelamento O XML do evento fica disponível como `xml_cancelamento` — ver [Arquivos](/docs/documentos/nfce/arquivos). O `xml` original continua lá: cancelar não apaga a nota, registra um evento sobre ela. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/visao-geral ============================================================================== # NFS-e A **Nota Fiscal de Serviço Eletrônica** tem um cenário diferente dos documentos estaduais: em vez de um autorizador por estado, historicamente existe **um por município**, cada um com o próprio layout, credenciais e comportamento — e agora, além deles, o padrão nacional. O papel do Conota é oferecer uma interface única, absorvendo as diferenças de comunicação. ## Antes de integrar Você precisa conhecer: - município do prestador; - inscrição municipal, quando exigida; - regime e enquadramentos aplicáveis; - serviço prestado e o código de tributação; - alíquota e retenções, quando aplicáveis; - credenciais exigidas pelo município ou provedor. > **ATENÇÃO — Homologação pode não existir** > Nem todo município oferece ambiente de teste, e os que oferecem nem sempre reproduzem o > comportamento da produção. Confirme antes de planejar a validação da integração. ## Dois caminhos | Caminho | Quando | Rota | |---|---|---| | **Padrão Nacional** | municípios no Sistema Nacional NFS-e | `POST /v1/nfse/emitir` | | **Padrão Nacional, motor próprio** | leiautes novos, como os da NT 009 e condomínios | `POST /v1/nfse-nacional/emitir` | | **Provedor municipal** | municípios em provedor próprio | `POST /v1/nfse/govdigital/emitir` | A estrutura do payload **muda** entre eles: o Padrão Nacional usa a DPS (`infDPS`), enquanto os provedores municipais seguem o modelo ABRASF. Ver [Provedores e municípios](/docs/documentos/nfse/provedores). O motor próprio também usa a DPS, mas permite escolher o leiaute e validar o payload antes de emitir. Ver [NFS-e Nacional — motor próprio](/docs/documentos/nfse/nfse-nacional). ## Rotas | Operação | Rota | |---|---| | Emitir (Padrão Nacional) | `POST /v1/nfse/emitir` | | Emitir (Padrão Nacional, motor próprio) | `POST /v1/nfse-nacional/emitir` | | Emitir NFS-e de condomínio (NT 009) | `POST /v1/nfse-nacional/condominios/emitir` | | Validar DPS sem emitir | `POST /v1/nfse-nacional/validar` | | Emitir (provedor municipal) | `POST /v1/nfse/govdigital/emitir` | | Consultar | `GET /v1/nfse/consultar/{job_id}` | | Baixar arquivo | `GET /v1/nfse/{job_id}/file/{tipo}` | | Cancelar | `POST /v1/nfse/cancelar` | | Consultar por RPS | `GET /v1/nfse/{cpf_cnpj}/consultar-rps` | | Consultar no ambiente nacional | `POST /v1/nfse/consultar-sefaz` | As rotas com `{cpf_cnpj}` no caminho são anteriores e seguem mantidas por compatibilidade. Integrações novas devem usar as rotas assíncronas com `cpf_cnpj` no corpo. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/emitir ============================================================================== # Emitindo uma NFS-e ## Padrão Nacional ```http POST /v1/nfse/emitir ``` O documento é a **DPS** (Declaração de Prestação de Serviços), no bloco `infDPS`. A partir dela o Ambiente Nacional gera a NFS-e. Para escolher o leiaute da DPS (como os da NT 009) ou validar o payload antes de emitir, use o motor próprio. Ver [NFS-e Nacional — motor próprio](/docs/documentos/nfse/nfse-nacional). ## Provedor municipal ```http POST /v1/nfse/govdigital/emitir ``` Segue o modelo ABRASF, com **RPS** (Recibo Provisório de Serviços) convertido em NFS-e pelo município. Os dois caminhos devolvem `202` com `job_id` e são acompanhados da mesma forma. ## Quando o retorno se perde > **ATENÇÃO — A NFS-e é onde mais aparece o "fantasma"** > Um timeout do município **não significa** que a nota não foi gerada. Ela pode existir na prefeitura > sem que a resposta tenha chegado até aqui — e reenviar cria uma segunda nota de serviço. Antes de reenviar, consulte pelo RPS: ```http GET /v1/nfse/{cpf_cnpj}/consultar-rps ``` Ou, no Padrão Nacional, pela chave: ```http POST /v1/nfse/consultar-sefaz ``` E, do lado do Conota, localize a operação: ```http GET /v1/jobs/localizar?ref=sua_referencia ``` ## Cancelamento ```http POST /v1/nfse/cancelar ``` Prazos e regras de cancelamento de NFS-e são **municipais** e variam bastante — alguns municípios exigem substituição em vez de cancelamento. Confirme a regra do município antes de prometer o comportamento ao usuário final. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/nfse-nacional ============================================================================== # Emitindo NFS-e pelo motor próprio do Padrão Nacional ```http POST /v1/nfse-nacional/emitir ``` As rotas `/v1/nfse-nacional` emitem no Padrão Nacional pelo **motor próprio** do Conota. A DPS é montada e conferida contra o XSD oficial **antes** de ir para a Sefin, e cada erro volta com o caminho exato do campo. Use este caminho quando precisar de um leiaute que `POST /v1/nfse/emitir` ainda não aceita, como os da NT 009. A rota `POST /v1/nfse/emitir` continua funcionando como antes. A estrutura completa do payload está na [Referência da API](https://api.conota.dev/docs) — esta página trata do **fluxo e das decisões**, não do schema. ## Rotas | Operação | Rota | Consome cota | |---|---|---| | Emitir | `POST /v1/nfse-nacional/emitir` | sim | | Emitir NFS-e de condomínio (NT 009) | `POST /v1/nfse-nacional/condominios/emitir` | sim | | Validar sem emitir | `POST /v1/nfse-nacional/validar` | não | As emissões devolvem `202` com `job_id`. Consulta, arquivos e cancelamento usam as rotas de sempre: [Consultar emissão](/docs/documentos/nfse/consultar), [Arquivos](/docs/documentos/nfse/arquivos) e [Cancelamento](/docs/documentos/nfse/cancelamento). ## Forma da chamada ```json { "cpf_cnpj": "11222333000181", "referencia_externa": "pedido_98231", "versao": "1.01", "nota": { "infDPS": { "toma": { "CPF": "11144477735", "xNome": "Cliente Exemplo" }, "serv": { "locPrest": { "cLocPrestacao": "3106200" }, "cServ": { "cTribNac": "010101", "xDescServ": "Desenvolvimento de sistemas", "cNBS": "115021000" } }, "valores": { "vServPrest": { "vServ": 1500.00 }, "trib": { "tribMun": { "tribISSQN": "1", "tpRetISSQN": "1", "pAliq": 2.00 }, "totTrib": { "indTotTrib": "0" } } }, "IBSCBS": { "finNFSe": "0", "cIndOp": "100301", "indDest": "0", "valores": { "trib": { "gIBSCBS": { "CST": "000", "cClassTrib": "000001" } } } } } } } ``` Você **não precisa** informar o que já está no cadastro da empresa. Quando omitidos, o Conota preenche: - prestador: CNPJ ou CPF, inscrição municipal e regime tributário (`regTrib`); - `cLocEmi`, `tpAmb`, `dhEmi` e `dCompet`; - `serie` e `nDPS`, a partir da numeração da empresa no ambiente da chave. Para **não** enviar a inscrição municipal, informe `"IM": null` em `prest`. ## Escolha do leiaute O campo `versao` define o leiaute da DPS: | `versao` | Leiaute | Quando usar | |---|---|---| | `1.01` | XSD oficial de 09/02/2026 | padrão, quando `versao` é omitido | | `1.01-20261020` | XSD oficial de 20/10/2026, com parte da NT 009 | homologação, até a Sefin adotar o novo XSD em produção | | `1.01-nt009` | leiaute completo da NT 009, com condomínios | NFS-e de condomínio; provisório até a publicação do XSD oficial | Um valor fora da lista é recusado na hora, com `400`. > **ATENÇÃO — O leiaute muda a posição dos campos** > O mesmo JSON **não** serve para todos os leiautes. Um campo enviado na posição de outro leiaute é > recusado com `campo não existe no leiaute`, e nada é enviado à Sefin. Valide o payload no leiaute > escolhido antes de emitir. ### O que muda no leiaute `1.01-20261020` - `finNFSe` sai de `IBSCBS` e vai para `infDPS`. Passa a ser **obrigatório**. - `CST` e `cClassTrib` sobem de `IBSCBS.valores.trib.gIBSCBS` para `IBSCBS.valores.trib`. O `gIBSCBS` fica opcional e guarda só `cCredPres`, `gTribRegular` e `gDif`. - `cIndOp` passa a ser opcional. - A dedução/redução (`gDedRed`) e o reembolso (`gReeRepRes`) dão lugar ao ajuste da base de cálculo (`gAjusteBC`). - Novos grupos: `IBSCBS.imovel.gLocacao` (locação, cessão e arrendamento), `IBSCBS.imovel.gUnidImob` (unidades imobiliárias) e `IBSCBS.bensMoveis`. O exemplo acima, no leiaute `1.01-20261020`, fica assim: ```json { "versao": "1.01-20261020", "nota": { "infDPS": { "finNFSe": "0", "IBSCBS": { "cIndOp": "100301", "indDest": "0", "valores": { "trib": { "CST": "000", "cClassTrib": "000001" } } } } } } ``` Os demais campos não mudam. ## Valide antes de emitir ```bash curl -X POST https://api.conota.dev/v1/nfse-nacional/validar \ -H "X-API-Key: $CONOTA_API_KEY" \ -H "Content-Type: application/json" \ -d @dps.json ``` A validação monta a DPS exatamente como a emissão montaria, **sem** assinar, enviar, consumir cota ou reservar número. - `200` com `"sucesso": true`: a DPS passou no XSD e nas regras. O XML gerado vem em `xml`. - `422`: a DPS tem problemas. Cada erro vem com o caminho do campo, em `erros` (montagem), `erros_xsd` (XSD oficial) ou `erros_regras` (regras de condomínio). Use o mesmo `versao` que você vai usar na emissão. > **DICA — A validação não substitui a Sefin** > O XSD confere a **forma** da DPS. Regras de negócio, como cadastro do município e códigos de > serviço, só a Sefin confere. Veja as rejeições mais comuns abaixo. ## Rejeições comuns da Sefin | Código | O que significa | O que fazer | |---|---|---| | `E0234` | o endereço do tomador é obrigatório para o `cIndOp` informado | informe `toma.end` | | `E0322` | com IBS/CBS, a DPS precisa do código NBS | informe `serv.cServ.cNBS` | | `E0120` | o município não tem dados do prestador no cadastro nacional, e a inscrição municipal não deve ir | envie `"IM": null` em `prest` | | `E0312` | o município de incidência não administra o `cTribNac` na competência | confirme o código de serviço com o município | Os códigos `cNBS`, `cIndOp` e `cClassTrib` de cada serviço estão na tabela de correlação oficial do Portal Nacional da NFS-e (Anexo VIII da NT 004). Rejeições da Sefin são **definitivas**: o Conota não tenta de novo. Corrija o payload e emita outra vez com outra `referencia_externa`. ## Número da DPS já usado O número da DPS (`nDPS`) é único por município, prestador e série. Se a Sefin informar que o número já existe, o Conota busca a NFS-e que ela tem para ele: - se for a **mesma** operação (por exemplo, um retorno que se perdeu), a emissão é dada como concluída com essa nota; - se for **outra** operação, a emissão termina com o erro `DPS_DIVERGENTE`, com a chave da nota existente e os campos que divergem. > **ATENÇÃO — DPS_DIVERGENTE pede ajuste de numeração** > Esse erro aparece quando o número já foi usado por outro sistema ou outra integração. Ajuste a > numeração da empresa antes de emitir de novo. Ver a numeração atual em > `GET /v1/empresas/numeracao`. ## Condomínios ```http POST /v1/nfse-nacional/condominios/emitir ``` Para o subitem 99.05 (`cTribNac` `990501`), no leiaute da NT 009. Além do XSD, o Conota confere as regras da NT antes do envio: - `vServ` igual à soma das cobranças; - descontos batendo com `vDescCondIncond`; - tipo de cobrança sem repetição; - grupo do imóvel presente. O leiaute da NT 009 ainda é **provisório**, montado a partir da planilha oficial até a publicação do XSD. Quando o XSD sair, o Conota passa a usá-lo e esta página é atualizada. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/provedores ============================================================================== # Municípios e provedores A NFS-e não tem um autorizador único. O Conota unifica a chamada, mas você precisa saber **para onde** a emissão vai. ## Padrão Nacional O Sistema Nacional da NFS-e centraliza a emissão para os municípios que aderiram. O documento é a **DPS**, e o layout é o mesmo em todos os municípios participantes — é a direção para onde o país está caminhando. ```http POST /v1/nfse/emitir ``` ## Provedor municipal Municípios que ainda operam sistema próprio seguem o modelo **ABRASF**, com variações entre implementações. Além de dados fiscais, muitos exigem **credenciais da prefeitura** (login, senha ou token), configuradas em: ```http PUT /v1/empresas/{cpf_cnpj}/nfse ``` ```http POST /v1/nfse/govdigital/emitir ``` ## O que confirmar antes de integrar um município novo - [ ] O município está no Padrão Nacional ou em provedor próprio? - [ ] Existe ambiente de homologação? - [ ] Quais credenciais a prefeitura exige, além do certificado? - [ ] A inscrição municipal é obrigatória? - [ ] Qual o código de tributação do serviço prestado? - [ ] Há retenções aplicáveis? - [ ] Qual a regra de cancelamento — cancela ou substitui? > **INFO — A diferença aparece no payload** > Não é só o endpoint que muda: a **estrutura do documento** é outra. Um payload de Padrão Nacional > não é aceito por um provedor ABRASF, e vice-versa. Consulte a > [Referência da API](https://api.conota.dev/docs) para o formato de cada um. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/consultar ============================================================================== # Consultando uma emissão de NFS-e Há **duas consultas diferentes**, e confundi-las custa cota. | O que você quer | Rota | Consome cota | |---|---|---| | saber como ficou a emissão que você pediu | `GET /v1/nfse/consultar/{job_id}` | **não** | | perguntar à prefeitura o que ela tem | `POST /v1/nfse/consultar-sefaz` | **sim** | | idem, por RPS, no GovDigital | `GET /v1/nfse/{cpf_cnpj}/consultar-rps` | **sim** | ## Pelo `job_id` — o caminho normal ```bash curl -s https://api.conota.dev/v1/nfse/consultar/$JOB_ID \ -H "X-API-Key: $CONOTA_API_KEY" ``` Lê o que já guardamos. É o que você usa para acompanhar uma emissão, e **não consome cota** — pode consultar à vontade enquanto espera. A resposta traz os dois eixos de estado — o do processamento e o fiscal. Ver [Status das emissões](/docs/conceitos/status). ## Perguntando à prefeitura ```http POST /v1/nfse/consultar-sefaz ``` ```json { "cpf_cnpj": "11222333000181", "chave_acesso": "..." } ``` > **ATENÇÃO — Esta consome cota de NFS-e** > Ela sai da nossa base e vai falar com o provedor — Padrão Nacional por API, municípios próprios pelo > ACBr. Por isso é cobrada como uma operação, e não como leitura. > > Use quando precisa da **verdade da prefeitura**: conferir se uma nota que sumiu do seu lado existe > lá, ou reconciliar depois de uma indisponibilidade. Para acompanhar emissão do dia a dia, use a > consulta por `job_id`. ## Em lote A rota de lote é a mesma para todos os documentos — até **200 ids**, e lê o que já guardamos: ```http POST /v1/jobs/consultar-lote ``` Id inexistente ou de outra conta volta como `"status": "nao_encontrado"` — sem `404`. ## Quando o `job_id` se perdeu ```http GET /v1/jobs/localizar?ref=os_4471 ``` Também aceita período, CNPJ do prestador, documento do tomador e valor — ver [Referência externa](/docs/conceitos/referencia-externa). ## A NFS-e demora mais, e falha diferente > **INFO — Prefeitura não é SEFAZ** > A autorização de NFS-e depende do sistema do município, e a variação é grande: alguns respondem em > segundos, outros levam minutos e alguns saem do ar sem aviso. > > Isso torna o **webhook** mais útil aqui que na NF-e — ver [Webhooks](/docs/conceitos/webhooks) — e > torna o `job_id` mais importante ainda: é ele que liga o que você pediu ao que a prefeitura > respondeu, mesmo dias depois. ## Consultar não é o mesmo que ter o documento Depois de autorizada, o XML e o DANFSe saem por [Arquivos](/docs/documentos/nfse/arquivos). ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/arquivos ============================================================================== # Arquivos: XML e DANFSe Depois que a prefeitura autoriza, os arquivos ficam disponíveis por `job_id`. ```http GET /v1/nfse/{job_id}/file/{tipo} ``` | `tipo` | Conteúdo | |---|---| | `xml` | XML da NFS-e autorizada, como o provedor devolveu | | `pdf` | **DANFSe** | | `xml_cancelamento` | XML do cancelamento, quando houver | | `log` | log técnico do processamento | As rotas genéricas por job também servem, e são as mesmas para qualquer documento: ```http GET /v1/jobs/{job_id}/arquivos # o que existe para este job GET /v1/jobs/{job_id}/file/{tipo} # baixa o arquivo GET /v1/jobs/{job_id}/download/{tipo} # devolve a URL assinada, sem baixar ``` > **DICA — Não sabe o que o job produziu? Pergunte** > `GET /v1/jobs/{job_id}/arquivos` lista o que existe, com tamanho e URL pronta. Um job de > cancelamento, por exemplo, tem `xml_cancelamento` e `log`, mas **não** tem `xml`. ## O XML da NFS-e não tem um layout único > **ATENÇÃO — Aqui a diferença entre provedores aparece** > Na NF-e o XML segue um layout nacional e único. Na NFS-e, **o que você recebe depende de quem > autorizou**: > > - no **Padrão Nacional**, o XML segue o layout da NFS-e nacional; > - em municípios com sistema próprio, o XML é o do provedor daquele município. > > Se a sua aplicação faz *parsing* do XML da NFS-e, ela precisa saber com qual provedor está lidando. > Ver [Provedores](/docs/documentos/nfse/provedores). O `pdf` é o **DANFSe**, gerado por nós a partir do XML autorizado. Ele é uma representação — como o DANFE para a NF-e — e não substitui o XML. ## Guarde o XML > **IMPORTANTE — O XML é o documento fiscal — o PDF é só a representação** > A obrigação de guarda recai sobre o **XML autorizado**. O DANFSe pode ser regerado a partir dele; o > contrário não é verdade. A retenção dos arquivos no Conota depende do plano. Sua operação deve armazenar os XMLs no próprio ambiente — não trate a API como arquivo definitivo. ## Pacotes mensais Para fechamento contábil, o Conota gera pacotes ZIP com os XMLs do mês anterior: ```http GET /v1/arquivos/zips # o que está disponível GET /v1/arquivos/zip-mensal?tipo=nfse&competencia=2026-08 # baixa ``` Repare no `tipo=nfse`: cada tipo de documento tem o seu pacote. Os ZIPs são gerados no dia 1º de cada mês e o download vem por URL assinada, com validade curta. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/cancelamento ============================================================================== # Cancelando uma NFS-e ```http POST /v1/nfse/cancelar ``` ```json { "cpf_cnpj": "11222333000181", "job_id": "6f8dc295-...", "justificativa": "Serviço não executado, conforme acordo com o tomador" } ``` Informe `job_id` **ou** `numero` da NFS-e. O cancelamento é assíncrono: devolve `202` com um novo `job_id`, e **consome cota de NFS-e**. ## Aqui não existe "a regra" — existe a regra do município > **IMPORTANTE — Esta é a diferença que mais surpreende quem vem da NF-e** > A NF-e tem regra nacional: evento de cancelamento, justificativa de 15 caracteres, prazo em torno de > 24 horas. **A NFS-e não.** Prazo, campos exigidos e até a possibilidade de cancelar são definidos > por **cada município**. > > Existem municípios que: > > - não permitem cancelamento pela API, só pelo portal da prefeitura; > - exigem um **código de motivo** de uma lista própria; > - exigem o **CPF de quem autorizou** o cancelamento; > - aceitam substituição em vez de cancelamento; > - têm prazo de dias, e outros de horas. > > Antes de desenhar o fluxo, confirme a regra do município do prestador. ## Campos condicionais Além de `job_id`/`numero` e `justificativa`, a rota aceita campos que **alguns provedores exigem**: | Campo | Quando | |---|---| | `codigo_cancelamento` | municípios que usam lista própria de motivos | | `cpf_autor` | provedores que registram quem pediu o cancelamento | | `provedor` | para forçar o provedor, quando a empresa tem mais de um configurado | Enviar um campo que o município não usa não atrapalha; **faltar** um que ele exige vira rejeição com a mensagem do próprio provedor. Ver [Provedores](/docs/documentos/nfse/provedores). ## Só se cancela o que foi autorizado | Situação | Cancelamento | |---|---| | autorizada | possível, conforme a regra do município | | rejeitada | **não existe o que cancelar** | | já cancelada | nada a fazer | Uma NFS-e rejeitada não consome numeração de NFS-e — mas o **RPS** já foi numerado. O contador de RPS é nosso e por ambiente; ver [Referência de campos](/docs/documentos/nfse/referencia-de-campos). ## Depois do cancelamento O XML do evento fica disponível como `xml_cancelamento` — ver [Arquivos](/docs/documentos/nfse/arquivos). O `xml` original continua lá: cancelar não apaga a nota. > **DICA — Se a prefeitura aceitou mas o Conota não registrou** > Acontece quando o provedor responde e a conexão cai no meio. Use > [`POST /v1/nfse/consultar-sefaz`](/docs/documentos/nfse/consultar) para perguntar a ela qual é o > estado real — é a consulta que vale como verdade. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/referencia-de-campos ============================================================================== # Referência de campos da NFS-e Campos do objeto `nota` na NFS-e do **Padrão Nacional**. O payload segue a estrutura oficial `infDPS` — o nome que você envia **é** o nome do layout, sem tradução. > **INFO — Esta página é gerada, não escrita** > Ela sai de duas fontes, direto do que roda em produção: > > - **o conversor** — quais nomes você pode enviar e em que campo do layout cada um vira; > - **os XSD oficiais** — tipo, tamanho, valores permitidos e a descrição de cada campo. > > Por isso ela não diverge do sistema: se um campo muda no código, muda aqui. E por isso os textos da > coluna *"O que é"* são os oficiais, não uma reescrita nossa. > > São **33 campos** em **6 grupos**, 29 deles com descrição > oficial. ## Como ler O corpo da emissão tem esta forma: ```json { "cpf_cnpj": "11222333000181", "nota": { "numero_rps": 1, "serie": "1", "infDPS": { "dhEmi": "2026-09-06T10:00:00-03:00", "prest": { "...": "..." }, "toma": { "...": "..." }, "serv": { "...": "..." } } } } ``` Cada seção abaixo é um desses blocos. A coluna **Nome interno** é o nome que o emissor usa internamente. Você não precisa dele para integrar, mas ele aparece em mensagens de erro. > **DICA — Um campo pode aceitar mais de um nome** > 3 campos aceitam nomes alternativos. Quando existem, aparecem como *"também:"* na > primeira coluna — qualquer um funciona. > **ATENÇÃO — Campo com nome errado não dá erro** > O conversor repassa chave desconhecida como veio, e o emissor a ignora: um `vlrProd` no lugar de > `vProd` gera uma nota **válida** com o produto valendo R$ 0,00. > > Antes da primeira emissão, passe o seu payload em > [`POST /v1/nfe/verificar-campos`](/docs/documentos/nfe/emitir) — ele aponta o campo desconhecido e > sugere o certo, sem emitir e sem consumir cota. ## `nota` (raiz) | Campo | Nome interno | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `numero_rps`
_também:_ `numero` | `Numero` | | | | _campo do emissor, sem descrição no layout_ | | `serie` | `Serie` | `string` | 5 | | Número do equipamento emissor do DPS ou série do DPS | | `dhEmi` | `DataEmissao` | `string` | | | Data e hora da emissão do DPS. Data e hora no formato UTC (Universal Coordinated Time): AAAA-MM-DDThh:mm:ssTZD | | `dCompet` | `Competencia` | `string` | | | Data em que se iniciou a prestação do serviço: Dia, mês e ano (AAAAMMDD) | | `verAplic` | `verAplic` | `TSString` | 20 | | | | `tpEmit` | `tpEmit` | `string` | | `1` `2` `3` | Emitente da DPS: 1 - Prestador; 2 - Tomador; 3 - Intermediário | ## `nota.prest` | Campo | Nome interno | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `CNPJ` | `CNPJ` | `string` | 14 | | Número do CNPJ do emitente da NFS-e. | | `CPF` | `CNPJCPF` | `string` | 11 | | Número do CPF do emitente da NFS-e. | | `InscricaoMunicipal`
_também:_ `IM` | `InscricaoMunicipal` | | | | _campo do emissor, sem descrição no layout_ | | `xNome`
_também:_ `RazaoSocial` | `RazaoSocial` | `string` | 300 | | Nome / Razão Social do emitente. | | `opSimpNac` | `opSimpNac` | `string` | | `1` `2` `3` | Situação perante o Simples Nacional: 1 - Não Optante; 2 - Optante - Microempreendedor Individual (MEI); 3 - Optante - Microempresa ou Empresa de Pequeno Porte (ME/EPP); | | `cMun` | `CodigoMunicipio` | `string` | | | Código do município, conforme Tabela do IBGE | | `CEP` | `CEP` | `string` | | | Número do CEP | | `email` | `Email` | `TSString` | 80 | | E-mail do emitente. | ## `nota.toma` | Campo | Nome interno | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `CNPJ` | `CNPJCPF` | `string` | 14 | | Número da inscrição no Cadastro Nacional de Pessoa Jurídica (CNPJ) do Destinatário do serviço | | `CPF` | `CNPJCPF` | `string` | 11 | | Número da inscrição no Cadastro de Pessoa Física (CPF) do Destinatário do serviço | | `xNome` | `RazaoSocial` | `string` | 300 | | Nome / Nome Empresarial do do Destinatário do serviço | | `email` | `Email` | `TSString` | 80 | | E-mail do Destinatário do serviço | | `cMun` | `CodigoMunicipio` | `string` | | | Código do município, conforme Tabela do IBGE | | `CEP` | `CEP` | `string` | | | Número do CEP | ## `nota.locPrest` | Campo | Nome interno | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cLocPrestacao` | `CodigoMunicipio` | `string` | | | Código do município onde o serviço foi prestado (tabela do IBGE) | | `cTribNac` | `ItemListaServico` | `string` | | | Código de tributação nacional do ISSQN, nos termos da LC 116/2003, conforme aba MUN.INCID_INFO.SERV. do ANEXO I Regra de formação - 6 dígitos numéricos sendo: 2 para Item (LC 116/2003), 2 para Subitem (LC 116/2003) e 2 para Desdobro Nacional | | `cTribMun` | `CodigoTributacaoMunicipio` | `string` | | | Código de tributação municipal do ISSQN | | `cIntContrib` | `CodigoInterContr` | `TSString` | 20 | | Código interno do contribuinte | | `xDescServ` | `Discriminacao` | `TSStringComQuebraDeLinha` | 2000 | | Descrição completa do serviço prestado | | `cNBS` | `CodigoNBS` | `string` | | | Código NBS correspondente ao serviço prestado, seguindo a versão 2.0, conforme Anexo B | ## `nota.atvEvento` | Campo | Nome interno | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `xNome` | `xNome` | `string` | 300 | | | | `dtIni` | `dtIni` | `string` | | | Data de início da atividade de evento. Ano, Mês e Dia (AAAA-MM-DD) | | `dtFim` | `dtFim` | `string` | | | Data de fim da atividade de evento. Ano, Mês e Dia (AAAA-MM-DD) | | `idAtvEvt` | `idAtvEvt` | `string` | 30 | | Identificação da Atividade de Evento (código identificador de evento determinado pela Administração Tributária Municipal) | | `CEP` | `CEP` | `string` | | | Número do CEP | ## `nota.vServPrest` | Campo | Nome interno | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `vServ` | `ValorServicos` | `string` | | | Valor dos serviços em R$ | | `vReceb` | `ValorRecebido` | `string` | | | Valor monetário recebido pelo intermediário do serviço (R$) | ## O que esta página não cobre Ela lista **quais campos existem e o que cada um aceita**. Ela não diz **quando** cada grupo é exigido — isso depende de UF, município, regime tributário e da operação, e está nos guias de emissão. Um payload que passa por esta referência ainda pode ser rejeitado por regra fiscal. ============================================================================== # https://docs.conota.dev/docs/documentos/nfse/referencia-de-campos-govdigital ============================================================================== # Referência de campos da NFS-e GovDigital Campos do objeto `nota` quando o provedor é o **GovDigital**. O payload é o mesmo `infDPS` do Padrão Nacional — o que muda é o XML que geramos a partir dele, não o que você envia. > **INFO — Esta página é gerada, não escrita** > Ela sai de duas fontes, direto do que roda em produção: > > - **o conversor** — quais nomes você pode enviar e em que campo do layout cada um vira; > - **os XSD oficiais** — tipo, tamanho, valores permitidos e a descrição de cada campo. > > Por isso ela não diverge do sistema: se um campo muda no código, muda aqui. E por isso os textos da > coluna *"O que é"* são os oficiais, não uma reescrita nossa. > > São **35 campos** em **12 grupos**, 30 deles com descrição > oficial. ## Como ler O corpo da emissão tem esta forma: ```json { "cpf_cnpj": "11222333000181", "provedor": "govdigital", "nota": { "infDPS": { "prest": { "CNPJ": "...", "IM": "..." }, "toma": { "...": "..." }, "serv": { "cServ": { "...": "..." } } } } } ``` Cada seção abaixo é um desses blocos. A coluna **Campo** é o próprio nome que você envia: neste provedor não há tradução de nome, só a montagem do XML. > **DICA — Um campo pode aceitar mais de um nome** > 8 campos aceitam nomes alternativos. Quando existem, aparecem como *"também:"* na > primeira coluna — qualquer um funciona. > **ATENÇÃO — Campo com nome errado não dá erro** > O conversor repassa chave desconhecida como veio, e o emissor a ignora: um `vlrProd` no lugar de > `vProd` gera uma nota **válida** com o produto valendo R$ 0,00. > > Antes da primeira emissão, passe o seu payload em > [`POST /v1/nfe/verificar-campos`](/docs/documentos/nfe/emitir) — ele aponta o campo desconhecido e > sugere o certo, sem emitir e sem consumir cota. ## `nota.prest` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `CNPJ` | `CNPJ` | `string` | 14 | | Número do CNPJ do emitente da NFS-e. | | `IM`
_também:_ `InscricaoMunicipal` | `IM` | `string` | 15 | | Número da inscrição municipal | | `xNome`
_também:_ `RazaoSocial` | `xNome` | `string` | 300 | | Nome / Razão Social do emitente. | | `opSimpNac` | `opSimpNac` | `string` | | `1` `2` `3` | Situação perante o Simples Nacional: 1 - Não Optante; 2 - Optante - Microempreendedor Individual (MEI); 3 - Optante - Microempresa ou Empresa de Pequeno Porte (ME/EPP); | ## `nota.cServ` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cNBS` | `cNBS` | `string` | | | Código NBS correspondente ao serviço prestado, seguindo a versão 2.0, conforme Anexo B | | `xDescServ` | `xDescServ` | `TSStringComQuebraDeLinha` | 2000 | | Descrição completa do serviço prestado | ## `nota.locPrest` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cLocPrestacao` | `cLocPrestacao` | `string` | | | Código do município onde o serviço foi prestado (tabela do IBGE) | ## `nota.tribMun` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cLocIncid`
_também:_ `cLocPrestacao` | `cLocIncid` | `string` | | | O código de município utilizado pelo Sistema Nacional NFS-e é o código definido para cada município pertencente ao ""Anexo V – Tabela de Código de Municípios do IBGE"", que consta ao final do Manual de Orientação ao Contribuinte do ISSQN para a Sefin Nacional NFS-e. O município de incidência do ISSQN é determinado automaticamente pelo sistema, conforme regras do aspecto espacial da lei complementar federal (LC 116/03) que são válidas para todos os municípios. http://www.planalto.gov.br/ccivil_03/Leis/LCP/Lcp116.htm | | `vISSQN` | `vISSQN` | `string` | | | Valor do ISSQN (R$) = Valor da Base de Cálculo x Alíquota ISSQN = vBC x pAliqAplic | | `pAliq` | `pAliq` | `string` | | | Valor da alíquota (%) do serviço prestado relativo ao município sujeito ativo (município de incidência) do ISSQN. Se o município de incidência pertence ao Sistema Nacional NFS-e a alíquota estará parametrizada e, portanto, será fornecida pelo sistema. Se o município de incidência não pertence ao Sistema Nacional NFS-e a alíquota não estará parametrizada e, por isso, deverá ser fornecida pelo emitente. | | `vBC`
_também:_ `vServ` | `vBC` | `string` | | | | | `tpRetISSQN` | `tpRetISSQN` | `string` | | `1` `2` `3` | Tipo de retencao do ISSQN: 1 - Não Retido; 2 - Retido pelo Tomador; 3 - Retido pelo Intermediario; | ## `nota.vServPrest` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `vServ` | `vServ` | `string` | | | Valor dos serviços em R$ | ## `nota.IBSCBS` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cIndOp` | `cIndOp` | `string` | | | Código indicador da operação de fornecimento, conforme tabela "código indicador de operação" | ## `nota.gIBSCBS` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cClassTrib`
_também:_ `CClassTribReg`, `cClassTribReg` | `cClassTrib` | `string` | | | Código de Classificação Tributária do IBS e da CBS | | `CST`
_também:_ `cst` | `CST` | `string` | | `00` `01` `02` `03` `04` `05` `06` `07` `08` `09` `49` `50` … | | | `TpRetPisCofins`
_também:_ `tpRetPisCofins` | `TpRetPisCofins` | | | | _campo do emissor, sem descrição no layout_ | ## `nota` (raiz) Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `usar_nt004` | `usar_nt004` | | | | _campo do emissor, sem descrição no layout_ | ## `nota.toma` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `CPF` | `CPF` | `string` | 11 | | Número da inscrição no Cadastro de Pessoa Física (CPF) do Destinatário do serviço | | `CNPJ` | `CNPJ` | `string` | 14 | | Número da inscrição no Cadastro Nacional de Pessoa Jurídica (CNPJ) do Destinatário do serviço | | `IM` | `IM` | `string` | 15 | | Número da inscrição municipal | | `xNome` | `xNome` | `string` | 300 | | Nome / Nome Empresarial do do Destinatário do serviço | ## `nota.atvEvento` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `desc`
_também:_ `nome`, `xNome` | `desc` | | | | _campo do emissor, sem descrição no layout_ | | `dtIni` | `dtIni` | `string` | | | Data de início da atividade de evento. Ano, Mês e Dia (AAAA-MM-DD) | | `dtFim` | `dtFim` | `string` | | | Data de fim da atividade de evento. Ano, Mês e Dia (AAAA-MM-DD) | | `idAtvEvt` | `idAtvEvt` | `string` | 30 | | Identificação da Atividade de Evento (código identificador de evento determinado pela Administração Tributária Municipal) | ## `nota.end` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `xLgr` | `xLgr` | `TSString` | 255 | | Tipo e nome do logradouro da localização do imóvel | | `nro` | `nro` | `TSString` | 60 | | Número do imóvel | | `xCpl` | `xCpl` | `TSString` | 156 | | Complemento do endereço | | `xBairro` | `xBairro` | `TSString` | 60 | | Bairro | | `UF` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | Sigla da unidade da federação do município do endereço do emitente. | | `CEP` | `CEP` | `string` | | | Número do CEP | | `cMun` | `cMun` | `string` | | | Código do município, conforme Tabela do IBGE | ## `nota.endNac` Neste grupo o nome que você envia **é** o nome do layout — não há tradução. | Campo | Campo | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cMun` | `cMun` | `string` | | | Código do município, conforme Tabela do IBGE | | `CEP` | `CEP` | `string` | | | Número do CEP | ## Grupos que passam direto Em 12 grupos o campo vai para o layout com o mesmo nome, sem tradução: `prest` · `cServ` · `locPrest` · `tribMun` · `vServPrest` · `IBSCBS` · `gIBSCBS` · `raiz` · `toma` · `atvEvento` · `end` · `endNac` São os grupos da Reforma Tributária e do ISSQN. Use os nomes do layout oficial. ## O que esta página não cobre Ela lista **quais campos existem e o que cada um aceita**. Ela não diz **quando** cada grupo é exigido — isso depende de UF, município, regime tributário e da operação, e está nos guias de emissão. Um payload que passa por esta referência ainda pode ser rejeitado por regra fiscal. ============================================================================== # https://docs.conota.dev/docs/documentos/cte/visao-geral ============================================================================== # CT-e — Conhecimento de Transporte Eletrônico O CT-e documenta a **prestação de um serviço de transporte**. Não é a nota da mercadoria: é a nota do frete. A carga já tem a NF-e dela; o CT-e diz quem transportou, de onde para onde, e por quanto. O Conota emite os dois modelos, no **modal rodoviário**: | Modelo | O que é | Quando | |---|---|---| | **57** — CT-e | transporte de **carga de terceiros** | o caso comum: você leva a mercadoria de alguém | | **67** — CT-e OS | **outros serviços** de transporte | pessoas, valores, excesso de bagagem | ```http POST /v1/cte/emitir ``` O modelo vem de `nota.identificacao.modelo`. O padrão é **57**. ## O que o CT-e tem e nenhum outro documento nosso tem > **ATENÇÃO — Cinco papéis, e o tomador é *escolhido* entre eles** > Na NF-e há emitente e destinatário. No CT-e (57) há **cinco**: > > - **remetente** — quem entrega a carga ao transportador; > - **expedidor** — quem faz a entrega no ponto de partida, quando não é o remetente; > - **recebedor** — quem recebe no destino, quando não é o destinatário; > - **destinatário** — para quem a carga vai; > - **tomador** — **quem paga o frete**, e é quem recebe o documento fiscal. > > O tomador normalmente **não é descrito**: ele é **apontado** entre os quatro acima. > > ```json > "tomador": { "indice": "0" } > ``` > > `0` = remetente · `1` = expedidor · `2` = recebedor · `3` = destinatário. > > Só quando quem paga é alguém de fora dos quatro é que o tomador se descreve por extenso. O **modelo 67 não tem nada disso**: é serviço prestado a um contratante único, então tem só `tomador`, e `servico` no lugar de `carga`. ## Pré-requisitos, por empresa 1. **Certificado A1 ativo** — ver [Certificado digital](/docs/conceitos/certificado). 2. **Credenciamento para CT-e na SEFAZ** do estado. É separado do credenciamento de NF-e: estar autorizado a emitir NF-e **não** autoriza a emitir CT-e. 3. **Configuração de CT-e** na empresa: ```http PUT /v1/empresas/{cpf_cnpj}/cte ``` ```json { "ambiente": 2, "crt": 3, "serie": "1", "proximo_numero": 1, "rntrc": "12345678" } ``` O **RNTRC** é o registro do transportador na ANTT, e vai no grupo `rodo` do CT-e 57. O **TAF** é o equivalente para o CT-e OS (67) — quem só emite 57 não precisa dele. > **DICA — Configurou uma vez, não precisa repetir na emissão** > Se o payload não trouxer `rodoviario.rntrc`, o Conota usa o que está na configuração da > empresa. O que vier no payload sempre vence. ## Cobertura Todos os **27 estados**, em produção e homologação. Os autorizadores variam — a maioria dos estados usa o **SVRS**, e MG, MS, MT, PR e SP têm os próprios —, mas isso é resolvido por nós: você manda a UF, o Conota acha o serviço. ## As rotas | Rota | O que faz | Consome cota | |---|---|---| | `POST /v1/cte/emitir` | emite (57 ou 67) | **sim** | | `POST /v1/cte/cancelar` | cancela um CT-e autorizado | **sim** | | `GET /v1/cte/consultar/{id}` | acompanha o job | não | | `GET /v1/cte/{id}/file/{tipo}` | baixa XML, DACTE ou log | não | ## Próximos passos - [Emitir](/docs/documentos/cte/emitir) — o payload dos dois modelos - [Referência de campos](/docs/documentos/cte/referencia-de-campos) — todos os campos, gerados do conversor - [Cancelamento](/docs/documentos/cte/cancelamento) — e por que "anulação" não existe mais ============================================================================== # https://docs.conota.dev/docs/documentos/cte/emitir ============================================================================== # Emitindo um CT-e ```http POST /v1/cte/emitir ``` ```bash curl -X POST https://api.conota.dev/v1/cte/emitir \ -H "X-API-Key: $CONOTA_API_KEY" \ -H "Content-Type: application/json" \ -d @cte.json ``` Devolve `202` com um `job_id`. A emissão é assíncrona, como todo documento aqui — ver [Emissão assíncrona](/docs/conceitos/assincrono). ## Modelo 57 — carga ```json { "cpf_cnpj": "11222333000181", "referencia_externa": "frete-4471", "nota": { "identificacao": { "modelo": 57, "cfop": "5353", "natureza_operacao": "PRESTACAO DE SERVICO DE TRANSPORTE", "serie": "1", "numero": "1", "data_emissao": "2026-09-06T10:00:00-03:00", "tipo_servico": "0", "codigo_municipio_inicio": "3106200", "municipio_inicio": "BELO HORIZONTE", "uf_inicio": "MG", "codigo_municipio_fim": "3550308", "municipio_fim": "SAO PAULO", "uf_fim": "SP" }, "emitente": { "cnpj": "11222333000181", "razao_social": "TRANSPORTADORA EXEMPLO" }, "remetente": { "cnpj": "11222333000181", "razao_social": "REMETENTE EXEMPLO" }, "destinatario": { "cnpj": "11222333000181", "razao_social": "DESTINATARIO EXEMPLO" }, "tomador": { "indice": "0" }, "prestacao": { "valor_total": "1500.00", "valor_receber": "1500.00", "componentes": [{ "nome": "FRETE VALOR", "valor": "1500.00" }] }, "imposto": { "icms": { "cst": "00", "base_calculo": "1500.00", "aliquota": "12.00", "valor": "180.00" } }, "carga": { "valor_carga": "50000.00", "produto_predominante": "ELETRODOMESTICOS", "quantidades": [{ "unidade": "01", "tipo_medida": "PESO BRUTO", "quantidade": "1200.0000" }] }, "documentos": { "nfe": [{ "chave_acesso": "3126..." }] }, "rodoviario": { "rntrc": "12345678" } } } ``` ## Modelo 67 — outros serviços Muda a estrutura, não só um campo: **um tomador só**, e `servico` no lugar de `carga`. ```json { "cpf_cnpj": "11222333000181", "nota": { "identificacao": { "modelo": 67, "tipo_servico": "6", "cfop": "5357", "...": "..." }, "emitente": { "...": "..." }, "tomador": { "cnpj": "11222333000181", "razao_social": "CONTRATANTE EXEMPLO" }, "servico": { "descricao": "TRANSPORTE DE PESSOAS", "quantidade": "1.0000" }, "prestacao": { "...": "..." }, "imposto": { "...": "..." }, "rodoviario": { "taf": "123456789" } } } ``` `tipo_servico` no 67: `6` transporte de pessoas · `7` transporte de valores · `8` excesso de bagagem. ## Detalhes que evitam rejeição > **DICA — Datas podem ir em ISO 8601** > O autorizador exige `dd/mm/aaaa`, mas isso é problema nosso. Mande > `2026-09-06T10:00:00-03:00` como no resto da API — a conversão acontece aqui. > **ATENÇÃO — O ICMS depende do CST, e o layout também** > No CT-e o grupo de ICMS **muda de forma conforme o CST**. Você manda sempre em > `imposto.icms`, com o `cst`, e o Conota monta o grupo certo: > > | CST | Grupo | > |---|---| > | `00` | tributação normal | > | `20` | com redução de base | > | `40`, `41`, `51` | isento / não tributado | > | `60` | ICMS cobrado por substituição tributária | > | `90` | outros | > > Simples Nacional usa `imposto.icms.simples_nacional: true`. > **IMPORTANTE — Tomador contribuinte precisa de IE** > Se `indicador_ie_tomador` marca contribuinte, a inscrição estadual **daquele papel** tem de > estar preenchida e válida. `ISENTO` não serve. É a rejeição **481**, e ela é fácil de > provocar sem perceber, porque o tomador costuma ser apontado por índice — o campo que falta > está em outro objeto. ## Complemento e substituição `identificacao.tipo_cte` define a finalidade: | Valor | O que é | |---|---| | `0` | normal | | `1` | complemento de valores | | `3` | **substituição** — corrige um CT-e já emitido | ```json "identificacao": { "tipo_cte": "3" }, "substituicao": { "chave": "3126...", "altera_tomador": "0" } ``` > **IMPORTANTE — `tipo_cte = 2` (Anulação) não existe mais** > No leiaute **3.00** havia CT-e de Anulação. No **4.00 ele foi removido** — o valor saiu da > lista permitida e o grupo `infCteAnu` saiu do schema. > > O Conota **recusa `tipo_cte = 2` com o motivo**, em vez de deixar você descobrir pela > rejeição da SEFAZ. Para corrigir um CT-e emitido, o caminho é a **substituição**. ## Idempotência `referencia_externa` faz o reenvio devolver o job original em vez de emitir de novo. Em frete isso importa mais que na NF-e: um retry de rede vira um segundo CT-e cobrando o mesmo serviço. Ver [Referência externa](/docs/conceitos/referencia-externa). ## Numeração A numeração é sua: `identificacao.numero`. O Conota transmite o que recebeu. Ver [Referência de campos](/docs/documentos/cte/referencia-de-campos) para a lista completa. ============================================================================== # https://docs.conota.dev/docs/documentos/cte/consultar ============================================================================== # Consultando uma emissão de CT-e ```bash curl -s https://api.conota.dev/v1/cte/consultar/$JOB_ID \ -H "X-API-Key: $CONOTA_API_KEY" ``` Lê o que já guardamos. **Não consome cota** — pode consultar à vontade enquanto espera. A resposta traz os dois eixos de estado, o do processamento e o fiscal. Ver [Status das emissões](/docs/conceitos/status). ## Em lote e por referência As rotas genéricas valem para o CT-e como para qualquer documento: ```http POST /v1/jobs/consultar-lote # até 200 ids GET /v1/jobs/localizar?ref=frete_4471 ``` Id inexistente ou de outra conta volta como `"status": "nao_encontrado"` — sem `404`. ## Rejeição não é "concluído" > **ATENÇÃO — Um CT-e recusado pela SEFAZ vem como `failed`, com o motivo** > Isso parece óbvio e não é: a biblioteca que fala com o autorizador devolve **sucesso** mesmo > quando a SEFAZ **rejeita** o documento. Quem trata isso somos nós. > > O erro chega com o código oficial na frente: > > ``` > [CTe 481] Rejeicao: IE deve ser informada para tomador Contribuinte > ``` > > E rejeição **não é re-tentada**: o documento está errado e seria recusado de novo. As > exceções são `108` e `109` — serviço paralisado —, que são transitórias e essas sim voltam a > tentar. ## O CT-e depende de dois cadastros, não de um > **INFO — Rejeição de credenciamento parece rejeição de payload** > Emitir CT-e exige **credenciamento próprio na SEFAZ**, separado do de NF-e. Uma empresa que > emite NF-e há anos pode ter o primeiro CT-e recusado sem que haja nada de errado no payload. > > Se as rejeições apontarem o emitente e não um campo da carga, confira o credenciamento antes > de mexer no JSON. ## Consultar não é o mesmo que ter o documento Depois de autorizado, o XML e o DACTE saem por [Arquivos](/docs/documentos/cte/arquivos). ============================================================================== # https://docs.conota.dev/docs/documentos/cte/arquivos ============================================================================== # Arquivos: XML e DACTE ```http GET /v1/cte/{job_id}/file/{tipo} ``` | `tipo` | Conteúdo | |---|---| | `xml` | XML do CT-e autorizado (`cteProc`: o CT-e mais o protocolo) | | `pdf` | **DACTE** | | `xml_cancelamento` | XML do cancelamento, quando houver | | `log` | log técnico do processamento | As rotas genéricas por job também servem: ```http GET /v1/jobs/{job_id}/arquivos # o que existe para este job GET /v1/jobs/{job_id}/download/{tipo} # devolve a URL assinada, sem baixar ``` ## O DACTE acompanha a carga > **ATENÇÃO — Aqui o papel tem função operacional, não só fiscal** > O DANFE de uma NF-e acompanha a mercadoria. O **DACTE acompanha o veículo**, e é o que a > fiscalização de estrada pede na barreira. Diferente do cupom da NFC-e, que o consumidor > descarta, este documento é conferido por terceiros durante a viagem. > > Vale desenhar o fluxo pensando nisso: o motorista precisa do DACTE **antes de sair**, não > depois que o sistema reconciliar. ## `xml` sem protocolo = não autorizado O `xml` de um CT-e autorizado é o **`cteProc`** — o documento mais o protocolo da SEFAZ. Se você receber um XML que começa em `` e não em ``, ele **não foi autorizado**; consulte o job para ver o motivo. ## Guarde o XML > **IMPORTANTE — O XML é o documento fiscal — o PDF é a representação** > A obrigação de guarda recai sobre o **XML autorizado**. O DACTE pode ser regerado a partir > dele; o contrário não. A retenção no Conota depende do plano. Sua operação deve armazenar os XMLs no próprio ambiente. ## Pacotes mensais ```http GET /v1/arquivos/zip-mensal?tipo=cte&competencia=2026-08 ``` Repare no `tipo=cte`: cada documento tem o seu pacote. ============================================================================== # https://docs.conota.dev/docs/documentos/cte/cancelamento ============================================================================== # Cancelando um CT-e ```http POST /v1/cte/cancelar ``` ```json { "cpf_cnpj": "11222333000181", "job_id": "6f8dc295-...", "justificativa": "Servico de transporte nao executado" } ``` Informe `job_id` **ou** `chave`. A justificativa tem **mínimo de 15 caracteres** — exigência do autorizador. Devolve `202` com um novo `job_id`, e **consome cota de CT-e**. ## O prazo é mais curto, e depende da viagem > **IMPORTANTE — Não assuma as 24 horas da NF-e** > O prazo de cancelamento do CT-e é **definido por cada UF** e costuma ser bem menor que o da > NF-e. E há um limite que não é de tempo: **vários estados não permitem cancelar depois de > iniciada a prestação do serviço** — ou seja, depois que o veículo saiu. > > Quem recusa é a SEFAZ, não a API. Confirme a regra da UF do emitente. ## Anulação não existe mais > **ATENÇÃO — Quem vem do leiaute 3.00 vai procurar e não vai achar** > Havia o **CT-e de Anulação** (`tpCTe = 2`). No leiaute **4.00 ele foi removido**: o valor > saiu da lista permitida e o grupo `infCteAnu` saiu do schema oficial. > > O Conota **recusa `tipo_cte = 2` com o motivo**, em vez de deixar a SEFAZ devolver um código > que ninguém entende. O caminho de correção passou a ser a **substituição**: ```json "identificacao": { "tipo_cte": "3" }, "substituicao": { "chave": "3126...", "altera_tomador": "0" } ``` `altera_tomador` só é necessário quando a substituição **também troca o tomador**; sem ele, o autorizador entende que o tomador permanece. Quando o problema é do lado de quem contratou o frete, existe ainda o evento próprio de prestação em desacordo, registrado pelo tomador — que é outro fluxo, e não passa por esta rota. ## Só se cancela o que foi autorizado | Situação | Cancelamento | |---|---| | autorizado | possível, dentro do prazo da UF | | rejeitado | **não existe o que cancelar** | | já cancelado | nada a fazer | ## Depois do cancelamento O XML do evento fica disponível como `xml_cancelamento` — ver [Arquivos](/docs/documentos/cte/arquivos). O `xml` original continua lá. ============================================================================== # https://docs.conota.dev/docs/documentos/cte/referencia-de-campos ============================================================================== # Referência de campos do CT-e Todos os campos que o Conota aceita dentro do objeto `nota`, para **CT-e (modelo 57)** e **CT-e OS (modelo 67)**, no modal rodoviário. > **INFO — Esta página é gerada, não escrita** > Ela sai de duas fontes, direto do que roda em produção: > > - **o conversor** — quais nomes você pode enviar e em que campo do layout cada um vira; > - **os XSD oficiais** — tipo, tamanho, valores permitidos e a descrição de cada campo. > > Por isso ela não diverge do sistema: se um campo muda no código, muda aqui. E por isso os textos da > coluna *"O que é"* são os oficiais, não uma reescrita nossa. > > São **231 campos** em **29 grupos**, 131 deles com descrição > oficial. ## Como ler O corpo da emissão tem esta forma: ```json { "cpf_cnpj": "11222333000181", "nota": { "identificacao": { "modelo": 57, "...": "..." }, "emitente": { "...": "..." }, "remetente": { "...": "..." }, "destinatario": { "...": "..." }, "tomador": { "indice": "0" }, "prestacao": { "valor_total": "100.00", "componentes": [ { "...": "..." } ] }, "imposto": { "icms": { "cst": "00", "...": "..." } }, "carga": { "...": "..." }, "documentos": { "nfe": [ { "chave_acesso": "..." } ] }, "rodoviario": { "rntrc": "..." } } } ``` Cada seção abaixo é um desses blocos. A coluna **Vira** é o nome do campo no layout oficial, útil quando o fisco devolve uma rejeição citando o nome dele. > **DICA — Um campo pode aceitar mais de um nome** > 39 campos aceitam nomes alternativos. Quando existem, aparecem como *"também:"* na > primeira coluna — qualquer um funciona. > **ATENÇÃO — Campo com nome errado não dá erro** > O conversor repassa chave desconhecida como veio, e o emissor a ignora: um `vlrProd` no lugar de > `vProd` gera uma nota **válida** com o produto valendo R$ 0,00. > > Antes da primeira emissão, passe o seu payload em > [`POST /v1/nfe/verificar-campos`](/docs/documentos/nfe/emitir) — ele aponta o campo desconhecido e > sugere o certo, sem emitir e sem consumir cota. ## `nota.null` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cst` | `CST` | `string` | | `00` | | | `base_calculo` | `vBC` | `string` | | | | | `aliquota` | `pICMS` | `string` | | | Alíquota do ICMS | | `valor` | `vICMS` | `string` | | | | | `reducao_base` | `pRedBC` | `string` | | | Percentual de redução da BC | ## `nota.identificacao` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `codigo_uf`
_também:_ `uf` | `cUF` | `string` | | `11` `12` `13` `14` `15` `16` `17` `21` `22` `23` `24` `25` … | | | `codigo_ct` | `cCT` | `string` | | | Código numérico que compõe a Chave de Acesso. | | `cfop` | `CFOP` | `string` | | | Código Fiscal de Operações e Prestações | | `natureza_operacao`
_também:_ `nat_op` | `natOp` | `TString` | 60 | | Natureza da Operação | | `forma_pagamento` | `forPag` | | | | _campo do emissor, sem descrição no layout_ | | `modelo` | `mod` | `string` | | `64` | | | `serie` | `serie` | `TSerie` | 3 | | | | `numero` | `nCT` | `string` | | | | | `data_emissao` | `dhEmi` | `TDateTimeUTC` | | | | | `tipo_impressao` | `tpImp` | `string` | | `1` `2` | | | `tipo_emissao` | `tpEmis` | `string` | | `1` `2` | | | `tipo_ambiente`
_também:_ `ambiente` | `tpAmb` | `string` | | `1` `2` | | | `processo_emissao` | `procEmi` | `string` | | `0` `3` `4` | | | `versao_processo` | `verProc` | `TString` | 20 | | Versão do processo de emissão | | `data_contingencia` | `dhCont` | `string` | | | Data e Hora da entrada em contingência | | `justificativa` | `xJust` | `TString` | 256 | | Justificativa da entrada em contingência | | `tipo_cte` | `tpCTe` | `TFinGTVe` | | `4` | | | `cte_referenciado` | `refCTe` | | | | _campo do emissor, sem descrição no layout_ | | `codigo_municipio_envio` | `cMunEnv` | `string` | | | | | `municipio_envio` | `xMunEnv` | `TString` | 60 | | | | `uf_envio` | `UFEnv` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `modal` | `modal` | `TModTranspGTVe` | | `01` `06` `01` `06` | | | `tipo_servico` | `tpServ` | `string` | | `9` | Tipo do Serviço | | `codigo_municipio_inicio` | `cMunIni` | `string` | | | Código do Município de início da prestação | | `municipio_inicio` | `xMunIni` | `TString` | 60 | | Nome do Município do início da prestação | | `uf_inicio` | `UFIni` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | UF do início da prestação | | `codigo_municipio_fim` | `cMunFim` | `string` | | | Código do Município de término da prestação | | `municipio_fim` | `xMunFim` | `TString` | 60 | | Nome do Município do término da prestação | | `uf_fim` | `UFFim` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | UF do término da prestação | | `retira` | `retira` | `string` | | `0` `1` | Indicador se o Recebedor retira no Aeroporto, Filial, Porto ou Estação de Destino? | | `detalhe_retira` | `xDetRetira` | `TString` | 160 | | Detalhes do retira | | `globalizado` | `indGlobalizado` | `string` | | `1` | Indicador de CT-e Globalizado | | `indicador_ie_tomador` | `indIEToma` | `string` | | `1` `2` `9` | | ## `nota.complemento` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `caracteristica_adicional` | `xCaracAd` | `TString` | 15 | | Característica adicional do transporte | | `caracteristica_servico` | `xCaracSer` | `TString` | 30 | | Característica adicional do serviço | | `emitido_por` | `xEmi` | `TString` | 20 | | | | `origem` | `xOrig` | `TString` | 60 | | Sigla ou código interno da Filial/Porto/Estação/ Aeroporto de Origem | | `destino` | `xDest` | `TString` | 60 | | Sigla ou código interno da Filial/Porto/Estação/Aeroporto de Destino | | `rota` | `xRota` | `TString` | 10 | | Código da Rota de Entrega | | `tipo_data` | `TipoData` | | | | _campo do emissor, sem descrição no layout_ | | `tipo_hora` | `TipoHora` | | | | _campo do emissor, sem descrição no layout_ | | `origem_calculo` | `origCalc` | `TString` | 40 | | Município de origem para efeito de cálculo do frete | | `destino_calculo` | `destCalc` | `TString` | 40 | | Município de destino para efeito de cálculo do frete | | `observacoes` | `xObs` | `TString` | 2000 | | | ## `nota.emitente` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf` | `CNPJ` | `string` | | | CNPJ do emitente | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | Inscrição Estadual do Emitente | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão social ou Nome do emitente | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `regime_tributario`
_também:_ `crt` | `CRT` | `string` | 1 | `1` `2` `3` `4` | Código do Regime Tributário | | `inscricao_suframa` | `ISUFEmit` | `string` | 9 | | Inscrição do emitente da Suframa | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `telefone` | `fone` | `string` | | | | ## `nota.prestacao` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `valor_total` | `vTPrest` | `string` | | | Valor Total da Prestação do Serviço | | `valor_receber` | `vRec` | `string` | | | Valor a Receber | ## `nota.componentes[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `nome`
_também:_ `descricao` | `xNome` | `TString` | 60 | | | | `valor` | `vComp` | `string` | | | Valor do componente | ## `nota.Imp` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `total_tributos` | `vTotTrib` | `string` | | | Valor Total dos Tributos | | `informacao_fisco` | `infAdFisco` | `TString` | 2000 | | Informações adicionais de interesse do Fisco | | `total_dfe` | `vTotDFe` | `string` | | | Valor total do documento fiscal (vTPrest + total do IBS + total da CBS) | ## `nota.observacoes_contribuinte[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `campo` | `xCampo` | | | | _campo do emissor, sem descrição no layout_ | | `texto` | `xTexto` | `TString` | 160 | | Conteúdo do campo | ## `nota.observacoes_fisco[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `campo` | `xCampo` | | | | _campo do emissor, sem descrição no layout_ | | `texto` | `xTexto` | `TString` | 160 | | Conteúdo do campo | ## `nota.cobranca` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `numero_fatura` | `nFat` | `TString` | 60 | | Número da fatura | | `valor_original` | `vOrig` | `string` | | | Valor original da fatura | | `desconto` | `vDesc` | `string` | | | Valor do desconto da fatura | | `valor_liquido` | `vLiq` | `string` | | | Valor líquido da fatura | ## `nota.responsavel_tecnico` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj` | `CNPJ` | `string` | | | | | `contato` | `xContato` | `TString` | 60 | | Nome da pessoa a ser contatada | | `email` | `email` | `string` | 60 | | | | `telefone` | `fone` | `string` | | | | ## `nota.remetente` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## `nota.local_coleta` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## `nota.expedidor` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## `nota.recebedor` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## `nota.destinatario` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão Social ou Nome do destinatário | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## `nota.infCarga` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `valor_carga` | `vCarga` | `string` | | | Valor total da carga | | `produto_predominante` | `proPred` | `TString` | 60 | | Produto predominante | | `outras_caracteristicas` | `xOutCat` | `TString` | 30 | | Outras características da carga | | `valor_averbacao` | `vCargaAverb` | `string` | | | Valor da Carga para efeito de averbação | ## `nota.quantidades[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `unidade` | `cUnid` | `string` | | `00` `01` `02` `03` `04` `05` | Código da Unidade de Medida | | `tipo_medida` | `tpMed` | `TString` | 2 | `00` `01` `02` `03` `04` `05` `06` `07` `08` `09` `10` `11` … | Tipo da Medida | | `quantidade` | `qCarga` | `string` | | | | ## `nota.nfe[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `chave_acesso`
_também:_ `chave` | `chave` | `string` | 44 | | | | `pin` | `PIN` | `string` | 9 | | PIN SUFRAMA | | `data_prevista` | `dPrev` | `string` | | | Data prevista de entrega | ## `nota.rodoviario` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `rntrc` | `RNTRC` | `string` | | | | | `data_prevista` | `dPrev` | `string` | | | Data prevista de entrega | | `lotacao` | `lota` | | | | _campo do emissor, sem descrição no layout_ | ## `nota.substituicao` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `chave`
_também:_ `chave_cte`, `chave_substituido` | `chCte` | `string` | 44 | | Chave de acesso do CT-e a ser substituído (original) | | `altera_tomador` | `indAlteraToma` | `string` | | `1` | Indicador de CT-e Alteração de Tomador | ## `nota.tomador` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão Social ou Nome do destinatário | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## `nota.servico` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `descricao` | `xDescServ` | `TString` | 30 | | Descrição do Serviço prestado | | `quantidade` | `qCarga` | `string` | | | | ## `nota.documentos_referenciados[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `chave_bpe` | `chBPe` | `TChDFe` | 44 | | Chave de acesso do BP-e que possui eventos excesso de bagagem | | `numero` | `nDoc` | `TString` | 20 | | | | `serie` | `serie` | `TSerie` | 3 | | | | `data_emissao` | `dEmi` | `string` | | | | | `valor` | `vDoc` | `string` | | | Valor Transportado | ## `nota.seguros[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `responsavel` | `respSeg` | `string` | 1 | `4` `5` | Responsável pelo seguro | | `seguradora` | `xSeg` | `TString` | 30 | | Nome da Seguradora | | `apolice` | `nApol` | `TString` | 20 | | Número da Apólice | | `averbacao` | `nAver` | | | | _campo do emissor, sem descrição no layout_ | | `valor_carga` | `vCarga` | `string` | | | Valor total da carga | ## `nota.rodoviario` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `taf` | `TAF` | | | | _campo do emissor, sem descrição no layout_ | | `registro_estadual` | `NroRegEstadual` | | | | _campo do emissor, sem descrição no layout_ | ## `nota.fretamento` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `tipo` | `tpFretamento` | | | | _campo do emissor, sem descrição no layout_ | | `data_viagem` | `dhViagem` | | | | _campo do emissor, sem descrição no layout_ | ## `nota.tributos_federais` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `pis` | `vPIS` | `string` | | | Valor do PIS | | `cofins` | `vCOFINS` | `string` | | | Valor COFINS | | `ir` | `vIR` | `string` | | | Valor de Imposto de Renda | | `inss` | `vINSS` | `string` | | | Valor do INSS | | `csll` | `vCSLL` | `string` | | | Valor do CSLL | ## `nota.tomador` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf`, `cpf`, `documento` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIeDest` | 14 | | | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão Social ou Nome do destinatário | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome Fantasia | | `telefone` | `fone` | `string` | | | | | `email` | `Email` | | | | _campo do emissor, sem descrição no layout_ | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | CEP | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `codigo_pais` | `cPais` | `string` | | | Código do país | | `pais` | `xPais` | `TString` | 60 | | Nome do país | ## Grupos que passam direto Em 6 grupos o campo vai para o layout com o mesmo nome, sem tradução: `icms_uf_fim` · `nf[]` · `outros[]` · `ordens_coleta[]` · `null` · `toma3` São os grupos da Reforma Tributária e do ISSQN. Use os nomes do layout oficial. ## O que esta página não cobre Ela lista **quais campos existem e o que cada um aceita**. Ela não diz **quando** cada grupo é exigido — isso depende de UF, município, regime tributário e da operação, e está nos guias de emissão. Um payload que passa por esta referência ainda pode ser rejeitado por regra fiscal. ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/visao-geral ============================================================================== # MDF-e — Manifesto Eletrônico de Documentos Fiscais O MDF-e é o documento **da viagem**, não da carga nem do frete. Ele agrupa, num único documento, todos os CT-e ou NF-e que estão dentro daquele veículo naquele deslocamento. ```http POST /v1/mdfe/emitir ``` ## É o único documento que exige ação depois de autorizado > **IMPORTANTE — Manifesto aberto é infração** > Todos os outros documentos do Conota terminam quando a SEFAZ autoriza. O MDF-e não: > **quando a viagem acaba, ele precisa ser encerrado.** > > ```http > POST /v1/mdfe/encerrar > ``` > > Se você emite MDF-e, o encerramento **faz parte do fluxo**, não é opcional. Desenhe isso > desde o começo — descobrir depois que há dezenas de manifestos abertos é caro. > > E para saber quais estão pendentes, não precisa manter um controle paralelo: > > ```http > POST /v1/mdfe/nao-encerrados > ``` > > Essa rota **pergunta à própria SEFAZ** quais manifestos daquele CNPJ seguem abertos. É a > fonte da verdade, e **não consome cota**. ## `tipo_emitente` decide o que o manifesto carrega > **ATENÇÃO — Errar aqui produz um manifesto vazio, e ninguém reclama** > | `tipo_emitente` | Quem é | O manifesto carrega | > |---|---|---| > | `1` | prestador de serviço de transporte | **CT-e** | > | `2` | transportador de carga própria | **NF-e** | > | `3` | prestador com CT-e Globalizado | **NF-e** | > > A biblioteca do autorizador **não reclama** da combinação errada: ela monta um manifesto > **sem documento nenhum**. O Conota recusa antes, com o motivo — mas vale entender a regra, > porque ela não é intuitiva. > > Configure na empresa e não pense mais nisso: > > ```http > PUT /v1/empresas/{cpf_cnpj}/mdfe > ``` ## Como os documentos entram Agrupados **pelo município onde saem da carga**, não numa lista solta: ```json "descarregamento": [ { "codigo": "3550308", "municipio": "SAO PAULO", "cte": [{ "chave": "3126..." }] }, { "codigo": "3106200", "municipio": "BELO HORIZONTE", "cte": [{ "chave": "3126..." }, { "chave": "3126..." }] } ] ``` Faz sentido quando se pensa na viagem: o manifesto descreve um percurso com paradas, e cada parada tem a sua carga. ## Pré-requisitos 1. **Certificado A1 ativo** — ver [Certificado digital](/docs/conceitos/certificado). 2. **Configuração de MDF-e** na empresa (`tipo_emitente`, RNTRC, série). 3. Os documentos que vão no manifesto precisam estar **autorizados** antes. ## As rotas | Rota | O que faz | Consome cota | |---|---|---| | `POST /v1/mdfe/emitir` | emite o manifesto | **sim** | | `POST /v1/mdfe/encerrar` | encerra quando a viagem acaba | **sim** | | `POST /v1/mdfe/cancelar` | cancela — só antes de iniciada a viagem | **sim** | | `POST /v1/mdfe/nao-encerrados` | pergunta à SEFAZ quais seguem abertos | **não** | | `GET /v1/mdfe/consultar/{id}` | acompanha o job | não | | `GET /v1/mdfe/{id}/file/{tipo}` | XML, DAMDFE ou log | não | ## Próximos passos - [Emitir](/docs/documentos/mdfe/emitir) - [Encerramento](/docs/documentos/mdfe/encerramento) — a parte que não existe nos outros documentos - [Referência de campos](/docs/documentos/mdfe/referencia-de-campos) ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/emitir ============================================================================== # Emitindo um MDF-e ```http POST /v1/mdfe/emitir ``` ```json { "cpf_cnpj": "11222333000181", "referencia_externa": "viagem-4471", "nota": { "identificacao": { "codigo_uf": "31", "tipo_emitente": 1, "serie": "1", "numero": "1", "data_emissao": "2026-09-06T10:00:00-03:00", "data_inicio_viagem": "2026-09-06T12:00:00-03:00", "uf_inicio": "MG", "uf_fim": "SP", "municipios_carregamento": [ { "codigo": "3170206", "municipio": "UBERLANDIA" } ], "percurso": [{ "uf": "GO" }] }, "emitente": { "cnpj": "11222333000181", "razao_social": "TRANSPORTADORA EXEMPLO" }, "rodoviario": { "rntrc": "12345678", "veiculo": { "codigo_interno": "1", "placa": "ABC1D23", "tara": "5000", "capacidade_kg": "20000", "tipo_rodado": "06", "tipo_carroceria": "02", "uf": "MG" }, "condutores": [{ "nome": "MOTORISTA EXEMPLO", "cpf": "11122233396" }] }, "descarregamento": [ { "codigo": "3550308", "municipio": "SAO PAULO", "cte": [{ "chave": "3126..." }] } ], "produto_predominante": { "tipo_carga": "05", "descricao": "ELETRODOMESTICOS" }, "totais": { "quantidade_cte": "1", "valor_carga": "50000.00", "unidade": "01", "quantidade_carga": "1200.0000" } } } ``` Devolve `202` com um `job_id`. ## O campo que mais gera erro > **IMPORTANTE — `tipo_emitente` tem de bater com o documento que você envia** > | `tipo_emitente` | Aceita em `descarregamento[]` | > |---|---| > | `1` prestador de serviço de transporte | `cte` | > | `2` transportador de carga própria | `nfe` | > | `3` prestador com CT-e Globalizado | `nfe` | > > Mandar `nfe` com `tipo_emitente: 1` **não dá erro no autorizador** — ele monta um manifesto > sem documento nenhum, e autoriza. O Conota recusa antes: > > ```json > { "erro": "tipo_emitente=1 (prestador de servico de transporte) so aceita CTE no > manifesto, e o payload traz NFE. Essa combinacao nao da erro na biblioteca: ela monta > um manifesto SEM documento nenhum." } > ``` > > Se você configurou `tipo_emitente` na empresa, não precisa repetir no payload. ## O que vem da configuração da empresa `tipo_emitente` e `rntrc` são **cadastro**, não dado de viagem. Configure uma vez em `PUT /v1/empresas/{cpf_cnpj}/mdfe` e o Conota preenche quando o payload não trouxer. O que vier no payload sempre vence. ## Detalhes > **DICA — Datas podem ir em ISO 8601** > O autorizador exige `dd/mm/aaaa`; a conversão é nossa. **Percurso** é a lista de UFs por onde a carga passa **entre** a origem e o destino — não inclui as duas pontas. **Municípios de carregamento** aceitam mais de um: uma viagem pode recolher carga em vários pontos antes de sair. ## Idempotência `referencia_externa` faz o reenvio devolver o job original. Em manifesto isso importa: dois MDF-e para a mesma viagem é problema fiscal, não só duplicidade de registro. Ver [Referência externa](/docs/conceitos/referencia-externa). ## Depois de emitir O manifesto **não terminou**. Ver [Encerramento](/docs/documentos/mdfe/encerramento). ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/encerramento ============================================================================== # Encerrando um MDF-e ```http POST /v1/mdfe/encerrar ``` ```json { "cpf_cnpj": "11222333000181", "chave": "3126...", "codigo_municipio": "3550308", "protocolo": "131260001234567", "data": "2026-09-07" } ``` Consome cota de MDF-e. Devolve `202` com um `job_id`. ## Isto não é opcional > **IMPORTANTE — Manifesto aberto é infração** > Todos os outros documentos do Conota acabam quando a SEFAZ autoriza. O MDF-e é o único que > **exige uma segunda ação**, e o intervalo entre a autorização e o encerramento é uma janela > em que a empresa está irregular. > > Se a sua integração emite MDF-e e não encerra, ela está construindo um passivo — e ele só > aparece quando alguém olha. ## O município é onde a viagem *terminou* > **ATENÇÃO — Nem sempre é o destino planejado** > `codigo_municipio` é o IBGE do lugar onde a viagem **de fato** acabou. Se o veículo foi > desviado, se a última entrega mudou, se a carga voltou — o que vale é o real, não o que > estava no manifesto. > > Errar isso não é detalhe de preenchimento: o encerramento é a declaração de onde a operação > terminou. ## O `protocolo` é o da autorização do manifesto Sai da consulta do job de emissão. Guarde-o junto com a chave — você vai precisar dos dois no encerramento, possivelmente dias depois. ## Como saber quais estão abertos ```http POST /v1/mdfe/nao-encerrados ``` ```json { "cpf_cnpj": "11222333000181" } ``` > **DICA — Pergunta à SEFAZ, não a nós** > Esta rota consulta **o próprio autorizador**: quais manifestos deste CNPJ ele considera > abertos. Não é um espelho nosso do que aconteceu — é a fonte. > > Isso importa porque um espelho pode divergir: um encerramento que falhou no meio, um > manifesto emitido por outro sistema, uma reconciliação que ninguém rodou. A SEFAZ sabe. > > **Não consome cota** — é consulta. Rode com a frequência que fizer sentido para a sua > operação; um manifesto que ficou aberto por engano custa mais que a chamada. ## Cancelar não é encerrar | | Quando | O que significa | |---|---|---| | **cancelar** | **antes** de iniciada a viagem | o manifesto não valeu | | **encerrar** | **depois** que a viagem terminou | o manifesto cumpriu o papel | Depois que a viagem começou, o caminho é o encerramento. Cancelar deixa de ser possível — e essa é uma regra da SEFAZ, não da API. ## Depois do encerramento O manifesto continua existindo e o XML continua disponível em [Arquivos](/docs/documentos/mdfe/arquivos). Encerrar não apaga: registra que a viagem acabou. ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/consultar ============================================================================== # Consultando uma emissão de MDF-e ```bash curl -s https://api.conota.dev/v1/mdfe/consultar/$JOB_ID \ -H "X-API-Key: $CONOTA_API_KEY" ``` Lê o que já guardamos. **Não consome cota.** A mesma rota serve para acompanhar **emissão, encerramento e cancelamento** — os três são jobs, e todos devolvem um `job_id`. ## Rejeição vem como `failed`, com o motivo > **ATENÇÃO — A biblioteca do autorizador devolve sucesso mesmo quando a SEFAZ rejeita** > Quem trata isso somos nós. O erro chega com o código oficial na frente: > > ``` > [MDFe 493] Rejeicao: ... > ``` > > E rejeição **não é re-tentada** — o documento está errado e seria recusado de novo. As > exceções são `108` e `109`, serviço paralisado, que voltam a tentar. ## Em lote e por referência ```http POST /v1/jobs/consultar-lote # até 200 ids GET /v1/jobs/localizar?ref=viagem_4471 ``` ## Não confunda com a consulta de não encerrados | Pergunta | Rota | |---|---| | como ficou este job? | `GET /v1/mdfe/consultar/{id}` | | **quais manifestos meus seguem abertos?** | `POST /v1/mdfe/nao-encerrados` | A segunda vai à SEFAZ e é a base do controle de encerramento — ver [Encerramento](/docs/documentos/mdfe/encerramento). ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/arquivos ============================================================================== # Arquivos: XML e DAMDFE ```http GET /v1/mdfe/{job_id}/file/{tipo} ``` | `tipo` | Conteúdo | |---|---| | `xml` | XML do manifesto autorizado (`mdfeProc`: o MDF-e mais o protocolo) | | `pdf` | **DAMDFE** | | `xml_cancelamento` | XML do cancelamento, quando houver | | `log` | log técnico do processamento | ## O DAMDFE viaja com o veículo > **ATENÇÃO — É o documento que a fiscalização de estrada pede** > Como o DACTE, o DAMDFE tem função operacional: acompanha o veículo e é conferido em barreira. > O motorista precisa dele **antes de sair**. > > Diferente do DACTE, porém, o DAMDFE representa a **viagem inteira** — é por ele que a > fiscalização vê tudo o que está dentro do veículo num documento só. ## `xml` sem protocolo = não autorizado O `xml` de um manifesto autorizado é o **`mdfeProc`** — o documento mais o protocolo. Se vier começando em `` e não em ``, ele **não foi autorizado**; consulte o job para ver o motivo. ## Guarde o XML > **IMPORTANTE — O XML é o documento fiscal — o PDF é a representação** > A obrigação de guarda recai sobre o **XML autorizado**. O DAMDFE pode ser regerado a partir > dele; o contrário não. ## Pacotes mensais ```http GET /v1/arquivos/zip-mensal?tipo=mdfe&competencia=2026-08 ``` ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/cancelamento ============================================================================== # Cancelando um MDF-e ```http POST /v1/mdfe/cancelar ``` ```json { "cpf_cnpj": "11222333000181", "chave": "3126...", "justificativa": "Viagem cancelada antes do inicio do transporte" } ``` Justificativa com **mínimo de 15 caracteres** — exigência do autorizador. Consome cota. ## Só antes de a viagem começar > **IMPORTANTE — Depois disso, o caminho é o encerramento** > O cancelamento vale enquanto o transporte **não começou**. Uma vez iniciada a viagem, o > manifesto não se cancela: ele se **encerra**. > > | Situação | O que fazer | > |---|---| > | manifesto emitido, veículo ainda parado | **cancelar** | > | viagem em andamento ou concluída | **[encerrar](/docs/documentos/mdfe/encerramento)** | > | manifesto rejeitado | nada — não chegou a valer | > > Confundir os dois é o erro mais comum de quem está começando com MDF-e, e a SEFAZ responde > com rejeição, não com orientação. Há também prazo: cada UF define até quando o cancelamento é aceito, e ele é curto. Confirme a regra do estado do emitente. ## Depois do cancelamento O XML do evento fica disponível como `xml_cancelamento` — ver [Arquivos](/docs/documentos/mdfe/arquivos). ============================================================================== # https://docs.conota.dev/docs/documentos/mdfe/referencia-de-campos ============================================================================== # Referência de campos do MDF-e Todos os campos que o Conota aceita dentro do objeto `nota` para o **MDF-e (modelo 58)**, no modal rodoviário. > **INFO — Esta página é gerada, não escrita** > Ela sai de duas fontes, direto do que roda em produção: > > - **o conversor** — quais nomes você pode enviar e em que campo do layout cada um vira; > - **os XSD oficiais** — tipo, tamanho, valores permitidos e a descrição de cada campo. > > Por isso ela não diverge do sistema: se um campo muda no código, muda aqui. E por isso os textos da > coluna *"O que é"* são os oficiais, não uma reescrita nossa. > > São **85 campos** em **18 grupos**, 58 deles com descrição > oficial. ## Como ler O corpo da emissão tem esta forma: ```json { "cpf_cnpj": "11222333000181", "nota": { "identificacao": { "tipo_emitente": 1, "uf_inicio": "MG", "uf_fim": "SP", "municipios_carregamento": [ { "codigo": "...", "municipio": "..." } ], "percurso": [ { "uf": "GO" } ] }, "emitente": { "...": "..." }, "rodoviario": { "rntrc": "...", "veiculo": { "placa": "...", "...": "..." }, "condutores": [ { "nome": "...", "cpf": "..." } ] }, "descarregamento": [ { "codigo": "3550308", "municipio": "SAO PAULO", "cte": [ { "chave": "..." } ] } ], "produto_predominante": { "...": "..." }, "totais": { "...": "..." } } } ``` Cada seção abaixo é um desses blocos. A coluna **Vira** é o nome do campo no layout oficial, útil quando o fisco devolve uma rejeição citando o nome dele. > **DICA — Um campo pode aceitar mais de um nome** > 19 campos aceitam nomes alternativos. Quando existem, aparecem como *"também:"* na > primeira coluna — qualquer um funciona. > **ATENÇÃO — Campo com nome errado não dá erro** > O conversor repassa chave desconhecida como veio, e o emissor a ignora: um `vlrProd` no lugar de > `vProd` gera uma nota **válida** com o produto valendo R$ 0,00. > > Antes da primeira emissão, passe o seu payload em > [`POST /v1/nfe/verificar-campos`](/docs/documentos/nfe/emitir) — ele aponta o campo desconhecido e > sugere o certo, sem emitir e sem consumir cota. ## `nota.ide` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `codigo_uf`
_também:_ `uf` | `cUF` | `string` | | `11` `12` `13` `14` `15` `16` `17` `21` `22` `23` `24` `25` … | | | `tipo_emitente` | `tpEmit` | `string` | | `1` `2` `3` | Tipo do Emitente | | `modelo` | `mod` | `string` | | `58` | Modelo do Manifesto Eletrônico | | `serie` | `serie` | `string` | 3 | | | | `numero` | `nMDF` | `string` | | | Número do Manifesto | | `codigo_mdf` | `cMDF` | `string` | | | Código numérico que compõe a Chave de Acesso. | | `modal` | `modal` | `string` | | `1` `2` `3` `4` | Modalidade de transporte | | `data_emissao` | `dhEmi` | `string` | | | Data e hora de emissão do Manifesto | | `tipo_emissao` | `tpEmis` | `string` | | `1` `2` `3` | Forma de emissão do Manifesto | | `processo_emissao` | `procEmi` | `TProcEmi` | | `0` `4` | Identificação do processo de emissão do Manifesto | | `versao_processo` | `verProc` | `TString` | 20 | | Versão do processo de emissão | | `uf_inicio` | `UFIni` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | Sigla da UF do Carregamento | | `uf_fim` | `UFFim` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | Sigla da UF do Descarregamento | | `data_inicio_viagem` | `dhIniViagem` | `string` | | | Data e hora previstos de inicio da viagem | | `tipo_transportador` | `tpTransp` | `string` | | `1` `2` `3` | Tipo do Transportador | | `canal_verde` | `indCanalVerde` | `string` | | `1` | Indicador de participação do Canal Verde | | `carregamento_posterior` | `indCarregaPosterior` | `string` | | `1` | Indicador de MDF-e com inclusão da Carga posterior a emissão por evento de inclusão de DF-e | ## `nota.municipios_carregamento[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `codigo`
_também:_ `codigo_municipio` | `cMunCarrega` | `string` | | | Código do Município de Carregamento | | `municipio`
_também:_ `nome` | `xMunCarrega` | `TString` | 60 | | Nome do Município de Carregamento | ## `nota.percurso[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `uf`
_também:_ `valor` | `UFPer` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | Sigla das Unidades da Federação do percurso do veículo. | ## `nota.emitente` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj`
_também:_ `cnpj_cpf` | `CNPJ` | `string` | | | CNPJ do emitente | | `inscricao_estadual`
_também:_ `ie` | `IE` | `TIe` | | | Inscrição Estadual do emitemte | | `razao_social`
_também:_ `nome` | `xNome` | `TString` | 60 | | Razão social ou Nome do emitente | | `nome_fantasia`
_também:_ `fantasia` | `xFant` | `TString` | 60 | | Nome fantasia do emitente | | `logradouro` | `xLgr` | `TString` | 60 | | Logradouro | | `numero` | `nro` | `TString` | 60 | | Número | | `complemento` | `xCpl` | `TString` | 60 | | Complemento | | `bairro` | `xBairro` | `TString` | 60 | | Bairro | | `codigo_municipio` | `cMun` | `string` | | | | | `municipio` | `xMun` | `TString` | 60 | | | | `cep` | `CEP` | `string` | | | | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | UF do Emitente | | `telefone` | `fone` | `string` | | | | | `email` | `email` | `string` | 60 | | | ## `nota.Rodo` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `agencia_porto` | `codAgPorto` | `TString` | 16 | | Código de Agendamento no porto | ## `nota.veiculo` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `codigo_interno`
_também:_ `cInt`, `codigo` | `clInt` | | | | _campo do emissor, sem descrição no layout_ | | `placa` | `placa` | `TPlaca` | | | Placa do veículo | | `renavam`
_também:_ `renavan` | `RENAVAN` | | | | _campo do emissor, sem descrição no layout_ | | `tara` | `tara` | `string` | | | Tara em KG | | `capacidade_kg` | `capKG` | `string` | | | Capacidade em KG | | `capacidade_m3` | `capM3` | `string` | | | Capacidade em M3 | | `tipo_rodado` | `tpRod` | `string` | | `01` `02` `03` `04` `05` `06` | Tipo de Rodado | | `tipo_carroceria` | `tpCar` | `string` | | `00` `01` `02` `03` `04` `05` | Tipo de Carroceria | | `uf` | `UF` | `string` | | `AC` `AL` `AM` `AP` `BA` `CE` `DF` `ES` `GO` `MA` `MG` `MS` … | | | `cnpj`
_também:_ `cnpj_cpf`, `cpf` | `CNPJCPF` | | | | _campo do emissor, sem descrição no layout_ | | `rntrc` | `RNTRC` | `TString` | | | | | `proprietario` | `xNome` | `TString` | 60 | | | | `inscricao_estadual` | `IE` | `TIe` | | | | | `uf_proprietario` | `UFProp` | | | | _campo do emissor, sem descrição no layout_ | | `tipo_proprietario` | `tpProp` | `string` | | `0` `1` `2` | Tipo Proprietário ou possuidor | ## `nota.condutores[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cpf`
_também:_ `documento` | `CPF` | `string` | | | | | `nome` | `xNome` | `TString` | 60 | | | ## `nota.prodPred` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `tipo_carga` | `tpCarga` | `string` | | `01` `02` `03` `04` `05` `06` `07` `08` `09` `10` `11` `12` | Tipo de Carga | | `descricao`
_também:_ `produto` | `xProd` | `TString` | 120 | | Descrição do produto | | `ean` | `cEAN` | `string` | | | GTIN (Global Trade Item Number) do produto, antigo código EAN ou código de barras | | `ncm` | `NCM` | `string` | | | Código NCM | ## `nota.local_carregamento` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cep` | `CEP` | `string` | | | | | `latitude` | `latitude` | `TString` | | | | | `longitude` | `longitude` | `TString` | | | | ## `nota.local_descarregamento` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cep` | `CEP` | `string` | | | | | `latitude` | `latitude` | `TString` | | | | | `longitude` | `longitude` | `TString` | | | | ## `nota.totais` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `quantidade_cte` | `qCTe` | `string` | | | Quantidade total de CT-e relacionados no Manifesto | | `quantidade_nfe` | `qNFe` | `string` | | | Quantidade total de NF-e relacionadas no Manifesto | | `quantidade_mdfe` | `qMDFe` | `string` | | | Quantidade total de MDF-e relacionados no Manifesto Aquaviário | | `valor_carga` | `vCarga` | `string` | | | Valor total da carga / mercadorias transportadas | | `quantidade_carga` | `qCarga` | `string` | | | Peso Bruto Total da Carga / Mercadorias transportadas | | `unidade` | `cUnid` | `string` | | `01` `02` | Código da unidade de medida do Peso Bruto da Carga / Mercadorias transportadas | ## `nota.lacres[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `numero`
_também:_ `lacre`, `valor` | `nLacre` | `TString` | 60 | | número do lacre | ## `nota.informacoes_adicionais` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `informacao_fisco` | `infAdFisco` | `TString` | 2000 | | Informações adicionais de interesse do Fisco | | `informacoes_complementares`
_também:_ `observacoes` | `infCpl` | `TString` | 5000 | | Informações complementares de interesse do Contribuinte | ## `nota.responsavel_tecnico` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `cnpj` | `CNPJ` | `string` | | | | | `contato` | `xContato` | `TString` | 60 | | Nome da pessoa a ser contatada | | `email` | `email` | `string` | 60 | | | | `telefone` | `fone` | `string` | | | | ## `nota.vale_pedagio` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `categoria` | `categCombVeic` | `string` | | `02` `04` `06` `07` `08` `10` `11` `12` `13` `14` | Categoria de Combinação Veicular | ## `nota.null` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `codigo`
_também:_ `codigo_municipio` | `cMunDescarga` | `string` | | | Código do Município de Descarregamento | | `municipio`
_também:_ `nome` | `xMunDescarga` | `TString` | 60 | | Nome do Município de Descarregamento | ## `nota.cte[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `chave`
_também:_ `chave_acesso` | `chCTe` | `string` | 44 | | Conhecimento Eletrônico - Chave de Acesso | | `codigo_barras` | `SegCodBarra` | `string` | | | Segundo código de barras | | `reentrega` | `indReentrega` | `string` | | `1` | Indicador de Reentrega | | `prestacao_parcial` | `indPrestacaoParcial` | `string` | | `1` | Indicador de Prestação parcial | ## `nota.nfe[]` | Campo | Vira | Tipo | Tam. | Valores | O que é | |---|---|---|---|---|---| | `chave`
_também:_ `chave_acesso` | `chNFe` | `string` | 44 | | | | `codigo_barras` | `SegCodBarra` | `string` | | | Segundo código de barras | | `reentrega` | `indReentrega` | `string` | | `1` | Indicador de Reentrega | ## Grupos que passam direto Em 3 grupos o campo vai para o layout com o mesmo nome, sem tradução: `null` · `null` · `infANTT` São os grupos da Reforma Tributária e do ISSQN. Use os nomes do layout oficial. ## O que esta página não cobre Ela lista **quais campos existem e o que cada um aceita**. Ela não diz **quando** cada grupo é exigido — isso depende de UF, município, regime tributário e da operação, e está nos guias de emissão. Um payload que passa por esta referência ainda pode ser rejeitado por regra fiscal. ============================================================================== # https://docs.conota.dev/docs/consultas/ncm ============================================================================== # Consulta de NCM Quem cadastra produto sabe o que o produto **é**. Não sabe o número de oito dígitos. Essas três rotas cobrem os dois sentidos dessa tradução — da descrição para o código, e do código de volta para a descrição oficial: | Rota | Para quê | |---|---| | `POST /v1/ncm/buscar` | você tem a **descrição** e quer o código | | `GET /v1/ncm/{codigo}` | você tem o **código** e quer saber o que ele significa | | `GET /v1/ncm/{codigo}/validar` | o código **ainda existe** na tabela vigente? | Os dados vêm da tabela oficial publicada pelo governo, com a descrição, a vigência e o ato normativo de cada código. ## Buscar pela descrição ```bash curl -s https://api.conota.dev/v1/ncm/buscar \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{"descricao": "parafuso"}' ``` ```json { "sucesso": true, "termo": "parafuso", "total": 8, "ncms": [ { "codigo": "73181400", "descricao": "Parafusos autoperfurantes", "inicio_vigencia": "01/04/2022", "fim_vigencia": "31/12/9999", "ato": "Res Gecex", "numero_ato": "272", "ano_ato": "2021" } ] } ``` ### Como o termo casa O texto é procurado em **qualquer posição** da descrição oficial. Por isso `autoperfurantes` encontra *Parafusos autoperfurantes*, mesmo sendo a segunda palavra. Mas a busca é **literal**: não entende sinônimo, plural nem frase. | Envie | Não envie | |---|---| | `parafuso` | `parafuso de aço inox 3/8` | | `amendoim` | `amendoins torrados` | Uma palavra, no singular, escrita como o texto oficial escreveria. Se não vier resultado, tente **outra palavra do mesmo produto** antes de concluir que ele não tem NCM. ### Só códigos de oito dígitos A tabela oficial também traz os níveis intermediários da árvore — `73` é um capítulo, `7318` é uma posição. **Nenhum dos dois vale numa nota**: o campo `NCM` exige o código final de oito dígitos, e mandar `7318` rende rejeição. Por isso a resposta traz **apenas os códigos de oito dígitos** por padrão. Para enxergar a árvore inteira — útil para explorar, nunca para emitir — envie: ```json { "descricao": "parafuso", "apenas_codigos_finais": false } ``` ### Restringir ao começo da descrição Quando a busca ampla traz resultado demais, `so_inicio` exige que a descrição **comece** com o termo: ```json { "descricao": "parafuso", "so_inicio": true } ``` É mais preciso e acha menos. `autoperfurantes` com `so_inicio: true` não acha nada. ### Busca sem resultado não é erro Termo que não existe na tabela devolve **`200`** com a lista vazia: ```json { "sucesso": true, "termo": "zzzqqq", "total": 0, "ncms": [] } ``` Trate `total: 0` como "não achei com essa palavra", não como falha. ## Consultar um código ```bash curl -s https://api.conota.dev/v1/ncm/73181400 \ -H "Authorization: Bearer SUA_CHAVE" ``` Código inexistente devolve **404** com `encontrado: false`. ## Validar um código ```bash curl -s https://api.conota.dev/v1/ncm/73181400/validar \ -H "Authorization: Bearer SUA_CHAVE" ``` ```json { "sucesso": true, "valido": true } ``` Vale para conferir cadastro antigo antes de emitir: NCM **sai de vigência** por ato normativo, e um código que funcionava no ano passado pode não existir mais. > **DICA — Onde isso rende mais** > Rodar a validação sobre o catálogo inteiro, uma vez, encontra os produtos que vão levar > rejeição — antes de a rejeição acontecer no cliente. ## Cota e desempenho As três rotas consomem cota de `ncm`, na mesma família de [CEP e CNPJ](/docs/conceitos/limites). A cota existe para haver controle, não para limitar uso legítimo. A tabela fica em cache no Conota. A primeira consulta depois de uma renovação pode demorar um pouco mais; as seguintes respondem na hora. ## Pelo MCP As mesmas consultas existem como ferramentas de MCP — `buscar_ncm_por_descricao`, `consultar_ncm` e `validar_ncm`. É onde a busca por descrição rende mais: perguntar *"qual o NCM de um parafuso de aço"* é o uso natural de um assistente. Ver [MCP](/docs/mcp/introducao). ============================================================================== # https://docs.conota.dev/docs/captura/visao-geral ============================================================================== # Notas recebidas A **captura** baixa, das fontes oficiais, as notas que fornecedores emitem **contra** as suas empresas — as notas de entrada. Você consulta tudo pela API, pelo painel ou pelo MCP, baixa o XML e pode receber um aviso por webhook quando chega uma nota nova. | Documento | Fonte | Histórico disponível ao ligar | |---|---|---| | **NF-e** (modelo 55) | SEFAZ — Ambiente Nacional (distribuição de DF-e) | cerca de 3 meses | | **NFS-e** | ADN — Ambiente de Dados Nacional da NFS-e | todo o histórico que a fonte guarda | ## O que entra e o que não entra **Entra** toda nota em que a empresa figura como **tomadora** (NFS-e), **destinatária** (NF-e) ou **intermediária**. **Não entra**: - **as notas que a própria empresa emitiu.** A fonte as entrega junto, e nós as separamos — a lista de notas recebidas nunca mistura entrada com saída; - **NFC-e** — a SEFAZ não distribui a nota de consumidor ao comprador; - **NFS-e de município que não compartilha com o ADN.** O ADN recebe as notas do padrão nacional e as que os municípios enviam a ele. Uma nota emitida num sistema municipal que não compartilha **pode não aparecer** — não é falha da captura, é a cobertura da fonte. > **INFO — NF-e: o resumo chega antes da nota inteira** > A SEFAZ entrega ao destinatário, primeiro, um **resumo** da NF-e (emitente, valor, data, situação). > O XML completo é liberado depois que a empresa registra a **Ciência da Operação**. O registro > automático da Ciência entra em operação numa próxima etapa; até lá, as NF-e recebidas aparecem, em > geral, como resumo — `xml_integral: false`. ## Como ligar 1. **Plano.** A captura é incluída por plano, separadamente para NF-e e NFS-e. Fale com o suporte para incluir. 2. **Certificado.** A empresa precisa de certificado A1 ativo e válido — é com ele que a captura se identifica na fonte. Veja [Certificado digital](/docs/conceitos/certificado). 3. **Ligar por empresa**, no painel (página da empresa) ou pela API, com uma **chave de produção**: a captura lê as notas reais, não existe captura em homologação. A partir daí, o histórico disponível é baixado, e a captura passa a consultar as fontes periodicamente. Detalhes em [Ligar e consultar](/docs/captura/ligar-e-consultar). ## Onde está cada coisa | | | |---|---| | Ligar, desligar, consultar, baixar o XML | [Ligar e consultar](/docs/captura/ligar-e-consultar) | | Aviso quando chega uma nota | [Webhook das notas recebidas](/docs/captura/webhook) | | Todos os campos e respostas | [Referência da API da captura](https://api.conota.dev/v1/captura/docs) | | Agentes de IA | As ferramentas `estado_da_captura`, `listar_notas_recebidas`, `xml_da_nota_recebida` e `ligar_ou_desligar_captura`, no [MCP](/docs/mcp/introducao) | > **NOTA — Webhook e chave não estão no MCP** > A configuração do webhook devolve a chave de assinatura da conta, e ela acabaria no histórico da > conversa do agente. Por isso ela é feita só no painel ou pela API. ============================================================================== # https://docs.conota.dev/docs/captura/ligar-e-consultar ============================================================================== # Ligar e consultar A captura é ligada **por empresa** e **por tipo**. Todas as rotas usam a mesma autenticação do resto da API (`X-API-Key`). Os campos completos estão na [referência da API da captura](https://api.conota.dev/v1/captura/docs). ## Ligar e desligar ```bash curl -X PUT https://api.conota.dev/v1/captura \ -H "X-API-Key: $CONOTA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "cpf_cnpj": "11222333000181", "nfse": true }' ``` - Envie `nfe` e/ou `nfse`, com `true` para ligar e `false` para desligar. Um pedido com os dois muda os dois ou nenhum. - Exige **chave de produção** — a resposta é `403` com chave de homologação. - Ligar exige o tipo no plano (`403`) e certificado A1 ativo e válido (`422`). - Desligar para de buscar notas novas. **O que já foi capturado continua disponível.** Religar continua de onde parou. > **ATENÇÃO — Ligar a NF-e é um aceite em nome da empresa** > Para ligar a NF-e, envie também `"aceite_ciencia_da_operacao": true`. Sem ele, a resposta é `422`. > > Com o aceite, a captura fica autorizada a registrar na SEFAZ, em nome da empresa, a **Ciência da > Operação** (evento 210210) de cada NF-e recebida — é o que libera o XML completo. A Ciência só > informa que a empresa tomou conhecimento da nota: **não confirma a operação**. Confirmar, > desconhecer ou recusar continua sendo decisão da empresa. ## Acompanhar `GET /v1/captura?cpf_cnpj=11222333000181` devolve, por tipo, se está incluída no plano, ligada e em que `situacao`: | `situacao` | O que fazer | |---|---| | `sincronizando` | Nada: o histórico está sendo baixado, logo depois de ligar. | | `em_dia` | Nada: a captura consulta a fonte periodicamente. | | `aguardando_limite_de_consumo` | Nada: a fonte impôs uma espera (ex.: rejeição 656 da SEFAZ). A captura retoma sozinha. | | `com_erro` | Ler o campo `erro` — por exemplo, certificado vencido — e corrigir. | | `desligada` / `nao_incluida_no_plano` | Ligar, ou incluir no plano. | A mesma resposta mostra o webhook configurado para a empresa. > **DICA — Notas novas não aparecem na hora** > Quando não há nada novo, a captura espera cerca de uma hora antes da próxima consulta — é a regra das > fontes, e consultar antes gera bloqueio temporário. Uma nota emitida agora contra a sua empresa > aparece na próxima consulta, não imediatamente. ## Listar as notas recebidas ```bash curl "https://api.conota.dev/v1/captura/notas?cpf_cnpj=11222333000181&tipo=nfse&desde=2026-09-01" \ -H "X-API-Key: $CONOTA_API_KEY" ``` - Filtros: `tipo` (`nfe` | `nfse`), `desde` e `ate` (data de emissão, `AAAA-MM-DD`, no fuso de Brasília), `situacao`, `pagina` e `limite` (até 200). - Cada nota traz `papel` (`tomador`, `destinatario`, `intermediario`), o emissor, o valor e a situação. - `situacao` vem como a fonte informou. Um código que ainda não interpretamos aparece **cru** — por exemplo `cstat-107` — e nunca como `autorizada`. Não trate código desconhecido como nota válida. ## Baixar o XML ```bash curl "https://api.conota.dev/v1/captura/notas/xml?chave=&cpf_cnpj=11222333000181" \ -H "X-API-Key: $CONOTA_API_KEY" -o nota.xml ``` - A chave de acesso tem 44 dígitos na NF-e e 50 na NFS-e. - O header `X-Conota-Documento` diz se veio a nota `integral` ou só o `resumo`. - Informe `cpf_cnpj`: se a mesma nota aparecer em duas empresas da conta (uma nota entre elas, por exemplo), sem ele a resposta é `409`. - O XML só sai pela rota autenticada — não há link público. ============================================================================== # https://docs.conota.dev/docs/captura/webhook ============================================================================== # Webhook das notas recebidas O webhook avisa sua aplicação quando a captura encontra uma **nota recebida nova** ou quando uma nota recebida é **cancelada**. > **IMPORTANTE — Não é o mesmo contrato do webhook de emissão** > Headers, chave e assinatura são **diferentes** dos do [webhook de emissão](/docs/conceitos/webhooks). > Código escrito para o webhook de emissão **não confere** estes avisos. > > | | Emissão | Notas recebidas | > |---|---|---| > | Onde se configura | `webhook_url` em cada emissão | uma vez, **por empresa** | > | Headers | `X-Qualyfiscal-*` | `X-Conota-*` | > | O que é assinado | o corpo | **`.`** | > | Chave | fornecida pelo Conota | **uma por conta**, gerada por você no painel ou pela API | > | Tentativas | 3 | 8, ao longo de ~22 h | ## Configurar O endereço precisa estar cadastrado antes, no painel, em **Integração → Destinos de webhook**, no ambiente **produção**. Depois, ligue para a empresa: ```bash curl -X PUT https://api.conota.dev/v1/captura/webhook \ -H "X-API-Key: $CONOTA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "cpf_cnpj": "11222333000181", "url": "https://seu-sistema.com.br/conota/notas-recebidas" }' ``` - Endereço fora dos destinos autorizados de produção: `422`. - Valem as mesmas exigências de endereço do webhook de emissão: `https://` na porta 443, endereço público, nome de host, sem redirecionamento. - `"ativo": false` desliga. Na **primeira** configuração da conta, a resposta traz a chave de assinatura: ```json { "cpf_cnpj": "11222333000181", "webhook": { "url": "https://seu-sistema.com.br/conota/notas-recebidas", "ativo": true }, "chave_de_assinatura": { "valor": "csec_...", "criada_em": "2026-09-25T19:40:00.000Z" } } ``` > **ATENÇÃO — A chave aparece uma única vez** > Guarde-a num gerenciador de segredos. Ela assina os avisos de **todas** as empresas da conta. Se > perder, gere outra com `POST /v1/captura/webhook/segredo` — a troca vale na hora, então atualize seu > sistema logo em seguida. ## Quando chega um aviso | Evento | Quando | |---|---| | `nota_recebida` | a captura encontrou uma nota recebida **nova** | | `nota_recebida_cancelada` | uma nota recebida foi cancelada pelo emissor | **Não geram aviso**: o histórico baixado ao ligar a captura, as notas que a própria empresa emitiu e tudo que chegar enquanto o webhook estiver desligado. ```http POST /conota/notas-recebidas Content-Type: application/json X-Conota-Evento: nota_recebida X-Conota-Entrega: 5b0f3c1e-0000-4000-8000-000000000000 X-Conota-Tentativa: 1 X-Conota-Timestamp: 1790364130 X-Conota-Signature: sha256= ``` ```json { "evento": "nota_recebida", "entrega_id": "5b0f3c1e-0000-4000-8000-000000000000", "ocorrido_em": "2026-09-25T19:22:10.000Z", "empresa": { "cpf_cnpj": "11222333000181" }, "nota": { "tipo": "nfse", "chave": "35503081299888777000166000000000012326081234567895", "papel": "tomador", "numero": "123", "emissor": { "cpf_cnpj": "99888777000166", "nome": "PRESTADORA EXEMPLO LTDA" }, "valor": 1500, "data_emissao": "2026-09-20T13:00:00.000Z", "situacao": "autorizada", "municipio_incidencia": "3550308", "xml_integral": true }, "xml_url": "https://api.conota.dev/v1/captura/notas/xml?chave=35503081299888777000166000000000012326081234567895&cpf_cnpj=11222333000181" } ``` O XML não vem no aviso: `xml_url` aponta para a rota autenticada, com a sua chave de API. ## Conferir a assinatura ```js const crypto = require('crypto') // corpoBruto: o body EXATAMENTE como chegou, antes do JSON.parse function avisoValido(corpoBruto, headers, chave) { const ts = headers['x-conota-timestamp'] // Aviso com mais de 5 minutos pode ser um reenvio capturado no caminho. if (!ts || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false const esperado = 'sha256=' + crypto .createHmac('sha256', chave) .update(`${ts}.${corpoBruto}`) .digest('hex') const a = Buffer.from(esperado) const b = Buffer.from(headers['x-conota-signature'] || '') return a.length === b.length && crypto.timingSafeEqual(a, b) } ``` > **ATENÇÃO — Use o corpo BRUTO** > `JSON.parse` seguido de `JSON.stringify` pode mudar a ordem e o espaçamento — e a assinatura deixa de > bater. Guarde o body cru antes do parse. ## Entrega e repetição - Responda **2xx**, rápido. Sem 2xx, tentamos de novo em 1 min, 5 min, 15 min, 1 h, 3 h, 6 h e 12 h — 8 tentativas ao todo. - O mesmo aviso pode chegar mais de uma vez. **Use `X-Conota-Entrega`** (igual a `entrega_id`) para descartar o que já processou. - Os avisos pendentes vão para o endereço configurado **na hora da entrega**: se você trocar o endereço, eles seguem para o novo; se desligar o webhook ou tirar o destino da lista de autorizados, deixam de ser enviados. > **IMPORTANTE — Webhook não substitui consulta** > Se o seu endpoint ficar fora do ar durante todas as tentativas, o aviso se perde. Mantenha uma rotina > que consulte `GET /v1/captura/notas` com `desde` e compare com o que você já tem. Webhook é o caminho > rápido; a consulta é a rede de segurança. ============================================================================== # https://docs.conota.dev/docs/connect/visao-geral ============================================================================== # Conota Connect Conectar a sua plataforma de venda ou cobrança ao Conota, para que a nota saia sozinha quando o pedido é pago. ## O que está disponível hoje > **INFO — Esta página descreve o que já funciona — não um roadmap** > Integrações nativas estão em construção. Enquanto elas não chegam, o caminho disponível é o > **n8n**, e ele não é um paliativo: é uma automação de verdade, que roda em produção e que você > controla. | Caminho | Estado | Quando usar | |---|---|---| | **[n8n](/docs/connect/n8n)** | **disponível** | qualquer plataforma; o caminho mais rápido hoje | | **API REST direta** | **disponível** | você tem time técnico e volume alto | | Conectores nativos | em construção | quando chegarem, para as plataformas cobertas | ## Como escolher ```text Sua plataforma tem nó no n8n? │ ├── sim → n8n. Fluxo pronto em horas, sem escrever código. │ └── não → tem API ou webhook? │ ├── sim → n8n com nó HTTP Request │ └── não → integração direta pela nossa API, a partir do seu sistema ``` ## O que qualquer integração precisa resolver Independente do caminho, quatro coisas decidem se a integração funciona em produção ou dá dor de cabeça no fechamento do mês. Elas valem para n8n, para código próprio e para qualquer conector. ### 1. Não emitir duas vezes Todo gatilho pode disparar duas vezes — reenvio da plataforma, reexecução do fluxo, clique duplicado. Mande uma **`referencia_externa`** derivada de algo que já existe do seu lado (o número do pedido, o id da cobrança). Reenviar a mesma referência devolve o job existente em vez de emitir de novo. Ver [Referência externa e idempotência](/docs/conceitos/referencia-externa). ### 2. Saber de onde vêm os dados fiscais A plataforma de venda sabe **preço, cliente e quantidade**. Ela não sabe **NCM, CFOP nem CST**. > **ATENÇÃO — É aqui que a maioria das integrações trava** > Para **NFS-e**, costuma bastar um serviço fixo — o mesmo em toda emissão. É simples. > > Para **NF-e**, cada produto precisa da sua classificação fiscal. Esses dados precisam vir de algum > lugar: campos personalizados na própria plataforma, uma planilha de/para, ou o cadastro do seu ERP. > **Decida isso antes de montar o fluxo**, não depois. ### 3. Tratar o retorno assíncrono A emissão responde `202` com um `job_id` — aceita, ainda não autorizada. O resultado chega depois, por [webhook](/docs/conceitos/webhooks) ou consulta. Um fluxo que trata `202` como sucesso vai dizer "nota emitida" para uma nota que pode ser rejeitada segundos depois. Ver [Status das emissões](/docs/conceitos/status). ### 4. Separar rejeição de erro técnico **Rejeição fiscal** é o autorizador recusando por uma regra — repetir dá o mesmo resultado, alguém precisa corrigir o dado. **Falha técnica** pode ser repetida. Tratar os dois igual leva ao pior comportamento possível: reenviar em laço uma nota que vai ser recusada de novo. Ver [Erros e rejeições](/docs/conceitos/erros-rejeicoes). ## Próximos passos - [Automação com n8n](/docs/connect/n8n) — o caminho disponível hoje - [Onboarding da integração](/docs/comecando/onboarding) — se for integrar direto - [Referência da API](https://api.conota.dev/docs) — todas as rotas ============================================================================== # https://docs.conota.dev/docs/connect/n8n ============================================================================== # Automação com n8n O [n8n](https://n8n.io) conecta sistemas montando um fluxo com blocos, arrastando na tela. Você não escreve código: liga um bloco no outro. Como a API do Conota é aberta e simples, **um bloco de "requisição HTTP" já emite nota fiscal**. > **DICA — Isto já funciona hoje** > Nada aqui depende de recurso futuro. É a mesma API que já está em produção. ## Por onde começar Faça nesta ordem. Cada página leva poucos minutos. | | Página | O que você faz | |---|---|---| | **1** | **[Criar a credencial](/docs/connect/n8n/credencial)** | guarda sua chave no n8n com segurança — **faça isto primeiro** | | **2** | **[Fluxo de exemplo: consultar CNPJ](/docs/connect/n8n/consultar-cnpj)** | importa um fluxo pronto e vê funcionando | Depois desses dois, você já entendeu o mecanismo inteiro — todo o resto muda só o endereço e os dados enviados. ## Para quem é | Situação | n8n resolve? | |---|---| | Meu sistema não tem integração com o Conota | **sim** — é o caminho mais rápido | | Quero emitir a partir de uma planilha ou de um formulário | **sim** | | Quero avisar o cliente por e-mail ou WhatsApp quando a nota sair | **sim** | | Minha loja é WooCommerce, Shopify, Nuvemshop... | **sim** — o n8n já conversa com elas | | Emito milhares de notas por dia pelo meu sistema | não — [integre direto](/docs/comecando/onboarding) | | Quero perguntar sobre as notas em linguagem natural | não — use o [MCP](/docs/mcp/introducao) | ## Como um fluxo do Conota se parece Todos têm a mesma forma. Muda o que dispara e o que é enviado. ```text 1. Algo acontece (um pedido é pago, uma linha entra na planilha) ↓ 2. Você monta os dados (bloco "Edit Fields") ↓ 3. Chama o Conota (bloco "HTTP Request") ↓ 4. Guarda o resultado (o número do trabalho, para acompanhar depois) ``` ## Três avisos que evitam a maior parte dos problemas Estão detalhados nas páginas seguintes, mas vale ler antes de começar. > **IMPORTANTE — 1. Nunca escreva sua chave dentro de um bloco** > Fluxos do n8n são compartilhados como **arquivo**. Se a chave estiver escrita dentro de um bloco, > ela vai junto — e quem receber o arquivo **consegue emitir nota fiscal em nome da sua empresa**. > > Use sempre a **credencial** do n8n. É o assunto da [primeira página](/docs/connect/n8n/credencial). > **ATENÇÃO — 2. Um fluxo pode rodar duas vezes** > Você clica em "Execute" de novo, o sistema de origem reenvia o aviso, alguém testa. Sem proteção, > cada repetição é **uma nota nova**. > > A proteção é mandar uma `referencia_externa` — explicada em > [Referência externa e idempotência](/docs/conceitos/referencia-externa). > **ATENÇÃO — 3. "Aceito" não é "autorizado"** > Quando você pede uma emissão, o Conota responde na hora que **recebeu** o pedido. A nota ainda vai > ser processada e enviada ao órgão que autoriza — e isso leva alguns segundos. > > Um fluxo que avisa "nota emitida" nesse momento pode estar avisando sobre uma nota que será > recusada. Ver [Status das emissões](/docs/conceitos/status). ## Onde o n8n não é a ferramenta certa | Caminho | Quando | |---|---| | **n8n** | sem código; sua plataforma não tem integração pronta | | **API direta** | volume alto, rotina sempre igual — ver [Onboarding](/docs/comecando/onboarding) | | **[MCP](/docs/mcp/introducao)** | perguntar sobre as notas conversando | ## Próximo passo **[Criar a credencial →](/docs/connect/n8n/credencial)** ============================================================================== # https://docs.conota.dev/docs/connect/n8n/credencial ============================================================================== # Criar a credencial no n8n **Faça isto antes de qualquer fluxo.** Leva dois minutos e é o que separa uma integração segura de uma chave vazada. ## Por que não escrever a chave direto no fluxo O n8n permite digitar a chave dentro de um bloco. **Não faça isso.** > **IMPORTANTE — Sua API Key emite nota fiscal de verdade** > Fluxos do n8n são feitos para serem compartilhados: você exporta um arquivo, manda para o > contador, cola num grupo, salva num repositório, ou pede ajuda mostrando a tela. > > Se a chave estiver escrita dentro de um bloco, **ela vai junto em todas essas situações**. E quem > tiver a sua chave consegue **emitir documento fiscal em nome da sua empresa** — com efeito fiscal > real, que não se desfaz apagando um arquivo. > > Não existe hoje chave "só de consulta": a mesma chave que consulta é a que emite. A **credencial** do n8n resolve isso: a chave é guardada em um cofre separado, e o fluxo só guarda uma referência a ela. Quando você exporta o fluxo, **a chave não vai junto**. ## Antes de começar Você precisa da sua API Key. Ela é gerada no painel: 1. acesse **[console.conota.dev](https://console.conota.dev)**; 2. faça login; 3. vá em **API Keys**; 4. gere uma chave e **copie**. > **ATENÇÃO — Use uma chave de homologação para testar** > Homologação não tem valor fiscal. Enquanto estiver montando e testando fluxos, use ela — e só troque > para a chave de produção quando o fluxo estiver pronto. > > Ver [Ambientes](/docs/comecando/ambientes). ## Passo a passo ### 1. Abra a criação de credencial No n8n, clique no botão do canto superior direito e escolha **Create Credential**. ### 2. Escolha o tipo Na busca **"Select an app or service to connect to"**, digite `header` e escolha: ```text Header Auth ``` > **INFO — Por que "Header Auth"?** > O Conota identifica você por um cabeçalho da requisição, não por usuário e senha. "Header Auth" é > exatamente isso: manda um cabeçalho com um valor fixo em toda chamada. > > Não procure por "Conota" na lista — ainda não temos um bloco próprio no n8n. ### 3. Preencha os dois campos | Campo | O que colocar | |---|---| | **Name** | `X-API-Key` | | **Value** | a sua chave, copiada do painel | > **ATENÇÃO — Atenção ao campo "Name"** > Aqui **Name** não é o nome da credencial — é o nome do **cabeçalho**. Precisa ser exatamente > `X-API-Key`, com os hífens e as maiúsculas nesse formato. > > Se estiver diferente, o Conota não vai reconhecer a chave e você receberá um erro de autenticação. ### 4. Dê um nome que diga o ambiente No topo da tela, onde aparece o nome da credencial, troque para algo como: ```text Conota — homologação ``` E, quando criar a de produção: ```text Conota — PRODUÇÃO ``` > **IMPORTANTE — Isto evita o acidente mais comum** > Com nomes parecidos, é fácil escolher a credencial errada e emitir nota **com valor fiscal real** > achando que era teste. Escrever `PRODUÇÃO` em maiúsculas na hora de escolher faz diferença. ### 5. Salve Clique em **Save**. A credencial passa a aparecer na lista de qualquer bloco de requisição HTTP. ## Como saber se deu certo O jeito mais rápido é usar o fluxo de exemplo da próxima página: ele faz uma consulta simples e mostra o resultado na tela. Se a credencial estiver errada, você verá um erro de autenticação — normalmente `401` com a mensagem `API Key invalida`. ## Se a chave vazar Se você desconfiar que a chave foi exposta — mandou o fluxo com ela dentro, colou numa mensagem, subiu para um repositório: 1. entre em **[console.conota.dev](https://console.conota.dev)**; 2. **revogue** aquela chave; 3. gere uma nova; 4. atualize a credencial no n8n. Revogue primeiro e investigue depois. Ver [Segurança](/docs/operacao/seguranca). ## Próximo passo **[Fluxo de exemplo: consultar CNPJ →](/docs/connect/n8n/consultar-cnpj)** ============================================================================== # https://docs.conota.dev/docs/connect/n8n/consultar-cnpj ============================================================================== # Fluxo de exemplo: consultar CNPJ Um fluxo pronto para importar. Ele consulta os dados de uma empresa pelo CNPJ e mostra o resultado. **Comece por ele.** É a forma mais rápida de confirmar que a sua credencial está certa — e **nenhuma nota fiscal é emitida**, então não há risco de gerar documento por engano. > **INFO — O que este exemplo consome** > A consulta de CNPJ conta na franquia de consultas do seu plano — é barata, mas não é zero. O que > ela **não** faz é emitir documento nem gerar efeito fiscal. ## Antes de começar - [ ] Você já criou a **[credencial](/docs/connect/n8n/credencial)**. Se ainda não criou, faça isso primeiro — o fluxo não vai funcionar sem ela. ## 1. Baixe o fluxo **Baixar `conota-consultar-cnpj.json`** Se o arquivo abrir no navegador em vez de baixar, clique com o botão direito no link e escolha *"Salvar link como..."*. ## 2. Importe no n8n 1. no n8n, abra o menu do canto superior direito; 2. escolha **Import from File...**; 3. selecione o arquivo que você baixou. O fluxo aparece na tela com quatro blocos e duas notas amarelas explicando cada parte. > **DICA — Também dá para colar** > Se preferir, abra o arquivo em um editor de texto, copie todo o conteúdo, clique na tela em branco > do n8n e cole com `Ctrl+V`. O n8n reconhece e monta o fluxo. ## 3. Escolha a sua credencial Este é o único passo que você **precisa** fazer — o fluxo vem sem credencial de propósito. 1. clique no bloco **`CONOTA - Consultar CNPJ`**; 2. procure o campo **Credential for Header Auth**; 3. escolha a credencial que você criou (`Conota — homologação`); 4. feche o bloco. > **ATENÇÃO — O bloco aparece marcado até você fazer isso** > Se o n8n mostrar um aviso vermelho no bloco, é exatamente isso: falta escolher a credencial. Não é > erro do fluxo. ## 4. Execute Clique em **Execute workflow**, no rodapé da tela. Se tudo estiver certo, o bloco fica verde e o resultado aparece do lado direito: ```json { "cnpj": "00000000000191", "dados": { "razao_social": "BANCO DO BRASIL SA", "situacao": "ATIVA", "municipio": "BRASILIA", "uf": "DF" }, "sucesso": true } ``` > **DICA — Deu certo?** > Então sua credencial está correta e o n8n consegue falar com o Conota. **Todo o resto é variação > disto** — muda o endereço chamado e os dados enviados. ## O que cada bloco faz | Bloco | Para quê | |---|---| | **When clicking 'Execute workflow'** | dispara o teste quando você clica. Num fluxo de verdade, vira um **Webhook** — quem dispara é a sua loja ou o seu sistema | | **CNPJexemplo** | define o CNPJ que será consultado. É aqui que, num fluxo real, chegariam os dados de fora | | **CONOTA - Consultar CNPJ** | faz a chamada à API do Conota, usando a sua credencial | ## Trocar o CNPJ consultado 1. clique no bloco **`CNPJexemplo`**; 2. troque o número dentro de `"CNPJexemplo"`; 3. execute de novo. > **IMPORTANTE — Aqui vai **sem a barra**** > O CNPJ entra no **endereço** da chamada. A barra da máscara é separador de endereço: mandando > `00.000.000/0001-91`, a URL vira `/v1/cnpj/00.000.000/0001-91` e você recebe **404 — rota não > encontrada**. > > | O que digitar | Funciona? | > |---|---| > | `00000000000191` | ✅ use este | > | `00.000.000/0001-91` | ❌ 404 — a barra quebra o endereço | > | `00.000.0000001-91` | ✅ ponto e hífen passam; só a barra não | > > Em **CPF** a máscara completa funciona (`125.244.567-90`), porque CPF não tem barra. > > O formato novo de CNPJ, com letras, é aceito — ver > [Atualizações fiscais](/docs/atualizacoes/fiscal). ## Se algo deu errado | O que aparece | O que é | O que fazer | |---|---|---| | `401` · `API Key invalida` | a chave está errada, ou o cabeçalho não é `X-API-Key` | confira os dois campos na [credencial](/docs/connect/n8n/credencial) | | Aviso vermelho no bloco | falta escolher a credencial | passo 3 acima | | `429` | a franquia de consultas do plano acabou | veja o consumo em [console.conota.dev](https://console.conota.dev) | | `400` · CNPJ inválido | o número não tem 14 posições | confira o valor no bloco `CNPJexemplo` | A lista completa de comportamentos está em [Erros e rejeições](/docs/conceitos/erros-rejeicoes). ## E agora? Este fluxo é o "olá mundo" da integração. O próximo passo natural é **emitir**, e aí valem os cuidados que uma consulta não exige: - mandar uma **`referencia_externa`** para o fluxo não emitir duas vezes ao ser reexecutado — ver [Referência externa e idempotência](/docs/conceitos/referencia-externa); - entender que a resposta é **assíncrona**: o Conota confirma que recebeu, e o resultado chega depois — ver [Sua primeira emissão](/docs/comecando/primeira-emissao); - decidir **de onde vêm os dados fiscais** dos produtos (NCM, CFOP, CST), que a sua loja provavelmente não tem — ver [Conota Connect](/docs/connect/visao-geral). > **NOTA — Mais exemplos em breve** > Estamos publicando outros fluxos prontos: emitir NFS-e, emitir NF-e a partir de um pedido, receber > o retorno da emissão e tratar rejeição. ============================================================================== # https://docs.conota.dev/docs/mcp/introducao ============================================================================== # Conota MCP A API REST é a melhor opção quando o seu software **já sabe** qual operação precisa executar: emitir uma nota, consultar um documento, baixar um arquivo, listar registros. O **Conota MCP** acrescenta outra forma de integração: um assistente ou agente de IA **descobre** as ferramentas fiscais disponíveis e escolhe quais consultas executar a partir da intenção da pessoa. Em vez de navegar por telas e filtros, o usuário pergunta: > Quanto emitimos ontem? > Quais notas foram rejeitadas esta semana? > Qual item provocou a rejeição dessa nota? > Nossos certificados estão próximos do vencimento? O cliente de IA interpreta a solicitação, seleciona as ferramentas do servidor MCP do Conota e combina os resultados para responder. ## Endpoint ```text https://mcp.conota.dev/mcp ``` O catálogo das ferramentas realmente publicadas fica em **[mcp.conota.dev](https://mcp.conota.dev)** — gerado a partir do próprio servidor, então nunca diverge da implementação. ## A mesma conta, outra interface O MCP **não cria um universo fiscal separado**. Ele é uma camada fina sobre a mesma API REST: cada ferramenta chama a API com a sua API Key. Isso significa que o isolamento entre contas, as cotas, a validação e os logs são exatamente os mesmos. ```text Aplicação tradicional Assistente / agente │ │ ▼ ▼ API REST MCP │ │ └──────────── Conota ───────────┘ │ ▼ Infraestrutura fiscal ``` ## O que ele faz hoje As ferramentas cobrem consultas de cadastro, localização de emissões, relatórios por período, download de arquivos e **emissão com confirmação humana em dois passos**. > **ATENÇÃO — Emissão nunca é silenciosa** > Um agente não emite sozinho. O fluxo separa **preparar** de **confirmar**, e a confirmação exige > aprovação explícita de uma pessoa. Ver [Segurança no MCP](/docs/mcp/seguranca). ## Não existe MCP administrativo A credencial resolve **uma conta**. Não há visão cruzada entre clientes: consultar os dados de um cliente pelo MCP exige a chave dele. ## Próximos passos - [Quando usar MCP ou REST](/docs/mcp/mcp-vs-rest) - [Conectar ao MCP](/docs/mcp/conectar) - [Segurança e confirmação humana](/docs/mcp/seguranca) - [Exemplos de uso](/docs/mcp/exemplos) ============================================================================== # https://docs.conota.dev/docs/mcp/mcp-vs-rest ============================================================================== # Quando usar MCP ou API REST MCP e REST **não são concorrentes**. Resolvem problemas diferentes e costumam coexistir na mesma solução. | Situação | REST | MCP | |---|---|---| | Backend emitindo milhares de notas automaticamente | **Ideal** | Não recomendado | | ERP consultando status por `job_id` | **Ideal** | Possível, mas desnecessário | | Pessoa perguntando "quanto emiti este mês?" | Exige interface própria | **Ideal** | | Analista investigando rejeições em conversa | Exige implementação específica | **Ideal** | | Rotina transacional determinística | **Ideal** | Complementar | | Assistente fiscal interno | Complementar | **Ideal** | | Integração servidor a servidor | **Ideal** | Complementar | ## A regra prática **REST** quando o seu código já sabe exatamente qual operação executar. **MCP** quando um agente precisa **descobrir** quais ferramentas usar para atender uma intenção humana. ## Por que não usar MCP para volume Um agente escolhe ferramentas por inferência. Isso é excelente para responder perguntas variadas e péssimo para um laço que emite 5.000 notas: cada decisão custa tempo, é não determinística e consome cota igual. Volume quer previsibilidade, e previsibilidade é exatamente o que a API REST oferece. ## Por que não construir tela para tudo O caminho inverso também é ruim. Cada nova pergunta do time — "quais produtos aparecem nas rejeições da semana?" — viraria um filtro, um relatório, um deploy. Com MCP, a pergunta é feita e respondida sem que ninguém escreva código. > **INFO — Os dois usam a mesma cota** > As consultas do assistente contam na cota do plano, igual às chamadas REST. Não existe cota > separada de IA. ============================================================================== # https://docs.conota.dev/docs/mcp/conectar ============================================================================== # Conectar ao Conota MCP O servidor usa **Streamable HTTP**. ```text URL: https://mcp.conota.dev/mcp Autenticação: X-API-Key ``` Use a **mesma API Key** da sua conta Conota. ## Claude Code ```bash claude mcp add --transport http conota https://mcp.conota.dev/mcp \ --header "X-API-Key: SUA_CHAVE_AQUI" ``` ## Codex ```toml [mcp_servers.conota] url = "https://mcp.conota.dev/mcp" enabled = true [mcp_servers.conota.http_headers] X-API-Key = "SUA_CHAVE_AQUI" ``` ## Outros clientes Qualquer cliente compatível com MCP sobre HTTP funciona, desde que permita configurar a URL e um header de autenticação. O `Authorization: Bearer SUA_CHAVE` também é aceito, para clientes que só oferecem esse campo. > **IMPORTANTE — Não versione a chave** > Arquivos de configuração de cliente MCP costumam ir para o Git junto com o resto do projeto. Quando > o cliente suportar variável de ambiente ou secret store, use — e confira o `.gitignore` antes do > primeiro commit. ## Conferindo a conexão Depois de conectar, peça algo simples ao assistente: > Liste as empresas emissoras da minha conta. Se vier a lista, a chave está válida e o transporte funcionando. ## Ferramenta nova exige reconectar O cliente guarda o catálogo obtido **no momento da conexão**. Quando publicamos uma ferramenta nova, reconecte para enxergá-la — o catálogo atual está sempre em [mcp.conota.dev](https://mcp.conota.dev). ## Erros chegam como texto Se a cota acabar ou a chave for inválida, a ferramenta devolve o motivo como **resultado**, não como falha de protocolo: ```json { "_erro": true, "http": 422, "erro": "..." } ``` É deliberado: o agente precisa **ler** o motivo para explicar à pessoa, em vez de apenas dizer que a ferramenta falhou. ============================================================================== # https://docs.conota.dev/docs/mcp/seguranca ============================================================================== # Segurança no MCP Um agente de IA interpreta linguagem natural e executa ferramentas. Uma operação fiscal **não pode perder as garantias de controle** só porque passou a ser iniciada por conversa. Por isso a emissão pelo MCP é separada em **preparação** e **confirmação**. ## Emissão em dois passos ### 1. Preparar O agente monta ou reaproveita os dados, pede a preparação e recebe um **resumo legível**. Nenhuma nota é emitida aqui, e nenhuma cota é consumida. ### 2. Confirmar O resumo é apresentado a uma pessoa. Só depois de um **sim explícito** a confirmação é chamada. ```text Usuário pede a emissão │ ▼ Agente prepara a operação │ ▼ Conota valida e devolve um resumo │ ▼ Pessoa confere │ confirma? │ │ não sim │ │ encerra ▼ emissão ``` ## As quatro camadas O desenho não depende de o agente "se comportar". Cada camada funciona sozinha: | # | Proteção | O que ela pega | |---|---|---| | 1 | **Preparação valida o payload** | payload torto nunca chega a virar token | | 2 | **Teto de valor por conta** | o que a atenção humana deixa passar | | 3 | **Token de uso único** | o agente que reenvia "por segurança" | | 4 | **Referência externa presa ao token** | duplicidade por outro caminho | > **INFO — Por que o teto existe** > Uma pessoa aprova o resumo do agente sem reconferir a ordem de grandeza — é assim que a atenção > humana funciona. O teto não depende de ninguém prestar atenção. Ele vale **só** na emissão > assistida: a `POST /v1/nfe/emitir` direta não tem limite, porque lá o valor vem do ERP do cliente. ## Repetir a confirmação não emite duas vezes O token é de **uso único**. Repetir a confirmação devolve **o mesmo job** — é a defesa número um contra um modelo que reenvia por insegurança. ## A chave não distingue leitura de emissão > **IMPORTANTE — Quem conecta o MCP com a chave da conta pode emitir** > Não existe hoje conexão só de leitura. A API Key carrega todas as permissões dela, e > `confirmar_emissao` está entre as ferramentas disponíveis. Trate a chave usada no MCP com o mesmo > cuidado da chave de produção. Se você quer que alguém só consulte, hoje a resposta é **não dar a chave** — e não "conectar em modo leitura", que não existe. ## O que o agente não deve fazer As descrições das ferramentas instruem o modelo explicitamente: - não chamar a confirmação na mesma resposta em que preparou; - se a pessoa não respondeu, **perguntar** — não assumir; - não prometer que um número de nota está garantido: consulta não é reserva. Isso é parte do contrato, não decoração: no MCP, a descrição da ferramenta **é** a interface. ============================================================================== # https://docs.conota.dev/docs/mcp/exemplos ============================================================================== # O que você pode fazer com o Conota MCP Depois de conectar, ninguém precisa decorar nome de ferramenta. A necessidade é formulada em linguagem natural e o agente escolhe o caminho. ## Gestão diária > Quanto emitimos hoje, separado por tipo de nota? > Liste as NF-e autorizadas desta semana. > Existe algum certificado vencendo em breve? > Em que número está a série 1 da NF-e em produção? ## Diagnóstico > Quais notas foram rejeitadas nos últimos sete dias? > Agrupe as rejeições pelos motivos mais comuns. > Mostre os itens da nota que foi rejeitada e me ajude a entender qual campo pode ter causado o > problema. O agente consegue ir do resumo até o item específico porque existe uma ferramenta que **marca qual item** provocou a rejeição — não é o modelo adivinhando. ## Localização de documentos > Localize a nota de R$ 1.280 emitida ontem para este CNPJ. > Quero o PDF da nota que emitimos para esse cliente. > Achei o `job_id` no meu log, me diga o que aconteceu com ele. ## Reemissão assistida > Pegue a nota rejeitada, altere somente o NCM do primeiro item e prepare novamente para eu > conferir. Esse caso é mais seguro do que montar do zero: o payload de origem **já foi validado pela realidade** — a SEFAZ opinou sobre ele —, então só a correção é nova. ## Emissão a partir de um modelo > Faça outra nota igual à de ontem para o mesmo cliente, mas com a quantidade do produto X alterada > para 20. Mostre tudo antes de emitir. > **ATENÇÃO — Emissão sempre passa pela confirmação** > Os exemplos acima **preparam**. A emissão efetiva só acontece depois de você conferir o resumo e > confirmar. Ver [Segurança e confirmação humana](/docs/mcp/seguranca). ## Fechamento > Quais pacotes mensais de XML estão disponíveis? > Baixe o zip de NF-e da competência passada. ## O catálogo completo A lista das ferramentas realmente publicadas, com os parâmetros de cada uma, está em **[mcp.conota.dev](https://mcp.conota.dev)**. Ela é gerada do próprio servidor — por isso não é duplicada aqui. ============================================================================== # https://docs.conota.dev/docs/ferramentas/redoc ============================================================================== # Referência da API A referência técnica do Conota é gerada a partir da especificação OpenAPI: **[api.conota.dev/docs](https://api.conota.dev/docs)** Use para consultar: - endpoints e métodos HTTP; - parâmetros e campos obrigatórios; - schemas de requisição e resposta; - enums e seus valores; - exemplos; - códigos de retorno. ## A divisão de trabalho | | | |---|---| | **Este portal** | como integrar — conceitos, fluxos, decisões | | **ReDoc** | o contrato exato da API | > **INFO — Por que não copiamos as tabelas de campos para cá** > O OpenAPI é **gerado do código do gateway**: alterar uma rota altera a referência na mesma entrega. > Uma cópia manual em Markdown não tem esse vínculo — ela envelhece em silêncio e, num certo dia, > passa a mentir. Documentação que mente é pior que documentação que falta. ## Não existe arquivo de spec Não há um `openapi.yaml` no repositório. A especificação é montada em tempo de execução a partir dos schemas das rotas. Se você quiser o arquivo: ```bash curl -s https://api.conota.dev/docs/json -o openapi-conota.json ``` Também disponível em YAML, em `/docs/yaml`. ============================================================================== # https://docs.conota.dev/docs/ferramentas/swagger ============================================================================== # Testando endpoints com Swagger O Swagger UI do Conota está em: **[api.conota.dev/swagger](https://api.conota.dev/swagger)** É um **console de desenvolvimento**: explora e executa endpoints com a sua chave. ## Como autenticar 1. abra o Swagger; 2. clique em **Authorize**; 3. cole a API Key no campo `apiKey` (header `X-API-Key`); 4. execute qualquer endpoint com **Try it out**. ## Quando usar - testar autenticação; - validar rapidamente um payload; - conferir a forma de uma resposta; - reproduzir uma chamada durante um diagnóstico. ## Quando não usar > **ATENÇÃO — Cuidado ao apertar "Execute" apontando para produção** > O Swagger executa de verdade. Um `POST /v1/nfe/emitir` com a chave de produção **emite uma nota com > efeito fiscal**. Confirme o ambiente antes. O Swagger também não substitui uma integração de backend nem é uma boa fonte para **entender** os fluxos fiscais. Para aprender a integrar, use este portal; para consultar schemas, use o [ReDoc](/docs/ferramentas/redoc). ============================================================================== # https://docs.conota.dev/docs/ferramentas/postman ============================================================================== # Usando o Conota no Postman O Postman importa a especificação OpenAPI e cria uma collection com os endpoints. ## Importando 1. abra **Import** no Postman; 2. escolha importação por **link**; 3. informe: ```text https://api.conota.dev/docs/json ``` 4. confirme a criação da collection. ## Configurando a chave 1. crie um **Environment** (por exemplo `Conota — homologação`); 2. adicione uma variável `apiKey` do tipo **secret**; 3. na collection, configure o header: ```text X-API-Key: {{apiKey}} ``` > **IMPORTANTE — Nunca grave a chave dentro da collection** > Collection é arquivo, e arquivo vai para o Git ou para um workspace compartilhado. Use variável de > ambiente do tipo secret, e mantenha environments separados para homologação e produção — com nomes > que não deixem dúvida sobre qual está ativo. ## Sugestão de organização Crie dois environments com nomes explícitos e **cores diferentes**, se o seu Postman permitir. O acidente clássico dessa API é executar em produção achando que está em homologação. ============================================================================== # https://docs.conota.dev/docs/ferramentas/openapi ============================================================================== # OpenAPI O contrato da API do Conota é descrito em **OpenAPI 3**. ```text https://api.conota.dev/docs/json # JSON https://api.conota.dev/docs/yaml # YAML ``` Essa especificação é a fonte da [Referência da API](/docs/ferramentas/redoc) e do [Swagger UI](/docs/ferramentas/swagger) — as duas páginas mostram **o mesmo contrato**, com apresentações diferentes. ## Usos comuns - importar no [Postman](/docs/ferramentas/postman); - gerar clientes em várias linguagens; - validar contratos em CI; - alimentar ferramentas de documentação; - dar contexto estruturado a ferramentas de desenvolvimento assistido por IA. ## Gerando um cliente ```bash npx @openapitools/openapi-generator-cli generate \ -i https://api.conota.dev/docs/json \ -g typescript-axios \ -o ./cliente-conota ``` > **INFO — Cliente gerado não sabe de fluxo** > Um SDK gerado sabe chamar `POST /v1/nfe/emitir`. Ele não sabe que a resposta é assíncrona, que > `completed` não significa autorizada, nem que reenviar depois de um timeout pode duplicar a nota. > Essa parte está aqui, neste portal. ## A regra interna Toda alteração de endpoint atualiza o OpenAPI **na mesma entrega** — porque o spec é gerado do próprio código da rota, não escrito à parte. Um endpoint publicado sem `summary`, `description` e exemplos adequados é tratado como documentação incompleta. ============================================================================== # https://docs.conota.dev/docs/ferramentas/ia ============================================================================== # Documentação para agentes e LLMs Além do [MCP](/docs/mcp/introducao), este portal oferece uma representação textual da documentação, fácil de consumir por ChatGPT, Claude, Codex, Cursor e Copilot. ## Os três arquivos | Arquivo | O que traz | Tamanho | |---|---|---| | **[`/llms.txt`](https://docs.conota.dev/llms.txt)** | o índice: o que é o produto, onde está cada coisa, e as armadilhas | ~1.500 tokens | | **[`/llms-api.txt`](https://docs.conota.dev/llms-api.txt)** | o **contrato**: endpoints, parâmetros, campos, tipos, obrigatoriedade, exemplos | ~15 mil tokens | | **[`/llms-full.txt`](https://docs.conota.dev/llms-full.txt)** | a documentação editorial inteira | ~30 mil tokens | Os três cabem juntos em qualquer janela de contexto moderna. Não há versão por área da API — com esse tamanho, dividir só acrescentaria a dúvida de qual arquivo carregar. ## Qual usar | Sua tarefa | Carregue | |---|---| | Gerar código de integração | `llms.txt` + `llms-api.txt` | | Entender o fluxo fiscal | `llms.txt` + `llms-full.txt` | | Só situar o assistente | `llms.txt` | > **INFO — Os dois grandes são gerados, não escritos** > `llms-api.txt` sai do OpenAPI — que sai do código do gateway. `llms-full.txt` sai das páginas deste > portal. Nenhum dos dois é mantido à mão. > > É a mesma regra que vale para o portal inteiro: uma lista de campos escrita à mão envelheceria em > silêncio, e um agente que lê campo desatualizado **erra com confiança**. ## Três recursos, três papéis | Recurso | O que entrega | |---|---| | **`llms.txt`** | contexto documental — como o produto funciona | | **OpenAPI** | contrato estruturado — quais campos existem | | **MCP** | ferramentas e acesso aos **dados reais** da conta | > **INFO — MCP não substitui `llms.txt`** > São coisas diferentes. O `llms.txt` explica o produto para o modelo; o MCP dá a ele ferramentas > autenticadas para consultar dados de verdade. Um assistente com os dois responde melhor do que com > qualquer um isolado. ## Usando com um assistente de código Para gerar código de integração, o par mais útil é `llms.txt` (conceitos e armadilhas) + o `openapi.json` (campos exatos). O modelo tende a errar menos nos pontos que este portal insiste: resposta assíncrona, `completed` não é autorizada, e não reenviar depois de timeout. ============================================================================== # https://docs.conota.dev/docs/operacao/boas-praticas ============================================================================== # Boas práticas de integração Uma integração fiscal precisa estar preparada para falha de rede, resposta externa lenta, rejeição e reprocessamento. Nenhuma dessas é exceção — todas acontecem toda semana. ## As dez que mais evitam problema 1. **Gere e persista uma `referencia_externa` por operação**, antes de enviar. 2. **Armazene o `job_id`** assim que ele chegar. 3. **Trate a emissão como assíncrona.** `202` não é autorização. 4. **Implemente webhooks de forma idempotente** — o mesmo evento pode chegar duas vezes. 5. **Nunca reenvie uma nota só porque houve timeout.** Localize primeiro. 6. **Registre erros e rejeições** sem armazenar segredos. 7. **Monitore certificados** — vencido derruba todas as emissões da empresa. 8. **Confira a numeração** antes de emitir; rejeitada não consome número. 9. **Use backoff** nas retentativas técnicas. 10. **Nunca transforme retentativa técnica em duplicação fiscal.** ## Antes de escalar volume - [ ] Uma emissão completa validada de ponta a ponta - [ ] Uma rejeição provocada de propósito e tratada pelo seu código - [ ] Webhook recebido, validado por assinatura e processado - [ ] Recuperação testada: derrube o webhook e reconcilie por consulta - [ ] XMLs sendo armazenados no seu ambiente - [ ] Logs com correlação, sem segredo - [ ] Alerta de certificado a vencer ## Distinga o que pode ser repetido > **IMPORTANTE — A pergunta certa não é "deu erro?", é "o que aconteceu com a operação?"** > Repetir uma consulta é inofensivo. Repetir uma emissão pode gerar duas notas para o mesmo fato > gerador. Antes de qualquer retentativa de emissão, descubra o estado real — > `GET /v1/jobs/localizar` existe para isso. ============================================================================== # https://docs.conota.dev/docs/operacao/seguranca ============================================================================== # Segurança Trate credenciais fiscais e da API como **segredos de produção**. ## Nunca exponha - API Key; - senha do certificado; - o arquivo do certificado; - tokens temporários de operação (como o da emissão assistida); - links assinados de download; - dados pessoais desnecessários em logs. ## API Key > **IMPORTANTE — Uma chave vazada é capacidade de emitir nota fiscal em nome da empresa** > Não é só leitura de dados. Se houver qualquer suspeita, **revogue primeiro** e investigue depois, > no painel: **Integração → Chaves de API → revogar**. A revogação vale na hora, sem propagação. Boas práticas: - uma chave por aplicação, para revogar sem derrubar tudo; - variáveis de ambiente ou secret manager, nunca arquivo versionado; - rotação periódica; - nunca em frontend. ## Links de download As URLs de arquivo assinadas têm validade curta **de propósito**. Não as persista nem as compartilhe: gere uma nova quando precisar. Um link salvo em banco vira um vazamento com prazo. ## Ao pedir suporte Envie identificadores e evidências suficientes para rastrear a operação — `job_id`, `referencia_externa`, horário, ambiente —, mas **remova credenciais**. Ver [Como abrir um chamado](/docs/operacao/suporte). ============================================================================== # https://docs.conota.dev/docs/operacao/logs ============================================================================== # Observabilidade e logs Seu sistema deve conseguir responder **três perguntas** sobre qualquer emissão, inclusive meses depois: 1. o que tentamos emitir? 2. qual operação foi criada no Conota? 3. qual foi o resultado final conhecido? Se qualquer uma delas depende de "abrir o painel e procurar", a sua observabilidade está incompleta. ## Campos de correlação - `referencia_externa`; - `job_id`; - CNPJ do emitente; - tipo do documento; - número e série, quando já existirem; - data e hora da tentativa; - ambiente; - status do job e status da nota; - código e motivo da rejeição. ## Registre a tentativa, não só o resultado > **INFO — O log mais útil é o da requisição que nunca voltou** > Se você só registra respostas, o caso mais difícil — o timeout — não deixa rastro. Grave a intenção > **antes** de enviar, com a `referencia_externa` já definida. É isso que torna a reconciliação > possível. ## Nunca registre - API Key; - senha do certificado; - o certificado; - o payload inteiro se ele carregar credenciais. ## Conciliação periódica Vale uma rotina que, todo dia, busque jobs sem estado final e consulte em lote: ```http POST /v1/jobs/consultar-lote ``` E, para o panorama do período: ```http GET /v1/jobs/erros?de=...&ate=...&formato=resumo GET /v1/jobs/rejeitadas?de=...&ate=...&formato=resumo ``` O formato `resumo` agrupa por motivo — costuma revelar que a maior parte das rejeições da semana tem uma causa só. ============================================================================== # https://docs.conota.dev/docs/operacao/suporte ============================================================================== # Como abrir um chamado técnico Antes de abrir o chamado, consulte o estado da operação. Boa parte das dúvidas se resolve em ```http GET /v1/nfe/consultar/{job_id} GET /v1/jobs/localizar?ref=... ``` ## Informe - **identificador da operação** (`job_id`) — é o que mais acelera; - `referencia_externa`; - tipo de documento; - **ambiente** (homologação ou produção); - CNPJ do emitente; - horário aproximado; - endpoint utilizado; - código HTTP, quando houver; - mensagem de erro ou de rejeição, **na íntegra**; - comportamento esperado. > **INFO — Um `job_id` vale mais que três parágrafos** > Com ele localizamos payload, tentativas, resposta do autorizador e arquivos gerados. Sem ele, a > primeira resposta do suporte vai ser justamente pedindo isso. ## Não envie - API Key; - senha do certificado; - o arquivo do certificado; - dados pessoais sem relação com a investigação. Se um deles já foi enviado por engano, **revogue ou troque** — considere comprometido. ## Antes de escalar Confira se não é um dos casos conhecidos: - certificado vencido → `GET /v1/empresas/certificados`; - rejeição fiscal (não é falha da API) → [Erros e rejeições](/docs/conceitos/erros-rejeicoes); - nota "sumida" após timeout → [`/v1/jobs/localizar`](/docs/conceitos/referencia-externa); - cota esgotada → painel. ============================================================================== # https://docs.conota.dev/docs/operacao/faq ============================================================================== # Perguntas frequentes ## O Swagger foi removido? Não. Ele está em [api.conota.dev/swagger](https://api.conota.dev/swagger) e continua sendo o console de testes. A **referência** da API usa ReDoc, em [api.conota.dev/docs](https://api.conota.dev/docs). ## O que devo usar para integrar: este portal ou o ReDoc? Os dois. Aqui você entende o fluxo; no ReDoc confere endpoints, parâmetros e schemas. ## Preciso usar MCP para integrar? Não. O MCP é uma forma **adicional**, voltada a assistentes e agentes de IA. Integrações tradicionais continuam usando a API REST. ## MCP substitui a API REST? Não. O MCP expõe capacidades controladas para agentes; a REST continua sendo a interface determinística para integrações transacionais. Ver [quando usar cada um](/docs/mcp/mcp-vs-rest). ## Uma IA pode emitir uma nota sozinha pelo MCP? Não. A emissão exige **preparação e confirmação humana explícita**. O token de confirmação é de uso único e há teto de valor por conta. Ver [Segurança no MCP](/docs/mcp/seguranca). ## Recebi timeout. Posso reenviar? Não automaticamente. Primeiro localize a operação: ```http GET /v1/jobs/localizar?ref=sua_referencia ``` Reenvio cego pode causar duplicidade. Se você enviou `referencia_externa`, o reenvio da mesma referência é seguro: devolve o job existente. ## Uma rejeição significa que a API está fora do ar? Não — significa o contrário. O documento **chegou** ao autorizador e foi recusado por uma regra fiscal ou cadastral. Ver [Erros e rejeições](/docs/conceitos/erros-rejeicoes). ## O status voltou `completed`. A nota foi autorizada? Não necessariamente. `completed` é o **processamento**; o desfecho fiscal está em `nota.status`. Ver [Status das emissões](/docs/conceitos/status). ## Minha nota foi rejeitada. Perdi o número? Não. Nota rejeitada **não consome numeração**. Corrija e emita de novo — com uma `referencia_externa` **nova**. ## Posso usar a API Key no frontend? Não. Ela permite emitir documentos com efeito fiscal. Use apenas em ambiente que você controla. ## Quanto tempo os arquivos ficam disponíveis? Depende do plano. Armazene os XMLs no seu ambiente — a obrigação de guarda é sua, e a API não é arquivo definitivo. ## O CNPJ alfanumérico já é aceito? Sim, em todos os pontos da API que tratam documento. Sobre máscara: em **query string** e no **corpo**, envie como quiser. Em **parâmetro de caminho** (`/v1/cnpj/{cnpj}`, `/v1/empresas/{cpf_cnpj}`), envie **sem a barra** — ela é separador de caminho e a rota não seria encontrada. ============================================================================== # https://docs.conota.dev/docs/atualizacoes/changelog ============================================================================== # Changelog Mudanças relevantes para quem integra com o Conota. Correções puramente ortográficas da documentação não entram aqui. --- ## 2026-10-29 ### Corrigido - **Quebra de linha nas informações complementares da NF-e.** Um `infCpl` com mais de uma linha chegava ao XML só com a primeira, sem aviso. Agora o texto vai inteiro, com cada quebra convertida em `; `. Ver [Informações complementares (OBS)](/docs/documentos/nfe/emitir#informações-complementares-obs). ### Adicionado - `danfe_config.quebrar_linha_obs` (NF-e): quebra a linha do DANFE em cada `;` das informações complementares. --- ## 2026-10-20 ### Adicionado - **NFS-e Nacional pelo motor próprio.** A DPS é montada e conferida contra o XSD oficial antes de ir para a Sefin, e cada erro volta com o caminho do campo. Ver [NFS-e Nacional — motor próprio](/docs/documentos/nfse/nfse-nacional). - `POST /v1/nfse-nacional/emitir`, `POST /v1/nfse-nacional/condominios/emitir` e `POST /v1/nfse-nacional/validar`. - Campo `versao` para escolher o leiaute: `1.01` (padrão), `1.01-20261020` (XSD oficial de 20/10/2026) e `1.01-nt009` (condomínios, provisório). - A validação não consome cota nem numeração. ### Atenção - No leiaute `1.01-20261020`, `finNFSe` sai de `IBSCBS` e vai para `infDPS`, e `CST` e `cClassTrib` sobem de `IBSCBS.valores.trib.gIBSCBS` para `IBSCBS.valores.trib`. O payload do leiaute `1.01` é recusado nesse leiaute. - A rota `POST /v1/nfse/emitir` não mudou. As integrações existentes continuam funcionando sem ajuste. --- ## 2026-09-25 ### Adicionado - **Notas recebidas (captura).** As NF-e e NFS-e que fornecedores emitem **contra** as suas empresas, baixadas das fontes oficiais — SEFAZ para NF-e e o Ambiente de Dados Nacional para NFS-e. Ligar e desligar por empresa e por tipo, consultar, baixar o XML e receber aviso por webhook. Incluída por plano. Ver [Notas recebidas](/docs/captura/visao-geral). - `GET` e `PUT /v1/captura`, `GET /v1/captura/notas`, `GET /v1/captura/notas/xml`, `PUT /v1/captura/webhook` e `POST /v1/captura/webhook/segredo`. - Referência própria, gerada do código: [api.conota.dev/v1/captura/docs](https://api.conota.dev/v1/captura/docs). - No MCP: `estado_da_captura`, `listar_notas_recebidas`, `xml_da_nota_recebida` e `ligar_ou_desligar_captura`. ### Atenção - O webhook das notas recebidas **não usa o mesmo contrato** do webhook de emissão: headers `X-Conota-*`, chave de assinatura por conta e assinatura sobre `.`. Ver [Webhook das notas recebidas](/docs/captura/webhook). O webhook de emissão não mudou. --- ## 2026-09-03 ### Adicionado - **`GET /v1/empresas/numeracao`** — diz em que número cada sequência está: o número da última nota **autorizada** por empresa, tipo, série e ambiente. Homologação e produção vêm separadas. É consulta, não reserva. Ver [Onboarding](/docs/comecando/onboarding). - A mesma informação está disponível no MCP, como `numeracao_das_notas`. - **Documentação em duas páginas**: [ReDoc](https://api.conota.dev/docs) para ler o contrato e [Swagger UI](https://api.conota.dev/swagger) para testar. `/docs/json` e `/docs/yaml` continuam respondendo nos mesmos endereços. - Este portal, em `docs.conota.dev`. ### Alterado - **CNPJ alfanumérico aceito em toda a API.** Desde 31/07/2026 o CNPJ pode ter letras nas 12 primeiras posições. Todos os pontos que tratam documento — rotas, filtros, buscas, máscaras e o MCP — passaram a preservar letras. Antes, elas eram removidas em silêncio, o que podia levar à empresa errada. - `GET /v1/cnpj/{cnpj}` deixou de recusar com "CNPJ deve conter 14 dígitos". - Documento na URL passou a tolerar pontuação. **Exceção importante:** a **barra** da máscara do CNPJ é separador de caminho e continua quebrando a rota — em parâmetro de caminho, envie sem ela. Em query string e no corpo, a máscara completa é aceita. ### Atenção - Bibliotecas de terceiros usadas na emissão ainda não suportam CNPJ alfanumérico. Emitir **para** ou **por** um CNPJ com letras depende dessa atualização, já mapeada. --- ## Como usar esta página Cada entrada indica o que mudou e, quando houver impacto, o que fazer. Mudanças que possam quebrar integrações existentes ficam em [Mudanças incompatíveis](/docs/atualizacoes/breaking-changes). ============================================================================== # https://docs.conota.dev/docs/atualizacoes/breaking-changes ============================================================================== # Mudanças incompatíveis Mudanças que possam quebrar uma integração existente recebem comunicação destacada e antecedência. ## O que conta como incompatível - remoção de campo; - mudança de tipo de um campo; - alteração ou remoção de valor de enum; - remoção de endpoint; - mudança de autenticação; - mudança obrigatória de fluxo. ## O que cada aviso informa 1. o que muda; 2. por que muda; 3. quem é afetado; 4. data de entrada em vigor; 5. como migrar; 6. exemplo antigo e novo. ## Nenhuma até aqui Não há mudança incompatível registrada. Quando houver, ela aparece aqui **antes** de entrar em vigor. > **INFO — O compromisso com os nomes existentes** > Vale um exemplo do que essa política significa na prática. Quando a marca mudou para Conota, os > headers de webhook **não** foram renomeados — continuam `X-Qualyfiscal-Signature`, > `X-Qualyfiscal-Job-Id`, `X-Qualyfiscal-Tentativa`. Eles são contrato, não marca: renomear quebraria > a validação de assinatura de toda integração existente, e a falha apareceria do lado do cliente, > silenciosamente. ============================================================================== # https://docs.conota.dev/docs/atualizacoes/fiscal ============================================================================== # Atualizações fiscais e regulatórias Esta página traduz mudanças oficiais que impactam **a integração**. Ela não substitui a documentação do fisco — responde o que muda para quem usa a API. --- ## CNPJ alfanumérico **Em vigor desde 31/07/2026 · obrigatório em 2027** O CNPJ passou a admitir **letras** nas 12 primeiras posições. Os 2 dígitos verificadores continuam numéricos, e o documento continua com 14 caracteres. O primeiro emitido foi `00.000.000/E08G-12`. **O que muda para você** - validações do tipo "somente números" no seu sistema passam a recusar CNPJ válido; - normalização com remoção de não-dígitos **corrompe** o documento em silêncio: `12.ABC.345/01DE-35` vira `1234501`; - o cálculo do dígito verificador muda — cada caractere vale o código ASCII menos 48 (`A` = 17, `B` = 18...). Para CNPJ só de números, o resultado é idêntico ao cálculo antigo. **O que já mudou no Conota** Toda a API aceita o formato novo. Onde antes havia recusa ou corrupção silenciosa, hoje há o comportamento correto. > **ATENÇÃO — Sobre a máscara em parâmetro de caminho** > A barra do CNPJ (`00.000.000/E08G-12`) é separador de caminho na URL. Em rotas como > `/v1/cnpj/{cnpj}`, envie **sem a barra**. Em query string e no corpo, a máscara completa é > aceita normalmente. > **ATENÇÃO — A emissão ainda depende de terceiros** > As bibliotecas usadas na montagem e assinatura do XML ainda não suportam o formato. Emitir **para** > ou **por** um CNPJ alfanumérico depende dessa atualização. Consultas e cadastro já funcionam. --- ## Reforma tributária — IBS e CBS O grupo IBS/CBS é aceito no payload da NF-e e transmitido no XML. Como qualquer campo tributário, a **classificação correta** — CST, cClassTrib, alíquotas — é responsabilidade da sua regra de negócio. O Conota transporta e valida a estrutura; ele não decide a tributação da operação. --- ## DANFSe conforme a NT 008 O layout do DANFSe foi atualizado para a versão 2.0 da Nota Técnica 008 do Sistema Nacional da NFS-e, incluindo os blocos de IBS/CBS, PIS/COFINS, NBS e os totais aproximados de tributos da Lei 12.741/2012. Não há mudança de integração: o PDF gerado passa a seguir o novo leiaute. --- > **INFO — Última revisão desta página** > 03/09/2026. Documentação regulatória sem data de atualização não deve ser considerada confiável — > inclusive esta.