API de Arquivos
Consulta e gestão de metadados de arquivos via API.
Consulte e gerencie metadados de arquivos no Bunto ERP. Este endpoint permite listar, consultar, atualizar metadados e desativar arquivos da sua empresa via API.
Importante: O upload de arquivos não é suportado via API. Este endpoint gerencia apenas metadados de arquivos já existentes no sistema. Para fazer upload de arquivos, utilize o painel do Bunto ERP.
Base URL
Produção:
https://api-backend.bunto.com.br/v1/arquivos/
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: arquivos com a ação correspondente (read, write ou delete).
Endpoints
Listar Arquivos
GET /v1/arquivos/
Escopo necessário: arquivos: read
Retorna a lista paginada de arquivos ativos da empresa (apenas metadados).
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 nome original do arquivo |
modulo | string | - | Filtrar por módulo de origem (ex: produtos, clientes, vendas) |
tipo | string | - | Filtrar por tipo do arquivo (ex: imagem, documento, pdf, planilha) |
ordenar | string | criado_em | Campo de ordenação: nome_original, criado_em, tamanho |
direcao | string | desc | Direção da ordenação: asc ou desc |
Exemplo com cURL
bashcurl 'https://api-backend.bunto.com.br/v1/arquivos/?pagina=1&por_pagina=10&modulo=produtos&tipo=imagem&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 arquivos com filtros resposta = requests.get( f"{BASE_URL}/arquivos/", headers=headers, params={ "pagina": 1, "por_pagina": 25, "modulo": "produtos", "tipo": "imagem", "ordenar": "criado_em", "direcao": "desc", }, ) dados = resposta.json() if dados["success"]: arquivos = dados["data"]["resultados"] paginacao = dados["data"]["paginacao"] print(f"Total de arquivos: {paginacao['total_registros']}") for arq in arquivos: tamanho_kb = arq["tamanho"] / 1024 print(f" - {arq['nome_original']} ({tamanho_kb:.1f} KB) [{arq['tipo']}]") 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", modulo: "produtos", tipo: "imagem", ordenar: "criado_em", direcao: "desc", }); const resposta = await fetch(`${BASE_URL}/arquivos/?${params}`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const arquivos = dados.data.resultados; const paginacao = dados.data.paginacao; console.log(`Total de arquivos: ${paginacao.total_registros}`); arquivos.forEach((arq) => { const tamanhoKb = (arq.tamanho / 1024).toFixed(1); console.log( ` - ${arq.nome_original} (${tamanhoKb} KB) [${arq.tipo}]` ); }); } else { console.error(`Erro: ${resposta.status}`); }
Resposta (200 OK)
json{ "success": true, "message": "56 registros encontrados", "data": { "resultados": [ { "id": 1, "nome_original": "camiseta-basica-frente.jpg", "extensao": "jpg", "mime_type": "image/jpeg", "modulo": "produtos", "tipo": "imagem", "tamanho": 245760, "publico": true, "ativo": true, "criado_em": "2026-02-10T14:30:00-03:00" }, { "id": 2, "nome_original": "catalogo-verao-2026.pdf", "extensao": "pdf", "mime_type": "application/pdf", "modulo": "produtos", "tipo": "pdf", "tamanho": 5242880, "publico": false, "ativo": true, "criado_em": "2026-02-08T09:15:00-03:00" } ], "paginacao": { "pagina_atual": 1, "total_paginas": 3, "total_registros": 56, "por_pagina": 25, "proxima": "https://api-backend.bunto.com.br/v1/arquivos/?pagina=2", "anterior": null } } }
Campos da Listagem
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | Identificador único do arquivo |
nome_original | string | Nome original do arquivo (com extensão) |
extensao | string | Extensão do arquivo (jpg, pdf, xlsx, etc.) |
mime_type | string / null | Tipo MIME do arquivo (image/jpeg, application/pdf, etc.) |
modulo | string | Módulo ao qual o arquivo pertence (produtos, clientes, etc.) |
tipo | string | Tipo do arquivo (imagem, documento, pdf, planilha, etc.) |
tamanho | integer | Tamanho do arquivo em bytes |
publico | boolean | Se o arquivo é acessível publicamente |
ativo | boolean | Se o arquivo está ativo no sistema |
criado_em | datetime | Data e hora de upload do arquivo |
Obter Arquivo
GET /v1/arquivos/{id}/
Escopo necessário: arquivos: read
Retorna os metadados completos de um arquivo específico, incluindo descrição e caminho completo.
Exemplo com cURL
bashcurl https://api-backend.bunto.com.br/v1/arquivos/1/ \ -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", } arquivo_id = 1 resposta = requests.get(f"{BASE_URL}/arquivos/{arquivo_id}/", headers=headers) dados = resposta.json() if dados["success"]: arq = dados["data"] print(f"Arquivo: {arq['nome_original']}") print(f"Tipo: {arq['tipo']} ({arq['mime_type']})") tamanho_kb = arq["tamanho"] / 1024 print(f"Tamanho: {tamanho_kb:.1f} KB") print(f"Público: {'Sim' if arq['publico'] else 'Não'}") print(f"Caminho: {arq['caminho_completo']}") else: print(f"Erro: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const arquivoId = 1; const resposta = await fetch(`${BASE_URL}/arquivos/${arquivoId}/`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const arq = dados.data; console.log(`Arquivo: ${arq.nome_original}`); console.log(`Tipo: ${arq.tipo} (${arq.mime_type})`); const tamanhoKb = (arq.tamanho / 1024).toFixed(1); console.log(`Tamanho: ${tamanhoKb} KB`); console.log(`Público: ${arq.publico ? "Sim" : "Não"}`); console.log(`Caminho: ${arq.caminho_completo}`); } else { console.error(`Erro: ${JSON.stringify(dados)}`); }
Resposta (200 OK)
json{ "success": true, "message": "Registro encontrado", "data": { "id": 1, "nome_original": "camiseta-basica-frente.jpg", "extensao": "jpg", "mime_type": "image/jpeg", "modulo": "produtos", "tipo": "imagem", "tamanho": 245760, "publico": true, "ativo": true, "criado_em": "2026-02-10T14:30:00-03:00", "descricao": "Foto frontal da camiseta básica algodão - cor branca", "caminho_completo": "empresas/1/produtos/2026/02/camiseta-basica-frente.jpg", "atualizado_em": "2026-02-10T14:30:00-03:00" } }
Campos do Detalhe (adicionais à listagem)
| Campo | Tipo | Descrição |
|---|---|---|
descricao | string / null | Descrição do arquivo |
caminho_completo | string | Caminho completo do arquivo no armazenamento |
atualizado_em | datetime | Data e hora da última atualização dos metadados |
Criar Arquivo (Não Suportado)
POST /v1/arquivos/
Este endpoint retorna erro 405 (Method Not Allowed). O upload de arquivos via API não é suportado. Utilize o painel do Bunto ERP para fazer upload de arquivos.
Resposta (405 Method Not Allowed)
json{ "success": false, "error": { "code": "NOT_SUPPORTED", "message": "Upload de arquivos via API não é suportado. Utilize o painel para fazer upload de arquivos." } }
Atualizar Metadados do Arquivo
PUT /v1/arquivos/{id}/
PATCH /v1/arquivos/{id}/
Escopo necessário: arquivos: write
Atualiza apenas os metadados de um arquivo existente. O conteúdo do arquivo em si não pode ser alterado via API. Use PUT para atualização completa ou PATCH para atualização parcial.
Campos do Request Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
nome_original | string | Não | Nome original do arquivo (máximo 255 caracteres) |
modulo | string | Não | Módulo ao qual o arquivo pertence |
descricao | string | Não | Descrição do arquivo |
publico | boolean | Não | Se o arquivo é acessível publicamente (padrão: false) |
Exemplo com cURL (PATCH - atualização parcial)
bashcurl -X PATCH https://api-backend.bunto.com.br/v1/arquivos/1/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "descricao": "Foto frontal da camiseta básica algodão - cor branca, tamanho M", "publico": true }'
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", } arquivo_id = 1 # Atualização parcial (PATCH) - apenas os metadados que mudaram atualizacao = { "descricao": "Foto frontal da camiseta básica algodão - cor branca, tamanho M", "publico": True, } resposta = requests.patch( f"{BASE_URL}/arquivos/{arquivo_id}/", headers=headers, json=atualizacao, ) dados = resposta.json() if dados["success"]: arq = dados["data"] print(f"Arquivo atualizado! Descrição: {arq['descricao']}") else: print(f"Erro ao atualizar: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const arquivoId = 1; const atualizacao = { descricao: "Foto frontal da camiseta básica algodão - cor branca, tamanho M", publico: true, }; const resposta = await fetch(`${BASE_URL}/arquivos/${arquivoId}/`, { method: "PATCH", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(atualizacao), }); const dados = await resposta.json(); if (dados.success) { console.log(`Arquivo atualizado! Descrição: ${dados.data.descricao}`); } else { console.error(`Erro ao atualizar:`, dados); }
Resposta (200 OK)
json{ "success": true, "message": "Arquivo atualizado com sucesso", "data": { "id": 1, "nome_original": "camiseta-basica-frente.jpg", "extensao": "jpg", "mime_type": "image/jpeg", "modulo": "produtos", "tipo": "imagem", "tamanho": 245760, "publico": true, "ativo": true, "criado_em": "2026-02-10T14:30:00-03:00", "descricao": "Foto frontal da camiseta básica algodão - cor branca, tamanho M", "caminho_completo": "empresas/1/produtos/2026/02/camiseta-basica-frente.jpg", "atualizado_em": "2026-02-12T17:15:00-03:00" } }
Desativar Arquivo (Soft Delete)
DELETE /v1/arquivos/{id}/
Escopo necessário: arquivos: delete
Desativa o arquivo (soft delete). O registro não é removido permanentemente do banco de dados e o arquivo físico não é excluído do armazenamento -- o campo ativo é definido como false.
Exemplo com cURL
bashcurl -X DELETE https://api-backend.bunto.com.br/v1/arquivos/1/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4'
Exemplo com Python
pythonimport requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = {"Authorization": f"Bearer {TOKEN}"} arquivo_id = 1 resposta = requests.delete(f"{BASE_URL}/arquivos/{arquivo_id}/", headers=headers) dados = resposta.json() if dados["success"]: print(f"Arquivo desativado com sucesso!") else: print(f"Erro ao desativar: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const arquivoId = 1; const resposta = await fetch(`${BASE_URL}/arquivos/${arquivoId}/`, { method: "DELETE", headers: { Authorization: `Bearer ${TOKEN}`, }, }); const dados = await resposta.json(); if (dados.success) { console.log("Arquivo desativado com sucesso!"); } else { console.error(`Erro ao desativar:`, dados); }
Resposta (200 OK)
json{ "success": true, "message": "Arquivo desativado com sucesso" }
Importante: O arquivo físico não é excluído do armazenamento. Apenas o registro é desativado (campo ativo=false), impedindo que apareça nas listagens. Arquivos desativados não são exibidos nas listagens padrão.
Erros Comuns
| Código | Erro | Causa | Solução |
|---|---|---|---|
| 400 | VALIDATION_ERROR | Dados enviados são inválidos (campo obrigatório ausente, formato incorreto, etc.) | Verifique os campos e os tipos de dados |
| 401 | Token inválido | Token ausente, expirado, revogado ou mal formatado | Verifique se o header é Authorization: Bearer bnt_xxx |
| 403 | Token não tem permissão | O token não possui o escopo arquivos ou a ação necessária (read, write, delete) | Verifique os escopos do token no painel |
| 404 | Não encontrado | Arquivo não existe ou pertence a outra empresa | Confirme o ID e se o arquivo pertence à empresa do token |
| 405 | NOT_SUPPORTED | Tentativa de upload via API (POST) | O upload de arquivos deve ser feito pelo painel |
| 429 | Limite de requisições excedido | Rate limit ultrapassado para o tipo de operação | Implemente retry com backoff exponencial |
Exemplo de Resposta de Erro (405)
json{ "success": false, "error": { "code": "NOT_SUPPORTED", "message": "Upload de arquivos via API não é suportado. Utilize o painel para fazer upload de arquivos." } }
Exemplo de Resposta de Erro (403)
json{ "detail": "Token não tem permissão para este recurso" }
Rate Limiting
A API aplica limites de requisição por token (não por IP). Cada tipo de operação tem um limite diferente.
| Operação | Métodos HTTP | Limite |
|---|---|---|
| Leitura | GET, HEAD, OPTIONS | 120 requisições/minuto |
| Escrita | PUT, PATCH | 30 requisições/minuto |
| Exclusão | DELETE | 10 requisições/minuto |
Nota: O método POST não é suportado neste endpoint (retorna 405).
Ao exceder o limite, a API retorna 429 Too Many Requests:
json{ "detail": "Limite de requisições excedido. Tente novamente em 45 segundos." }
Boas práticas
- Use
por_pagina=100para reduzir o número de requisições ao listar arquivos - Implemente retry com backoff exponencial ao receber
429 - Use os filtros
moduloetipopara reduzir o volume de dados retornados - Para atualizações em lote de metadados, use
PATCHapenas com os campos alterados
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) |
Limitações
- Upload não suportado: Não é possível fazer upload de arquivos via API. Use o painel do Bunto ERP.
- Conteúdo imutável: O conteúdo do arquivo em si não pode ser alterado via API, apenas seus metadados.
- Somente metadados: Este endpoint não retorna o conteúdo binário do arquivo, apenas informações sobre ele.
- Soft delete: Ao desativar um arquivo, o arquivo físico permanece no armazenamento. A desativação apenas impede que ele apareça nas listagens.