API de Ocorrências
CRUD de ocorrências e eventos do sistema via API.
Gerencie ocorrências e eventos do sistema no Bunto ERP. Este endpoint permite listar, consultar, criar, atualizar e excluir ocorrências da sua empresa via API.
Base URL
Produção:
https://api-backend.bunto.com.br/v1/ocorrencias/
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: ocorrencias com a ação correspondente (read, write ou delete).
Endpoints
Listar Ocorrências
GET /v1/ocorrencias/
Escopo necessário: ocorrencias: read
Retorna a lista paginada de ocorrências ativas da empresa.
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 título ou corpo da ocorrência |
modulo | string | - | Filtrar por módulo: vendas, compras, estoque, financeiro, fiscal, clientes, produtos, servicos, logistica, crm, marketing, geral |
tipo | string | - | Filtrar por tipo: info, warning, error, success, action, audit |
status | string | - | Filtrar por status: pendente, em_andamento, concluido, cancelado, aguardando, resolvido |
prioridade | string | - | Filtrar por prioridade: baixa, media, alta, critica |
ordenar | string | data_registro | Campo de ordenação: data_registro, titulo, prioridade |
direcao | string | desc | Direção da ordenação: asc ou desc |
Exemplo com cURL
bashcurl 'https://api-backend.bunto.com.br/v1/ocorrencias/?pagina=1&por_pagina=10&modulo=vendas&prioridade=alta&ordenar=data_registro&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 ocorrências com filtros resposta = requests.get( f"{BASE_URL}/ocorrencias/", headers=headers, params={ "pagina": 1, "por_pagina": 25, "modulo": "vendas", "prioridade": "alta", "ordenar": "data_registro", "direcao": "desc", }, ) dados = resposta.json() if dados["success"]: ocorrencias = dados["data"]["resultados"] paginacao = dados["data"]["paginacao"] print(f"Total de ocorrências: {paginacao['total_registros']}") for oc in ocorrencias: print(f" - [{oc['tipo']}] {oc['titulo']} ({oc['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", modulo: "vendas", prioridade: "alta", ordenar: "data_registro", direcao: "desc", }); const resposta = await fetch(`${BASE_URL}/ocorrencias/?${params}`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const ocorrencias = dados.data.resultados; const paginacao = dados.data.paginacao; console.log(`Total de ocorrências: ${paginacao.total_registros}`); ocorrencias.forEach((oc) => { console.log(` - [${oc.tipo}] ${oc.titulo} (${oc.status})`); }); } else { console.error(`Erro: ${resposta.status}`); }
Resposta (200 OK)
json{ "success": true, "message": "38 registros encontrados", "data": { "resultados": [ { "id": 1, "modulo": "vendas", "titulo": "Pedido #1042 com divergência no valor total", "tipo": "warning", "status": "pendente", "prioridade": "alta", "data_registro": "2026-02-12T14:30:00-03:00" }, { "id": 2, "modulo": "estoque", "titulo": "Estoque negativo detectado no produto CAM-001", "tipo": "error", "status": "em_andamento", "prioridade": "critica", "data_registro": "2026-02-11T09:15:00-03:00" } ], "paginacao": { "pagina_atual": 1, "total_paginas": 2, "total_registros": 38, "por_pagina": 25, "proxima": "https://api-backend.bunto.com.br/v1/ocorrencias/?pagina=2", "anterior": null } } }
Campos da Listagem
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | Identificador único da ocorrência |
modulo | string | Módulo de origem (vendas, estoque, financeiro, etc.) |
titulo | string | Título da ocorrência |
tipo | string | Tipo: info, warning, error, success, action, audit |
status | string | Status: pendente, em_andamento, concluido, cancelado, aguardando, resolvido |
prioridade | string | Prioridade: baixa, media, alta, critica |
data_registro | datetime | Data e hora do registro da ocorrência |
Obter Ocorrência
GET /v1/ocorrencias/{id}/
Escopo necessário: ocorrencias: read
Retorna os dados completos de uma ocorrência específica, incluindo corpo da ocorrência, observações e dados de vinculação.
Exemplo com cURL
bashcurl https://api-backend.bunto.com.br/v1/ocorrencias/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", } ocorrencia_id = 1 resposta = requests.get(f"{BASE_URL}/ocorrencias/{ocorrencia_id}/", headers=headers) dados = resposta.json() if dados["success"]: oc = dados["data"] print(f"Ocorrência: {oc['titulo']}") print(f"Módulo: {oc['modulo']}") print(f"Status: {oc['status']}") print(f"Prioridade: {oc['prioridade']}") else: print(f"Erro: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const ocorrenciaId = 1; const resposta = await fetch(`${BASE_URL}/ocorrencias/${ocorrenciaId}/`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const oc = dados.data; console.log(`Ocorrência: ${oc.titulo}`); console.log(`Módulo: ${oc.modulo}`); console.log(`Status: ${oc.status}`); console.log(`Prioridade: ${oc.prioridade}`); } else { console.error(`Erro: ${JSON.stringify(dados)}`); }
Resposta (200 OK)
json{ "success": true, "message": "Registro encontrado", "data": { "id": 1, "modulo": "vendas", "titulo": "Pedido #1042 com divergência no valor total", "tipo": "warning", "status": "pendente", "prioridade": "alta", "data_registro": "2026-02-12T14:30:00-03:00", "categoria": "financeiro", "ocorrencia": "O pedido #1042 apresenta divergência de R$ 15,00 entre o valor dos itens e o valor total registrado. Verificar se houve desconto aplicado manualmente.", "observacao_pessoal": "Verificar com o vendedor responsável", "objeto_id": 1042, "objeto_tipo": "pedido", "proximo_contato": "2026-02-13T10:00:00-03:00", "data_resolucao": null, "ativo": true, "criado_em": "2026-02-12T14:30:00-03:00", "atualizado_em": "2026-02-12T14:30:00-03:00" } }
Campos do Detalhe (adicionais à listagem)
| Campo | Tipo | Descrição |
|---|---|---|
categoria | string / null | Categoria da ocorrência |
ocorrencia | string | Corpo/descrição detalhada da ocorrência |
observacao_pessoal | string / null | Observação pessoal do usuário |
objeto_id | integer / null | ID do objeto vinculado (pedido, produto, etc.) |
objeto_tipo | string / null | Tipo do objeto vinculado (pedido, produto, cliente, etc.) |
proximo_contato | datetime / null | Data/hora do próximo contato agendado |
data_resolucao | datetime / null | Data/hora em que a ocorrência foi resolvida |
ativo | boolean | Se a ocorrência está ativa no sistema |
criado_em | datetime | Data e hora de criação |
atualizado_em | datetime | Data e hora da última atualização |
Criar Ocorrência
POST /v1/ocorrencias/
Escopo necessário: ocorrencias: write
Cria uma nova ocorrência na empresa do token autenticado.
Campos do Request Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
modulo | string | Sim | Módulo de origem: vendas, compras, estoque, financeiro, fiscal, clientes, produtos, servicos, logistica, crm, marketing, geral |
titulo | string | Sim | Título da ocorrência (máximo 200 caracteres) |
tipo | string | Sim | Tipo: info, warning, error, success, action, audit |
ocorrencia | string | Sim | Corpo/descrição detalhada da ocorrência |
status | string | Não | Status: pendente (padrão), em_andamento, concluido, cancelado, aguardando, resolvido |
prioridade | string | Não | Prioridade: baixa, media (padrão), alta, critica |
categoria | string | Não | Categoria da ocorrência (máximo 100 caracteres) |
proximo_contato | datetime | Não | Data/hora do próximo contato (formato: YYYY-MM-DDTHH:MM:SS) |
objeto_id | integer | Não | ID do objeto vinculado (pedido, produto, etc.) |
objeto_tipo | string | Não | Tipo do objeto vinculado (máximo 100 caracteres) |
observacao_pessoal | string | Não | Observação pessoal do usuário |
Exemplo com cURL
bashcurl -X POST https://api-backend.bunto.com.br/v1/ocorrencias/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "modulo": "vendas", "titulo": "Cliente solicitou cancelamento do pedido #1055", "tipo": "action", "ocorrencia": "O cliente José Silva entrou em contato solicitando o cancelamento do pedido #1055. Motivo: comprou por engano. Verificar possibilidade de estorno.", "status": "pendente", "prioridade": "alta", "categoria": "cancelamento", "objeto_id": 1055, "objeto_tipo": "pedido", "proximo_contato": "2026-02-13T09:00:00" }'
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", } nova_ocorrencia = { "modulo": "vendas", "titulo": "Cliente solicitou cancelamento do pedido #1055", "tipo": "action", "ocorrencia": ( "O cliente José Silva entrou em contato solicitando o cancelamento " "do pedido #1055. Motivo: comprou por engano. Verificar possibilidade de estorno." ), "status": "pendente", "prioridade": "alta", "categoria": "cancelamento", "objeto_id": 1055, "objeto_tipo": "pedido", "proximo_contato": "2026-02-13T09:00:00", } resposta = requests.post(f"{BASE_URL}/ocorrencias/", headers=headers, json=nova_ocorrencia) dados = resposta.json() if dados["success"]: oc = dados["data"] print(f"Ocorrência criada com sucesso! ID: {oc['id']}") print(f"Título: {oc['titulo']}") else: print(f"Erro ao criar ocorrência: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const novaOcorrencia = { modulo: "vendas", titulo: "Cliente solicitou cancelamento do pedido #1055", tipo: "action", ocorrencia: "O cliente José Silva entrou em contato solicitando o cancelamento do pedido #1055. Motivo: comprou por engano. Verificar possibilidade de estorno.", status: "pendente", prioridade: "alta", categoria: "cancelamento", objeto_id: 1055, objeto_tipo: "pedido", proximo_contato: "2026-02-13T09:00:00", }; const resposta = await fetch(`${BASE_URL}/ocorrencias/`, { method: "POST", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(novaOcorrencia), }); const dados = await resposta.json(); if (dados.success) { console.log(`Ocorrência criada com sucesso! ID: ${dados.data.id}`); console.log(`Título: ${dados.data.titulo}`); } else { console.error(`Erro ao criar ocorrência:`, dados); }
Resposta (201 Created)
json{ "success": true, "message": "Ocorrência criada com sucesso", "data": { "id": 39, "modulo": "vendas", "titulo": "Cliente solicitou cancelamento do pedido #1055", "tipo": "action", "status": "pendente", "prioridade": "alta", "data_registro": "2026-02-12T16:00:00-03:00", "categoria": "cancelamento", "ocorrencia": "O cliente José Silva entrou em contato solicitando o cancelamento do pedido #1055. Motivo: comprou por engano. Verificar possibilidade de estorno.", "observacao_pessoal": null, "objeto_id": 1055, "objeto_tipo": "pedido", "proximo_contato": "2026-02-13T09:00:00-03:00", "data_resolucao": null, "ativo": true, "criado_em": "2026-02-12T16:00:00-03:00", "atualizado_em": "2026-02-12T16:00:00-03:00" } }
Atualizar Ocorrência
PUT /v1/ocorrencias/{id}/
PATCH /v1/ocorrencias/{id}/
Escopo necessário: ocorrencias: write
Atualiza uma ocorrência existente. Use PUT para atualização completa ou PATCH para atualização parcial (apenas os campos enviados serão alterados).
Exemplo com cURL (PATCH - atualização parcial)
bashcurl -X PATCH https://api-backend.bunto.com.br/v1/ocorrencias/39/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "status": "em_andamento", "observacao_pessoal": "Estorno autorizado pelo supervisor. Aguardando processamento." }'
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", } ocorrencia_id = 39 # Atualização parcial (PATCH) - apenas os campos que mudaram atualizacao = { "status": "em_andamento", "observacao_pessoal": "Estorno autorizado pelo supervisor. Aguardando processamento.", } resposta = requests.patch( f"{BASE_URL}/ocorrencias/{ocorrencia_id}/", headers=headers, json=atualizacao, ) dados = resposta.json() if dados["success"]: oc = dados["data"] print(f"Ocorrência atualizada! Status: {oc['status']}") 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 ocorrenciaId = 39; const atualizacao = { status: "em_andamento", observacao_pessoal: "Estorno autorizado pelo supervisor. Aguardando processamento.", }; const resposta = await fetch(`${BASE_URL}/ocorrencias/${ocorrenciaId}/`, { method: "PATCH", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(atualizacao), }); const dados = await resposta.json(); if (dados.success) { console.log(`Ocorrência atualizada! Status: ${dados.data.status}`); } else { console.error(`Erro ao atualizar:`, dados); }
Resposta (200 OK)
json{ "success": true, "message": "Ocorrência atualizada com sucesso", "data": { "id": 39, "modulo": "vendas", "titulo": "Cliente solicitou cancelamento do pedido #1055", "tipo": "action", "status": "em_andamento", "prioridade": "alta", "data_registro": "2026-02-12T16:00:00-03:00", "categoria": "cancelamento", "ocorrencia": "O cliente José Silva entrou em contato solicitando o cancelamento do pedido #1055. Motivo: comprou por engano. Verificar possibilidade de estorno.", "observacao_pessoal": "Estorno autorizado pelo supervisor. Aguardando processamento.", "objeto_id": 1055, "objeto_tipo": "pedido", "proximo_contato": "2026-02-13T09:00:00-03:00", "data_resolucao": null, "ativo": true, "criado_em": "2026-02-12T16:00:00-03:00", "atualizado_em": "2026-02-12T16:45:00-03:00" } }
Excluir Ocorrência (Soft Delete)
DELETE /v1/ocorrencias/{id}/
Escopo necessário: ocorrencias: delete
Desativa a ocorrência (soft delete). O registro não é removido permanentemente do banco de dados -- o campo ativo é definido como false, preservando o histórico.
Exemplo com cURL
bashcurl -X DELETE https://api-backend.bunto.com.br/v1/ocorrencias/39/ \ -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}"} ocorrencia_id = 39 resposta = requests.delete(f"{BASE_URL}/ocorrencias/{ocorrencia_id}/", headers=headers) dados = resposta.json() if dados["success"]: print(f"Ocorrência excluída com sucesso!") else: print(f"Erro ao excluir: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const ocorrenciaId = 39; const resposta = await fetch(`${BASE_URL}/ocorrencias/${ocorrenciaId}/`, { method: "DELETE", headers: { Authorization: `Bearer ${TOKEN}`, }, }); const dados = await resposta.json(); if (dados.success) { console.log("Ocorrência excluída com sucesso!"); } else { console.error(`Erro ao excluir:`, dados); }
Resposta (200 OK)
json{ "success": true, "message": "Registro excluído com sucesso" }
Importante: Ocorrências excluídas via soft delete não aparecem mais nas listagens padrão. O campo ativo é definido como false.
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 obrigatórios 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 ocorrencias ou a ação necessária (read, write, delete) | Verifique os escopos do token no painel |
| 404 | Não encontrado | Ocorrência não existe ou pertence a outra empresa | Confirme o ID e se a ocorrência pertence à empresa do token |
| 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 (400)
json{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Erro de validação", "details": { "modulo": ["Este campo é obrigatório."], "tipo": ["\"invalido\" não é um valor válido."] } } }
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 | POST, PUT, PATCH | 30 requisições/minuto |
| Exclusão | DELETE | 10 requisições/minuto |
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 ocorrências - Implemente retry com backoff exponencial ao receber
429 - Armazene dados em cache local quando possível
- Para atualizações em lote, use
PATCHapenas com os campos alterados para economizar requisições de escrita
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) |
Valores de Referência
Módulos
| Valor | Descrição |
|---|---|
vendas | Módulo de vendas e pedidos |
compras | Módulo de compras |
estoque | Módulo de estoque |
financeiro | Módulo financeiro |
fiscal | Módulo fiscal |
clientes | Módulo de clientes |
produtos | Módulo de produtos |
servicos | Módulo de serviços |
logistica | Módulo de logística |
crm | Módulo de CRM |
marketing | Módulo de marketing |
geral | Ocorrências gerais |
Tipos de Ocorrência
| Valor | Descrição |
|---|---|
info | Informação - registro informativo |
warning | Alerta - situação que requer atenção |
error | Erro - problema que precisa ser resolvido |
success | Sucesso - ação concluída com êxito |
action | Ação - tarefa pendente a ser executada |
audit | Auditoria - registro para fins de auditoria |
Status da Ocorrência
| Valor | Descrição |
|---|---|
pendente | Pendente - aguardando tratamento |
em_andamento | Em andamento - sendo tratada |
concluido | Concluído - tratamento finalizado |
cancelado | Cancelado - ocorrência cancelada |
aguardando | Aguardando - dependendo de ação externa |
resolvido | Resolvido - problema solucionado |
Prioridades
| Valor | Descrição |
|---|---|
baixa | Baixa prioridade |
media | Média prioridade |
alta | Alta prioridade |
critica | Crítica - requer atenção imediata |