Como consultar uma DC-e pela API
GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id}
Devolve o estado atual de uma DC-e — situação, chave de acesso, protocolo, numeração, emitente, destinatário, valor total e o ambiente em que foi autorizada (environment: 1 produção, 2 homologação).
A resposta traz nome, inscrição e valor total do emitente e do destinatário — não os itens, nem o endereço completo. Guarde o corpo que você enviou na emissão, ou baixe o XML autorizado, se precisar do detalhe completo.
O campo status
| Valor | Significado |
|---|---|
Created | Criado, ainda não transmitido |
Processing | Em processamento |
Authorized | Autorizado pela SEFAZ — tem accessKey e protocol |
Rejected | Rejeitado pela SEFAZ, com cStat no histórico |
Cancelled | Cancelado |
Refused | Parou por veredito nosso — veja refusedStep e refusedReasons |
Unknown | Situação que esta versão do contrato não conhece |
Rejected e Refused não são a mesma coisaRejected é a SEFAZ dizendo não, depois de receber o documento — motivo fiscal, com cStat no histórico de eventos. Refused é a NFE.io parando a emissão antes de transmitir — cadastro incompleto, certificado com problema, ou validação local. Um documento Refused nunca chegou à SEFAZ.
status e flowStatus podem ganhar valores novos sem aviso — implantação é em ondas, e por alguns minutos convivem duas versões do serviço. Trate um valor desconhecido (Unknown ou outro) como "estado que ainda não conheço" e não falhe — um consumidor que estoura em enum novo repete, do lado do cliente, o mesmo tipo de incidente que a API já teve do lado do servidor.
{
"id": "0f6b1f5c-9a5e-4a0e-9c1b-2f4e6d8a1b23",
"status": "Authorized",
"flowStatus": "Finished",
"accessKey": "33260811222333000181990010000000211208201894",
"serie": 1,
"number": 21,
"protocol": "133260000123456",
"createdAt": "2026-08-19T13:04:11.512Z",
"issuerName": "EMPRESA EXEMPLO LTDA - MATRIZ",
"issuerFederalTaxNumber": "11222333000181",
"recipientName": "EMPRESA EXEMPLO LTDA - FILIAL",
"recipientFederalTaxNumber": "99887766000105",
"totalValue": 3000,
"environment": 2
}
{
"id": "0f6b1f5c-9a5e-4a0e-9c1b-2f4e6d8a1b23",
"status": "Refused",
"flowStatus": "DefineNumber",
"refusedStep": "DefineNumber",
"refusedReasons": ["Empresa sem certificado digital válido em custódia"],
"createdAt": "2026-08-19T13:04:11.512Z",
"issuerName": "EMPRESA EXEMPLO LTDA - MATRIZ",
"issuerFederalTaxNumber": "11222333000181"
}
Campos ausentes são omitidos do JSON — nunca devolvidos como null. É por isso que o exemplo Refused acima não tem accessKey, serie, number, protocol: nenhum deles chegou a existir.
O histórico de eventos
GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations/{id}/events
Devolve o histórico do documento, em ordem de versão — é a resposta para "por que este documento está neste estado?", inclusive quando o estado é Rejected ou Refused.
eventType | O que traz em data |
|---|---|
ContentDeclarationCreated | emitterType, emissionType, serie, number |
NumberDefined | number, serie, accessKey |
SentToSefaz | Nada além de tipo, versão e data |
Authorized | protocol, authorizedAt |
Rejected | cStat, reason |
ContingencyAccepted | accessKey |
DaceGenerated | hasFull, hasSummary, hasXml |
CancelRequested | reason, cancellationProtocol, cStat |
Cancelled | protocol, cancelledAt, cStat |
CancelRejected | cStat, reason |
Notified | eventType (o evento notificado) |
XML assinado e dados pessoais completos não aparecem aqui de propósito. Tipos de evento novos podem surgir — um tipo que você não conhece vem apenas com tipo, versão e data, sem data.
[
{
"eventType": "ContentDeclarationCreated",
"version": 1,
"occurredAt": "2026-08-19T13:04:11.512Z",
"data": {
"emitterType": "SelfIssuer",
"emissionType": "Normal",
"serie": 1,
"number": 0
}
},
{
"eventType": "NumberDefined",
"version": 2,
"occurredAt": "2026-08-19T13:04:12.004Z",
"data": {
"number": 21,
"serie": 1,
"accessKey": "33260811222333000181990010000000211208201894"
}
},
{
"eventType": "Authorized",
"version": 4,
"occurredAt": "2026-08-19T13:04:19.881Z",
"data": {
"protocol": "133260000123456",
"authorizedAt": "2026-08-19T13:04:19Z"
}
}
]
Consultar várias de uma vez
Quando o que você precisa é uma grade — o que foi emitido hoje, o que está preso em Processing, o que a SEFAZ rejeitou — a consulta em lista responde em uma chamada:
GET /v1/subscriptions/{subscriptionId}/taxpayers/{taxpayerId}/contentdeclarations
Ela aceita $filter, $orderby, $top, $skip, $count e $select, e devolve as colunas promovidas de cada documento — chave de acesso, situação, série e número, emitente, destinatário, valor total e ambiente. Itens, transporte e endereços não estão na lista: para isso é o GET {id} acima.
Três coisas que costumam pegar quem começa:
- A resposta não é um array nu. As linhas vêm em
value, no envelope OData. $toptem teto de 200, que também é o padrão. Acima disso a resposta é400; pagine com$skip.- O total vem em
@odata.count, e só quando você manda$count=true. Ele conta sob o mesmo filtro, não o tamanho da página.
Os parâmetros, o conjunto fechado de campos filtráveis e o que responde 400 estão na referência da operação.
Erros
| Código | O que significa |
|---|---|
401 | Token ausente, expirado, com audiência errada, ou chave de API no lugar de JWT |
403 | Token válido mas sem o escopo/papel da operação, ou a assinatura da URL não é do token nem acessível ao usuário (type termina em subscription-scope-undetermined) |
404 | Documento inexistente, ou fora da assinatura da URL |