API de Marcadores
CRUD completo de marcadores (tags coloridas) via API. Organize registros com tags visuais por módulo.
Gerencie marcadores (tags coloridas) para organizar registros em diferentes módulos do Bunto ERP. Marcadores permitem categorizar e filtrar vendas, produtos, clientes e outros registros de forma visual, com cores personalizadas.
Visão Geral
| Propriedade | Valor |
|---|---|
| Base URL (produção) | https://api-backend.bunto.com.br/v1/marcadores/ |
| Autenticação | Authorization: Bearer bnt_xxx |
| Formato | JSON |
| Escopo necessário (leitura) | marcadores: read |
| Escopo necessário (escrita) | marcadores: write |
| Escopo necessário (exclusão) | marcadores: delete |
Endpoints
| Método | Endpoint | Descrição | Escopo |
|---|---|---|---|
| GET | /v1/marcadores/ | Listar marcadores | marcadores: read |
| GET | /v1/marcadores/{id}/ | Detalhar marcador | marcadores: read |
| POST | /v1/marcadores/ | Criar marcador | marcadores: write |
| PUT | /v1/marcadores/{id}/ | Atualizar marcador (completo) | marcadores: write |
| PATCH | /v1/marcadores/{id}/ | Atualizar marcador (parcial) | marcadores: write |
| DELETE | /v1/marcadores/{id}/ | Excluir marcador (permanente) | marcadores: delete |
Atenção: A exclusão de marcadores é permanente (hard delete). O registro é removido definitivamente do banco de dados e não pode ser recuperado.
Listar Marcadores
GET /v1/marcadores/
Escopo necessário: marcadores: read
Retorna a lista paginada de marcadores da empresa.
Parâmetros de consulta
| 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 do marcador |
modulo | string | - | Filtrar por módulo (ex: produtos, vendas, clientes) |
ordenar | string | nome | Campo de ordenação: nome, modulo, criado_em |
direcao | string | asc | Direção da ordenação: asc ou desc |
Campos retornados na listagem
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | Identificador único do marcador |
nome | string | Nome do marcador |
slug | string | Slug gerado automaticamente a partir do nome |
cor | string | Cor em formato hexadecimal (ex: #0010FE) |
modulo | string | Módulo ao qual o marcador pertence |
Exemplo com cURL
bashcurl 'https://api-backend.bunto.com.br/v1/marcadores/?pagina=1&por_pagina=10&modulo=produtos&ordenar=nome&direcao=asc' \ -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 marcadores do modulo de produtos resposta = requests.get( f"{BASE_URL}/marcadores/", headers=headers, params={ "pagina": 1, "por_pagina": 25, "modulo":"produtos", "ordenar": "nome", "direcao": "asc", }, ) dados = resposta.json() if dados["success"]: marcadores = dados["data"]["resultados"] paginacao = dados["data"]["paginacao"] print(f"Total de marcadores: {paginacao['total_registros']}") for marcador in marcadores: print(f" - [{marcador['cor']}] {marcador['nome']} ({marcador['modulo']})") 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", ordenar: "nome", direcao: "asc", }); const resposta = await fetch(`${BASE_URL}/marcadores/?${params}`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const marcadores = dados.data.resultados; const paginacao = dados.data.paginacao; console.log(`Total de marcadores: ${paginacao.total_registros}`); marcadores.forEach((marcador) => { console.log(` - [${marcador.cor}] ${marcador.nome} (${marcador.modulo})`); }); } else { console.error(`Erro: ${resposta.status}`); }
Resposta de sucesso (200)
json{ "success": true, "message": "8 registros encontrados", "data": { "resultados": [ { "id": 1, "nome": "Destaque", "slug": "destaque", "cor": "#0010FE", "modulo":"produtos" }, { "id": 2, "nome": "Em promoção", "slug": "em-promocao", "cor": "#E53E3E", "modulo":"produtos" }, { "id": 3, "nome": "Novo", "slug": "novo", "cor": "#38A169", "modulo":"produtos" } ], "paginacao": { "pagina_atual": 1, "total_paginas": 1, "total_registros": 8, "por_pagina": 25, "proxima": null, "anterior": null } } }
Detalhar Marcador
GET /v1/marcadores/{id}/
Escopo necessário: marcadores: read
Retorna todos os dados de um marcador específico, incluindo as datas de criação e atualização.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
id | integer | ID do marcador |
Campos retornados no detalhe
Além de todos os campos da listagem, o detalhe inclui:
| Campo | Tipo | Descrição |
|---|---|---|
criado_em | datetime | Data e hora de criação do marcador |
atualizado_em | datetime | Data e hora da última atualização |
Exemplo com cURL
bashcurl https://api-backend.bunto.com.br/v1/marcadores/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", } marcador_id = 1 resposta = requests.get(f"{BASE_URL}/marcadores/{marcador_id}/", headers=headers) dados = resposta.json() if dados["success"]: marcador = dados["data"] print(f"Marcador: {marcador['nome']}") print(f"Cor: {marcador['cor']}") print(f"Modulo: {marcador['modulo']}") print(f"Criado em: {marcador['criado_em']}") else: print(f"Erro: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const marcadorId = 1; const resposta = await fetch(`${BASE_URL}/marcadores/${marcadorId}/`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const marcador = dados.data; console.log(`Marcador: ${marcador.nome}`); console.log(`Cor: ${marcador.cor}`); console.log(`Modulo: ${marcador.modulo}`); console.log(`Criado em: ${marcador.criado_em}`); } else { console.error(`Erro: ${JSON.stringify(dados)}`); }
Resposta de sucesso (200)
json{ "success": true, "message": "Registro encontrado", "data": { "id": 1, "nome": "Destaque", "slug": "destaque", "cor": "#0010FE", "modulo":"produtos", "criado_em": "2026-01-10T09:00:00-03:00", "atualizado_em": "2026-02-05T14:30:00-03:00" } }
Criar Marcador
POST /v1/marcadores/
Escopo necessário: marcadores: write
Cria um novo marcador na empresa do token autenticado. O campo slug é gerado automaticamente a partir do nome.
Campos do body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
nome | string | Sim | Nome do marcador (máximo 100 caracteres) |
cor | string | Não | Cor em formato hexadecimal (padrão: #0010FE) |
modulo | string | Não | Módulo ao qual o marcador pertence (padrão: produtos) |
Valores válidos para modulo
| Valor | Descrição |
|---|---|
vendas | Módulo de vendas |
estoque | Módulo de estoque |
produtos | Módulo de produtos (padrão) |
clientes | Módulo de clientes |
fornecedores | Módulo de fornecedores |
compras | Módulo de compras |
financeiro | Módulo financeiro |
expedicao | Módulo de expedição |
distribuição_dfe | Módulo de distribuição DF-e |
Exemplo com cURL
bashcurl -X POST https://api-backend.bunto.com.br/v1/marcadores/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "nome": "Prioridade alta", "cor": "#E53E3E", "modulo":"vendas" }'
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", } novo_marcador = { "nome": "Prioridade alta", "cor": "#E53E3E", "modulo":"vendas", } resposta = requests.post(f"{BASE_URL}/marcadores/", headers=headers, json=novo_marcador) dados = resposta.json() if dados["success"]: marcador = dados["data"] print(f"Marcador criado com sucesso! ID: {marcador['id']}") print(f"Nome: {marcador['nome']}") print(f"Slug: {marcador['slug']}") else: print(f"Erro ao criar marcador: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const novoMarcador = { nome: "Prioridade alta", cor: "#E53E3E", modulo: "vendas", }; const resposta = await fetch(`${BASE_URL}/marcadores/`, { method: "POST", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(novoMarcador), }); const dados = await resposta.json(); if (dados.success) { console.log(`Marcador criado com sucesso! ID: ${dados.data.id}`); console.log(`Nome: ${dados.data.nome}`); console.log(`Slug: ${dados.data.slug}`); } else { console.error(`Erro ao criar marcador:`, dados); }
Resposta de sucesso (201)
json{ "success": true, "message": "Registro criado com sucesso", "data": { "id": 15, "nome": "Prioridade alta", "slug": "prioridade-alta", "cor": "#E53E3E", "modulo":"vendas", "criado_em": "2026-02-12T16:00:00-03:00", "atualizado_em": "2026-02-12T16:00:00-03:00" } }
Nota: O campo slug é gerado automaticamente a partir do nome. No exemplo acima, "Prioridade alta" gera o slug prioridade-alta. Se já existir um marcador com o mesmo slug na empresa, um sufixo numérico será adicionado (ex: prioridade-alta-2).
Atualizar Marcador
Atualização completa
PUT /v1/marcadores/{id}/
Atualiza todos os campos do marcador. Campos não enviados serão definidos com seus valores padrão.
Atualização parcial
PATCH /v1/marcadores/{id}/
Atualiza apenas os campos enviados no body. Campos omitidos permanecem inalterados.
Escopo necessário: marcadores: write
Exemplo com cURL (PATCH)
bashcurl -X PATCH https://api-backend.bunto.com.br/v1/marcadores/15/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "nome": "Urgente", "cor": "#C53030" }'
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", } marcador_id = 15 # Atualizacao parcial (PATCH) - apenas os campos que mudaram atualizacao = { "nome": "Urgente", "cor": "#C53030", } resposta = requests.patch( f"{BASE_URL}/marcadores/{marcador_id}/", headers=headers, json=atualizacao, ) dados = resposta.json() if dados["success"]: marcador = dados["data"] print(f"Marcador atualizado! Novo nome: {marcador['nome']}") print(f"Novo slug: {marcador['slug']}") 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 marcadorId = 15; const atualizacao = { nome: "Urgente", cor: "#C53030", }; const resposta = await fetch(`${BASE_URL}/marcadores/${marcadorId}/`, { method: "PATCH", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(atualizacao), }); const dados = await resposta.json(); if (dados.success) { console.log(`Marcador atualizado! Novo nome: ${dados.data.nome}`); console.log(`Novo slug: ${dados.data.slug}`); } else { console.error(`Erro ao atualizar:`, dados); }
Resposta de sucesso (200)
json{ "success": true, "message": "Registro atualizado com sucesso", "data": { "id": 15, "nome": "Urgente", "slug": "urgente", "cor": "#C53030", "modulo":"vendas", "criado_em": "2026-02-12T16:00:00-03:00", "atualizado_em": "2026-02-12T16:45:00-03:00" } }
Nota: Ao alterar o nome, o slug é regenerado automaticamente.
Excluir Marcador (Hard Delete)
DELETE /v1/marcadores/{id}/
Escopo necessário: marcadores: delete
Remove permanentemente um marcador do banco de dados. Esta operação não pode ser desfeita. Todos os vínculos entre o marcador e os registros dos módulos serão removidos.
Atenção: Diferente de outros endpoints do Bunto ERP que utilizam soft delete, a exclusão de marcadores é permanente (hard delete). O registro é apagado definitivamente e não pode ser recuperado.
Exemplo com cURL
bashcurl -X DELETE https://api-backend.bunto.com.br/v1/marcadores/15/ \ -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}"} marcador_id = 15 resposta = requests.delete(f"{BASE_URL}/marcadores/{marcador_id}/", headers=headers) dados = resposta.json() if dados["success"]: print("Marcador excluído permanentemente!") else: print(f"Erro ao excluir: {dados['message']}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const marcadorId = 15; const resposta = await fetch(`${BASE_URL}/marcadores/${marcadorId}/`, { method: "DELETE", headers: { Authorization: `Bearer ${TOKEN}`, }, }); const dados = await resposta.json(); if (dados.success) { console.log("Marcador excluído permanentemente!"); } else { console.error(`Erro ao excluir: ${dados.message}`); }
Resposta de sucesso (200)
json{ "success": true, "message": "Registro excluído com sucesso" }
Erros
Validação (400)
Retornado quando os dados enviados são inválidos.
json{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Erro de validacao", "details": { "nome": ["Este campo é obrigatorio."], "cor": ["Informe uma cor hexadecimal valida (ex: #FF0000)."], "modulo": ["\"abc\" nao é uma opcao valida."] } } }
Não autenticado (401)
json{ "detail": "Token invalido" }
Sem permissão (403)
Retornado quando o token não possui o escopo necessário.
json{ "detail": "Token nao tem permissao para este recurso" }
Não encontrado (404)
Retornado quando o marcador não existe ou pertence a outra empresa.
json{ "success": false, "error": { "code": "NOT_FOUND", "message": "Registro nao encontrado" } }
Rate limit excedido (429)
json{ "detail": "Limite de requisicoes excedido. Tente novamente em 45 segundos." }
Códigos de Status HTTP
| Código | Significado | Quando ocorre |
|---|---|---|
| 200 | Sucesso | Consulta, atualização ou exclusão bem-sucedida |
| 201 | Criado | Marcador criado com sucesso via POST |
| 400 | Erro de validação | Dados inválidos (nome ausente, cor em formato incorreto, módulo inválido) |
| 401 | Não autenticado | Token ausente, inválido, expirado ou revogado |
| 403 | Sem permissão | Token não tem escopo para marcadores |
| 404 | Não encontrado | Marcador não existe ou pertence a outra empresa |
| 429 | Muitas requisições | Rate limit excedido |
| 500 | Erro interno | Erro inesperado no servidor |
Rate Limiting
Os limites de requisição são aplicados por token.
| Operação | Métodos | 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. Implemente retry com backoff exponencial para lidar com esses casos.
Paginação
Endpoints de listagem retornam dados paginados.
| 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 |
Nota: 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) |
Navegação entre páginas (Python)
pythonimport requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = {"Authorization": f"Bearer {TOKEN}"} todos_marcadores = [] url = f"{BASE_URL}/marcadores/?por_pagina=100" while url: resposta = requests.get(url, headers=headers) dados = resposta.json() if not dados["success"]: break todos_marcadores.extend(dados["data"]["resultados"]) url = dados["data"]["paginacao"]["proxima"] print(f"Total obtido: {len(todos_marcadores)} marcadores")
Valores de Referência
Módulos disponíveis
| Valor | Descrição |
|---|---|
vendas | Módulo de vendas |
estoque | Módulo de estoque |
produtos | Módulo de produtos (padrão) |
clientes | Módulo de clientes |
fornecedores | Módulo de fornecedores |
compras | Módulo de compras |
financeiro | Módulo financeiro |
expedicao | Módulo de expedição |
distribuição_dfe | Módulo de distribuição DF-e |
Cor padrão
Quando o campo cor não é informado na criação, o valor padrão utilizado é #0010FE (azul vibrante da paleta oficial do Bunto).
Exemplos Completos
Gerenciar marcadores por módulo (Python)
pythonimport os import time import requests class BuntoMarcadores: """Cliente para o endpoint de marcadores da API v1 do Bunto ERP.""" def __init__(self, token=None, base_url=None): self.token = token or os.environ["BUNTO_API_TOKEN"] self.base_url = base_url or "https://api-backend.bunto.com.br/v1" self.session = requests.Session() self.session.headers.update({ "Authorization": f"Bearer {self.token}", "Content-Type": "application/json", }) def _requisicao(self, metodo, endpoint, **kwargs): """Executa requisicao com retry para rate limit.""" url = f"{self.base_url}/{endpoint.lstrip('/')}" for tentativa in range(3): resposta = self.session.request(metodo, url, **kwargs) if resposta.status_code == 429: tempo = 2 ** tentativa * 15 print(f"Rate limit. Aguardando {tempo}s...") time.sleep(tempo) continue return resposta raise Exception("Limite de tentativas excedido") def listar(self, **filtros): """Lista marcadores com filtros opcionais.""" resposta = self._requisicao("GET", "/marcadores/", params=filtros) return resposta.json() def obter(self, marcador_id): """Obtém detalhes de um marcador.""" resposta = self._requisicao("GET", f"/marcadores/{marcador_id}/") return resposta.json() def criar(self, dados): """Cria um novo marcador.""" resposta = self._requisicao("POST", "/marcadores/", json=dados) return resposta.json() def atualizar(self, marcador_id, dados): """Atualiza parcialmente um marcador.""" resposta = self._requisicao("PATCH", f"/marcadores/{marcador_id}/", json=dados) return resposta.json() def excluir(self, marcador_id): """Exclui permanentemente um marcador.""" resposta = self._requisicao("DELETE", f"/marcadores/{marcador_id}/") return resposta.json() def listar_todos(self, **filtros): """Lista todos os marcadores (com paginacao automatica).""" filtros["por_pagina"] = 100 filtros["pagina"] = 1 todos = [] while True: resultado = self.listar(**filtros) if not resultado["success"]: break todos.extend(resultado["data"]["resultados"]) paginacao = resultado["data"]["paginacao"] if paginacao["proxima"] is None: break filtros["pagina"] += 1 return todos # Uso api = BuntoMarcadores() # Listar todos os marcadores do modulo de vendas marcadores_vendas = api.listar_todos(modulo="vendas") print(f"Total de marcadores em vendas: {len(marcadores_vendas)}") # Criar marcadores padrao para um novo modulo marcadores_padrao = [ {"nome": "Pendente", "cor": "#ECC94B", "modulo":"compras"}, {"nome": "Aprovado", "cor": "#38A169", "modulo":"compras"}, {"nome": "Recusado", "cor": "#E53E3E", "modulo":"compras"}, {"nome": "Em análise", "cor": "#3182CE", "modulo":"compras"}, ] for marcador in marcadores_padrao: resultado = api.criar(marcador) if resultado["success"]: print(f"Criado: {marcador['nome']} (ID: {resultado['data']['id']}, slug: {resultado['data']['slug']})") else: print(f"Erro ao criar {marcador['nome']}: {resultado}") # Respeitar rate limit de escrita (30/min) time.sleep(2.1)
Sincronizar marcadores entre módulos (JavaScript/Node.js)
javascriptclass BuntoMarcadores { constructor(token, baseUrl = null) { this.token = token ?? process.env.BUNTO_API_TOKEN; this.baseUrl = baseUrl ?? "https://api-backend.bunto.com.br/v1"; this.headers = { Authorization: `Bearer ${this.token}`, "Content-Type": "application/json", }; } async requisicao(metodo, endpoint, opcoes = {}) { const url = `${this.baseUrl}/${endpoint.replace(/^\//, "")}`; for (let tentativa = 0; tentativa < 3; tentativa++) { const resposta = await fetch(url, { method: metodo, headers: this.headers, ...opcoes, }); if (resposta.status === 429) { const tempo = 2 ** tentativa * 15 * 1000; console.log(`Rate limit. Aguardando ${tempo / 1000}s...`); await new Promise((resolve) => setTimeout(resolve, tempo)); continue; } return resposta.json(); } throw new Error("Limite de tentativas excedido"); } async listar(filtros = {}) { const params = new URLSearchParams(filtros); return this.requisicao("GET", `marcadores/?${params}`); } async criar(dados) { return this.requisicao("POST", "marcadores/", { body: JSON.stringify(dados), }); } async atualizar(marcadorId, dados) { return this.requisicao("PATCH", `marcadores/${marcadorId}/`, { body: JSON.stringify(dados), }); } async excluir(marcadorId) { return this.requisicao("DELETE", `marcadores/${marcadorId}/`); } } // Copiar marcadores de um modulo para outro const api = new BuntoMarcadores(); const resultado = await api.listar({ modulo: "produtos", por_pagina: "100" }); if (resultado.success) { const marcadoresProdutos = resultado.data.resultados; console.log(`Encontrados ${marcadoresProdutos.length} marcadores em produtos`); for (const marcador of marcadoresProdutos) { const novoMarcador = await api.criar({ nome: marcador.nome, cor: marcador.cor, modulo: "estoque", }); if (novoMarcador.success) { console.log(`Copiado: ${marcador.nome} -> estoque (ID: ${novoMarcador.data.id})`); } else { console.error(`Erro ao copiar ${marcador.nome}:`, novoMarcador); } // Respeitar rate limit de escrita (30/min) await new Promise((resolve) => setTimeout(resolve, 2100)); } }