API de Declaração de Conteúdo Eletrônica (DC-e)
API de emissão da DC-e, o documento fiscal de circulação de bens de quem não é contribuinte do ICMS.
A DC-e (Declaração de Conteúdo Eletrônica) é o documento de quem movimenta bens sem inscrição estadual — e por isso sem NF-e a emitir.
A DC-e não tem tributo
Não existe grupo de tributo nesta API: sem ICMS, sem IBS/CBS, sem alíquota, sem base de
cálculo e sem cálculo tributário. Quem chega da NF-e procurando onde informar imposto não vai
encontrar — e não é omissão da documentação, é o que o documento é. Os valores do item
(unitValue, totalValue) são valor de mercadoria, nada mais.
O caminho de integração
| Passo | Operação |
|---|---|
| Emitir | POST /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations |
| Emitir em lote | POST /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/$batch |
| Acompanhar | GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id} |
| Auditar o histórico | GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id}/events |
| Baixar a DACE (PDF) | GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id}/pdf |
| Baixar o XML autorizado | GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id}/xml |
| Cancelar | DELETE /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id} |
Autenticação: token JWT, e não a chave de API da plataforma
A DC-e aceita apenas Authorization: Bearer <token JWT>, com a audiência
dfetech.contentdeclaration.api. A chave de API usada nas outras APIs da nfe.io
(Authorization: <api-key>, sem Bearer) não é aceita aqui — e é por isso que as
bibliotecas oficiais (Node.js, PHP, Ruby), que autenticam por chave de API, ainda não atendem
a DC-e.
Veja o esquema bearerAuth para os escopos e papéis aceitos.
A assinatura vai na URL
Toda rota carrega a assinatura e o contribuinte emitente, nesta ordem:
/v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations…, em minúsculas.
O subscriptionId é a única fonte do escopo de dados — é ele que diz de quem são os
documentos; o taxpayerId diz qual contribuinte emite. Aceita o identificador com ou sem o
prefixo sub_. Nenhum cabeçalho de assinatura é lido, em rota nenhuma.
🔑 Esta é a única forma de URL que a API serve. Não há rota alternativa, nem em outro host,
nem para compatibilidade: as formas anteriores — /v2/companies/{companyId}/… e
/v2/subscriptions/{subscriptionId}/companies/{companyId}/… — respondem 404, e o cabeçalho
X-Subscription-Id deixou de ser lido. Se você integrou por uma delas, a migração é trocar o
caminho; nada mais no contrato mudou.
⚠️ taxpayers na URL, companyId no corpo — e os dois estão certos. O recurso público é o
contribuinte, e o serviço que o governa se chama tax-payers; dentro da plataforma o mesmo
identificador se chama empresa. Por isso o campo companyId que a listagem devolve carrega
exatamente o valor que você pôs em {taxpayerId}.
O ambiente é um campo obrigatório do corpo, e tem de bater com o cadastro da empresa
O corpo da emissão leva environment: 1 produção, 2 homologação. Ausente, 0 ou fora
desses dois valores, a resposta é 400. O valor tem de coincidir com o ambiente cadastrado da
empresa na plataforma — divergente, a resposta é 400 com a regra B10-10 e os dois valores.
Empresa sem ambiente cadastrado é homologação. Em homologação, a DACE sai com a tarja
"EMITIDO EM HOMOLOGAÇÃO — SEM VALOR FISCAL" e o documento não tem validade fiscal.
Erros no formato Problem Details
Toda resposta de erro é application/problem+json (RFC 9457), com type estável no espaço
https://docs.nfe.io/errors/dce/… — é o discriminador para o seu código; title e detail
são texto para pessoas, em inglês. Recusa sobre campos da requisição (400, 422) traz ainda
errors[], com name (o caminho do campo, em camelCase), reason (a explicação) e rule (o
identificador da regra, quando há).
Tolere valores de enum que você não conhece
Os campos de estado (status, flowStatus) podem ganhar valores novos sem aviso — implantação
é em ondas, e por alguns minutos convivem duas versões do serviço. Trate valor desconhecido
como "estado que não conheço ainda" e não falhe: um consumidor que estoura em enum novo
repete, do lado do cliente, o incidente que esta API já teve do lado do servidor.
O que ainda não está nesta referência
| Operação | Por que não está |
|---|---|
GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/sefaz/dce-status | a rota existe, sem implementação do leitor de status. Documentar endpoint que não responde gera chamado, não integração |
Authentication
- HTTP: Bearer Auth
Token JWT emitido pelo provedor de identidade da nfe.io, enviado em
Authorization: Bearer <token>.
Audiência (aud) | dfetech.contentdeclaration.api |
| Escopos que autorizam leitura | contentdeclaration:read, api.all.read, api.all.read-write |
| Escopos que autorizam emissão e cancelamento | contentdeclaration:write, api.all.read-write |
| Papéis aceitos (tokens de usuário) | dce:read para leitura, dce:issue para emissão |
⚠️ api.all.read não autoriza emissão. Escopo de leitura não vira permissão de emitir
documento fiscal.
⚠️ A chave de API da plataforma não é aceita. As outras APIs da nfe.io autenticam com
Authorization: <api-key>; aqui isso responde 401.
Assinatura e empresa: as duas vão na URL
O isolamento dos documentos é pela assinatura do caminho ({subscriptionId}) — não pelo
taxpayerId. As duas coisas são dimensões distintas: a assinatura diz de quem são os
documentos, e o taxpayerId diz qual contribuinte emite. Nenhum cabeçalho de assinatura
é lido.
- Token de assinatura (
client_credentials): o{subscriptionId}da URL tem de ser a assinatura do próprio token — outra, a resposta é403. - Token de usuário (login no console): o
{subscriptionId}tem de ser uma assinatura a que o usuário tem acesso — outra, a resposta é403.
O 403 de assinatura vem com type https://docs.nfe.io/errors/dce/subscription-scope-undetermined,
qualquer que seja o detail.
Security Scheme Type: | http |
|---|---|
HTTP Authorization Scheme: | bearer |
Bearer format: | JWT |