API de Distribuição DFe
Consulta de documentos fiscais recebidos via DFe (somente leitura).
Consulte documentos fiscais recebidos via Distribuição DFe (MDe/SEFAZ) no Bunto ERP. Este endpoint permite listar e consultar notas fiscais eletrônicas destinadas à empresa de forma somente leitura via API.
Base URL
Produção:
https://api-backend.bunto.com.br/v1/distribuicao-dfe/
Autenticação
Todas as requisições exigem um Token de API no header Authorization:
Authorization: Bearer bnt_seu_token_aqui
Tokens são gerados em Integrações -> Tokens de API no painel do Bunto ERP. Escopo necessário: distribuicao_dfe com a ação read.
Endpoints
Listar Documentos DFe
GET /v1/distribuicao-dfe/
Escopo necessário: distribuicao_dfe: read
Retorna a lista paginada de documentos fiscais recebidos via Distribuição DFe. Por padrão, os resultados são ordenados pela data de criação mais recente.
Query Parameters
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
pagina | integer | 1 | Número da página |
por_pagina | integer | 25 | Registros por página (máximo: 100) |
busca | string | - | Busca por chave de acesso, CNPJ do emitente, nome do emitente ou número da NF |
status | string | - | Filtrar por status: PENDENTE, CIENCIA, CONFIRMADO, DESCONHECIDO, NAO_REALIZADO, IMPORTADO ou IGNORADO |
data_inicio | string | - | Data inicial do período (formato: YYYY-MM-DD) |
data_fim | string | - | Data final do período (formato: YYYY-MM-DD) |
ordenar | string | criado_em | Campo de ordenação: criado_em, valor_nf, data_emissao, nsu |
direcao | string | desc | Direção da ordenação: asc ou desc |
Exemplo com cURL
bashcurl 'https://api-backend.bunto.com.br/v1/distribuicao-dfe/?pagina=1&por_pagina=10&status=PENDENTE&ordenar=criado_em&direcao=desc' \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json'
Exemplo com Python
pythonimport requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } # Listar documentos DFe pendentes resposta = requests.get( f"{BASE_URL}/distribuicao-dfe/", headers=headers, params={ "pagina": 1, "por_pagina": 25, "status": "PENDENTE", "ordenar": "criado_em", "direcao": "desc", }, ) dados = resposta.json() if dados["success"]: documentos = dados["data"]["resultados"] paginacao = dados["data"]["paginacao"] print(f"Total de documentos: {paginacao['total_registros']}") for doc in documentos: print(f" - NF {doc['numero_nf']}/{doc['serie_nf']} | {doc['emitente_nome']} | R$ {doc['valor_nf']} | {doc['status']}") else: print(f"Erro: {resposta.status_code}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const params = new URLSearchParams({ pagina: "1", por_pagina: "25", status: "PENDENTE", ordenar: "criado_em", direcao: "desc", }); const resposta = await fetch(`${BASE_URL}/distribuicao-dfe/?${params}`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const documentos = dados.data.resultados; const paginacao = dados.data.paginacao; console.log(`Total de documentos: ${paginacao.total_registros}`); documentos.forEach((doc) => { console.log(` - NF ${doc.numero_nf}/${doc.serie_nf} | ${doc.emitente_nome} | R$ ${doc.valor_nf} | ${doc.status}`); }); } else { console.error(`Erro: ${resposta.status}`); }
Resposta (200 OK)
json{ "success": true, "message": "12 registros encontrados", "data": { "resultados": [ { "id": 150, "nsu": "000000000012345", "chave": "35260212345678000190550010000001231123456789", "status": "PENDENTE", "emitente_cnpj": "12.345.678/0001-90", "emitente_nome": "Distribuidora Exemplo LTDA", "numero_nf": "123", "serie_nf": "1", "valor_nf": "1580.00", "data_emissao": "2026-02-10T08:00:00-03:00", "tem_xml_completo": false, "pre_entrada_id": null }, { "id": 149, "nsu": "000000000012344", "chave": "35260298765432000150550010000004561987654321", "status": "PENDENTE", "emitente_cnpj": "98.765.432/0001-50", "emitente_nome": "Fornecedor ABC S.A.", "numero_nf": "456", "serie_nf": "1", "valor_nf": "3200.75", "data_emissao": "2026-02-09T14:30:00-03:00", "tem_xml_completo": true, "pre_entrada_id": null } ], "paginacao": { "pagina_atual": 1, "total_paginas": 1, "total_registros": 12, "por_pagina": 25, "proxima": null, "anterior": null } } }
Campos da Listagem
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | Identificador único do documento DFe |
nsu | string | Número Sequencial Único (NSU) do documento na SEFAZ |
chave | string | Chave de acesso da NF-e (44 dígitos) |
status | string | Status do documento: PENDENTE, CIENCIA, CONFIRMADO, DESCONHECIDO, NAO_REALIZADO, IMPORTADO ou IGNORADO |
emitente_cnpj | string | CNPJ do emitente da nota fiscal |
emitente_nome | string | Nome/razão social do emitente |
numero_nf | string | Número da nota fiscal |
serie_nf | string | Série da nota fiscal |
valor_nf | decimal | Valor total da nota fiscal |
data_emissao | datetime / null | Data e hora de emissão da nota fiscal |
tem_xml_completo | boolean | Se o XML completo da NF-e já foi baixado |
pre_entrada_id | integer / null | ID da pré-entrada vinculada (null se não vinculada) |
Obter Documento DFe
GET /v1/distribuicao-dfe/{id}/
Escopo necessário: distribuicao_dfe: read
Retorna os dados completos de um documento DFe específico, incluindo informações adicionais como schema, tipo da NF, inscrição estadual do emitente, dados extras e datas de criação e atualização.
Exemplo com cURL
bashcurl https://api-backend.bunto.com.br/v1/distribuicao-dfe/150/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json'
Exemplo com Python
pythonimport requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } documento_id = 150 resposta = requests.get(f"{BASE_URL}/distribuicao-dfe/{documento_id}/", headers=headers) dados = resposta.json() if dados["success"]: doc = dados["data"] print(f"NF-e: {doc['numero_nf']}/{doc['serie_nf']}") print(f"Chave: {doc['chave']}") print(f"Emitente: {doc['emitente_nome']} ({doc['emitente_cnpj']})") print(f"Valor: R$ {doc['valor_nf']}") print(f"Status: {doc['status']}") print(f"XML completo: {'Sim' if doc['tem_xml_completo'] else 'Nao'}") else: print(f"Erro: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const documentoId = 150; const resposta = await fetch(`${BASE_URL}/distribuicao-dfe/${documentoId}/`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const doc = dados.data; console.log(`NF-e: ${doc.numero_nf}/${doc.serie_nf}`); console.log(`Chave: ${doc.chave}`); console.log(`Emitente: ${doc.emitente_nome} (${doc.emitente_cnpj})`); console.log(`Valor: R$ ${doc.valor_nf}`); console.log(`Status: ${doc.status}`); console.log(`XML completo: ${doc.tem_xml_completo ? "Sim" : "Nao"}`); } else { console.error(`Erro: ${JSON.stringify(dados)}`); }
Resposta (200 OK)
json{ "success": true, "message": "Registro encontrado", "data": { "id": 150, "nsu": "000000000012345", "chave": "35260212345678000190550010000001231123456789", "status": "PENDENTE", "emitente_cnpj": "12.345.678/0001-90", "emitente_nome": "Distribuidora Exemplo LTDA", "numero_nf": "123", "serie_nf": "1", "valor_nf": "1580.00", "data_emissao": "2026-02-10T08:00:00-03:00", "tem_xml_completo": false, "pre_entrada_id": null, "schema": "resNFe", "tipo_nf": "1", "emitente_ie": "123456789012", "dados_extras": { "natureza_operacao": "VENDA DE MERCADORIA", "protocolo": "135260000012345" }, "nf_documento_id": null, "data_criacao": "2026-02-10T10:30:00-03:00", "data_atualizacao": "2026-02-10T10:30:00-03:00" } }
Campos do Detalhe (adicionais à listagem)
| Campo | Tipo | Descrição |
|---|---|---|
schema | string | Schema do documento recebido (ex: resNFe, procNFe, resEvento) |
tipo_nf | string | Tipo da nota fiscal (1 = Saída, 0 = Entrada) |
emitente_ie | string / null | Inscrição estadual do emitente |
dados_extras | object | Dados adicionais extraídos do XML (estrutura variável conforme o schema) |
nf_documento_id | integer / null | ID do documento fiscal vinculado no sistema (null se não vinculado) |
data_criacao | datetime | Data e hora de criação do registro |
data_atualizacao | datetime | Data e hora da última atualização |
Status dos Documentos
Os documentos DFe possuem os seguintes status possíveis:
| Status | Descrição |
|---|---|
PENDENTE | Documento recebido, aguardando manifestação do destinatário |
CIENCIA | Ciência da operação registrada na SEFAZ |
CONFIRMADO | Operação confirmada pelo destinatário |
DESCONHECIDO | Operação desconhecida pelo destinatário |
NAO_REALIZADO | Operação não realizada |
IMPORTADO | Documento importado para o sistema (entrada de mercadorias) |
IGNORADO | Documento ignorado pelo usuário |
Erros Comuns
| Código | Erro | Causa | Solução |
|---|---|---|---|
| 401 | Token invalido | Token ausente, expirado, revogado ou mal formatado | Verifique se o header é Authorization: Bearer bnt_xxx |
| 403 | Token nao tem permissao | O token não possui o escopo distribuicao_dfe ou a ação read | Verifique os escopos do token no painel |
| 404 | Nao encontrado | Documento não existe ou pertence a outra empresa | Confirme o ID e se o documento pertence à empresa do token |
| 429 | Limite de requisicoes excedido | Rate limit ultrapassado | Implemente retry com backoff exponencial |
Exemplo de Resposta de Erro (403)
json{ "detail": "Token nao tem permissao para este recurso" }
Rate Limiting
A API aplica limites de requisição por token (não por IP).
| Operação | Métodos HTTP | Limite |
|---|---|---|
| Leitura | GET, HEAD, OPTIONS | 120 requisições/minuto |
Ao exceder o limite, a API retorna 429 Too Many Requests:
json{ "detail": "Limite de requisicoes excedido. Tente novamente em 45 segundos." }
Boas práticas
- Use
por_pagina=100para reduzir o número de requisições ao listar documentos - Implemente retry com backoff exponencial ao receber
429 - Armazene dados em cache local quando possível
- Use os filtros
data_inicio,data_fimestatuspara limitar o volume de dados retornados - Filtre por
status=PENDENTEpara identificar documentos que precisam de manifestação
Paginação
Todos os endpoints de listagem retornam dados paginados.
Parâmetros
| Parâmetro | Tipo | Padrão | Máximo | Descrição |
|---|---|---|---|---|
pagina | integer | 1 | - | Número da página |
por_pagina | integer | 25 | 100 | Registros por página |
Atenção: Os parâmetros são pagina e por_pagina (em português), não page e per_page.
Objeto paginacao na resposta
| Campo | Tipo | Descrição |
|---|---|---|
pagina_atual | integer | Número da página atual |
total_paginas | integer | Total de páginas disponíveis |
total_registros | integer | Total de registros encontrados |
por_pagina | integer | Registros por página |
proxima | string / null | URL da próxima página (null se for a última) |
anterior | string / null | URL da página anterior (null se for a primeira) |
Exemplo: percorrer todas as páginas (Python)
pythonimport requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = {"Authorization": f"Bearer {TOKEN}"} todos_os_documentos = [] url = f"{BASE_URL}/distribuicao-dfe/?por_pagina=100&status=PENDENTE" while url: resposta = requests.get(url, headers=headers) dados = resposta.json() if not dados["success"]: break todos_os_documentos.extend(dados["data"]["resultados"]) url = dados["data"]["paginacao"]["proxima"] print(f"Total obtido: {len(todos_os_documentos)} documentos DFe")