API de Estoque
Consulte saldos e realize lançamentos de estoque via API. Entradas, saídas e balanços.
Consulte posições de estoque e registre lançamentos de entrada e saída via API. Diferente dos demais endpoints, o Estoque não é um CRUD tradicional -- ele permite consultar saldos por produto e criar lançamentos que afetam a quantidade disponível.
Base URL
Produção:
https://api-backend.bunto.com.br/v1/estoque/
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: estoque com a ação correspondente (read ou write).
Visão Geral
| Propriedade | Valor |
|---|---|
| Base URL | https://api-backend.bunto.com.br/v1/estoque/ |
| Autenticação | Authorization: Bearer bnt_xxx |
| Formato | JSON |
| Escopo de leitura | estoque: read |
| Escopo de escrita | estoque: write |
Diferenças em relação aos demais endpoints
O endpoint de Estoque não suporta PUT, PATCH ou DELETE. Ele funciona da seguinte forma:
| Método | Endpoint | Descrição | Escopo |
|---|---|---|---|
| GET | /v1/estoque/ | Listar posições de estoque por produto | estoque: read |
| GET | /v1/estoque/{produto_id}/ | Detalhe de estoque de um produto (com depósitos) | estoque: read |
| POST | /v1/estoque/ | Criar lançamento de estoque (entrada ou saída) | estoque: write |
Para corrigir um lançamento incorreto, crie um lançamento inverso (entrada para compensar uma saída, ou vice-versa).
Endpoints
Listar Posições de Estoque
GET /v1/estoque/
Escopo necessário: estoque: read
Retorna a lista paginada de produtos que possuem controle de estoque ativo (controlar_estoque=true), com a quantidade total em estoque de cada um.
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 ou código do produto |
com_estoque | string | - | Filtrar por situação de estoque: true (apenas com estoque > 0) ou false (apenas com estoque = 0) |
ordenar | string | nome | Campo de ordenação: nome, codigo, estoque |
direcao | string | asc | Direção da ordenação: asc ou desc |
Exemplo com cURL
bashcurl 'https://api-backend.bunto.com.br/v1/estoque/?pagina=1&por_pagina=10&com_estoque=true&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 produtos com estoque positivo resposta = requests.get( f"{BASE_URL}/estoque/", headers=headers, params={ "pagina": 1, "por_pagina": 25, "com_estoque": "true", "ordenar": "nome", "direcao": "asc", }, ) dados = resposta.json() if dados["success"]: produtos = dados["data"]["resultados"] paginacao = dados["data"]["paginacao"] print(f"Total de produtos com estoque: {paginacao['total_registros']}") for produto in produtos: print(f" - [{produto['produto_codigo']}] {produto['produto_nome']} = {produto['estoque_total']} {produto['unidade']}") 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", com_estoque: "true", ordenar: "nome", direcao: "asc", }); const resposta = await fetch(`${BASE_URL}/estoque/?${params}`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const produtos = dados.data.resultados; const paginacao = dados.data.paginacao; console.log(`Total de produtos com estoque: ${paginacao.total_registros}`); produtos.forEach((produto) => { console.log( ` - [${produto.produto_codigo}] ${produto.produto_nome} = ${produto.estoque_total} ${produto.unidade}` ); }); } else { console.error(`Erro: ${resposta.status}`); }
Resposta (200 OK)
json{ "success": true, "message": "87 registros encontrados", "data": { "resultados": [ { "produto_id": 1, "produto_nome": "Camiseta Basica Algodão", "produto_codigo": "CAM-001", "unidade": "UN", "controlar_estoque": true, "estoque_total": "154" }, { "produto_id": 15, "produto_nome": "Bermuda Jeans Masculina", "produto_codigo": "BER-002", "unidade": "UN", "controlar_estoque": true, "estoque_total": "42" }, { "produto_id": 23, "produto_nome": "Meia Esportiva Cano Médio", "produto_codigo": "MEI-010", "unidade": "PAR", "controlar_estoque": true, "estoque_total": "310" } ], "paginacao": { "pagina_atual": 1, "total_paginas": 4, "total_registros": 87, "por_pagina": 25, "proxima": "https://api-backend.bunto.com.br/v1/estoque/?pagina=2&por_pagina=25&com_estoque=true", "anterior": null } } }
Campos da Listagem
| Campo | Tipo | Descrição |
|---|---|---|
produto_id | integer | Identificador único do produto |
produto_nome | string | Nome do produto |
produto_codigo | string | Código (SKU) do produto |
unidade | string | Unidade de medida (UN, KG, L, PAR, CX, etc.) |
controlar_estoque | boolean | Sempre true (produtos sem controle de estoque não aparecem) |
estoque_total | string | Quantidade total em estoque (calculada via lançamentos) |
Detalhe de Estoque de um Produto
GET /v1/estoque/{produto_id}/
Escopo necessário: estoque: read
Retorna o estoque de um produto específico, incluindo a distribuição por depósito.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
produto_id | integer | ID do produto |
Exemplo com cURL
bashcurl https://api-backend.bunto.com.br/v1/estoque/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", } produto_id = 1 resposta = requests.get(f"{BASE_URL}/estoque/{produto_id}/", headers=headers) dados = resposta.json() if dados["success"]: estoque = dados["data"] print(f"Produto: {estoque['produto_nome']} ({estoque['produto_codigo']})") print(f"Estoque total: {estoque['estoque_total']} {estoque['unidade']}") print("Distribuicao por depósito:") for deposito in estoque["depositos"]: print(f" - {deposito['deposito_nome']}: {deposito['quantidade']} {estoque['unidade']}") else: print(f"Erro: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const produtoId = 1; const resposta = await fetch(`${BASE_URL}/estoque/${produtoId}/`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const estoque = dados.data; console.log(`Produto: ${estoque.produto_nome} (${estoque.produto_codigo})`); console.log(`Estoque total: ${estoque.estoque_total} ${estoque.unidade}`); console.log("Distribuicao por depósito:"); estoque.depositos.forEach((deposito) => { console.log(` - ${deposito.deposito_nome}: ${deposito.quantidade} ${estoque.unidade}`); }); } else { console.error(`Erro: ${JSON.stringify(dados)}`); }
Resposta (200 OK)
json{ "success": true, "message": "Registro encontrado", "data": { "produto_id": 1, "produto_nome": "Camiseta Basica Algodão", "produto_codigo": "CAM-001", "unidade": "UN", "controlar_estoque": true, "estoque_total": "154", "depositos": [ { "deposito_id": 1, "deposito_nome": "Depósito Principal", "quantidade": "120" }, { "deposito_id": 3, "deposito_nome": "Loja Centro", "quantidade": "34" } ] } }
Campos do Detalhe (adicionais à listagem)
| Campo | Tipo | Descrição |
|---|---|---|
depositos | array | Lista de depósitos com suas respectivas quantidades |
depositos[].deposito_id | integer | Identificador do depósito |
depositos[].deposito_nome | string | Nome do depósito |
depositos[].quantidade | string | Quantidade do produto neste depósito |
Criar Lançamento de Estoque
POST /v1/estoque/
Escopo necessário: estoque: write
Cria um lançamento de entrada ou saída de estoque. Este endpoint funciona de forma similar ao POST /estoque/{idProduto} de outras plataformas -- você informa o produto, o tipo de movimentação e a quantidade.
Campos do Request Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
produto_id | integer | Sim | ID do produto para movimentar estoque |
deposito_id | integer | Não | ID do depósito (usa o depósito padrão da empresa se omitido) |
tipo | string | Sim | Tipo de lançamento: "entrada" ou "saida" |
quantidade | decimal | Sim | Quantidade a movimentar (deve ser maior que 0) |
custo_unitario | decimal | Não | Custo unitário do produto (padrão: 0) |
observacao | string | Não | Observação sobre o lançamento |
Exemplo com cURL
bashcurl -X POST https://api-backend.bunto.com.br/v1/estoque/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "produto_id": 42, "tipo": "entrada", "quantidade": 10, "custo_unitario": 25.90, "observacao":"Reposição mensal - fornecedor Têxtil Brasil" }'
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", } # Registrar entrada de estoque lancamento = { "produto_id": 42, "tipo": "entrada", "quantidade": 10, "custo_unitario": 25.90, "observacao":"Reposição mensal - fornecedor Têxtil Brasil", } resposta = requests.post(f"{BASE_URL}/estoque/", headers=headers, json=lancamento) dados = resposta.json() if dados["success"]: resultado = dados["data"] print(f"Lancamento criado! ID: {resultado['id']}") print(f"Tipo: {resultado['tipo']}") print(f"Produto: {resultado['produto_nome']} (ID {resultado['produto_id']})") print(f"Depósito: {resultado['deposito_nome']}") print(f"Quantidade: {resultado['quantidade']}") else: print(f"Erro ao criar lancamento: {dados}")
Exemplo com JavaScript
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const lancamento = { produto_id: 42, tipo: "entrada", quantidade: 10, custo_unitario: 25.9, observacao: "Reposição mensal - fornecedor Têxtil Brasil", }; const resposta = await fetch(`${BASE_URL}/estoque/`, { method: "POST", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(lancamento), }); const dados = await resposta.json(); if (dados.success) { const resultado = dados.data; console.log(`Lancamento criado! ID: ${resultado.id}`); console.log(`Tipo: ${resultado.tipo}`); console.log(`Produto: ${resultado.produto_nome} (ID ${resultado.produto_id})`); console.log(`Depósito: ${resultado.deposito_nome}`); console.log(`Quantidade: ${resultado.quantidade}`); } else { console.error(`Erro ao criar lancamento:`, dados); }
Resposta (201 Created)
json{ "success": true, "message": "Entrada de estoque registrada com sucesso", "data": { "id": 456, "tipo": "entrada", "produto_id": 42, "produto_nome": "Camiseta Basica Algodão", "deposito_id": 1, "deposito_nome": "Depósito Principal", "quantidade": "10.000", "custo_unitario": "25.90", "observacao":"Reposição mensal - fornecedor Têxtil Brasil" } }
Campos da Resposta (POST)
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | Identificador do lançamento criado |
tipo | string | Tipo do lançamento: "entrada" ou "saida" |
produto_id | integer | ID do produto movimentado |
produto_nome | string | Nome do produto movimentado |
deposito_id | integer | ID do depósito utilizado |
deposito_nome | string | Nome do depósito utilizado |
quantidade | string | Quantidade movimentada (decimal com 3 casas) |
custo_unitario | string | Custo unitário informado (decimal com 2 casas) |
observacao | string | Observação do lançamento |
Operações Não Suportadas
O endpoint de Estoque não suporta as seguintes operações:
| Método | Resultado |
|---|---|
PUT /v1/estoque/{id}/ | 405 Method Not Allowed |
PATCH /v1/estoque/{id}/ | 405 Method Not Allowed |
DELETE /v1/estoque/{id}/ | 405 Method Not Allowed |
Para corrigir um lançamento incorreto, crie um lançamento inverso. Por exemplo, se foi registrada uma saída de 5 unidades por engano, crie uma entrada de 5 unidades com a observação explicando a correção:
bashcurl -X POST https://api-backend.bunto.com.br/v1/estoque/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "produto_id": 42, "tipo": "entrada", "quantidade": 5, "observacao":"Correção: estorno da saida indevida registrada em 10/02" }'
Erros Comuns
| Código | Erro | Causa | Solução |
|---|---|---|---|
| 400 | VALIDATION_ERROR | Dados inválidos (campo obrigatório ausente, quantidade <= 0, etc.) | Verifique os campos obrigatórios e os tipos de dados |
| 400 | Produto nao encontrado | Produto com o ID informado não existe ou pertence a outra empresa | Confirme o ID e se pertence à empresa do token |
| 400 | Produto nao controla estoque | O produto existe mas tem controlar_estoque=false | Ative o controle de estoque no cadastro do produto |
| 400 | Depósito nao encontrado | Depósito com o ID informado não existe ou pertence a outra empresa | Confirme o ID do depósito ou omita para usar o padrão |
| 400 | Nenhum depósito padrao | A empresa não possui depósito padrão e deposito_id não foi informado | Informe o deposito_id ou configure um depósito padrã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 estoque ou a ação necessária | Verifique os escopos do token no painel |
| 404 | Nao encontrado | Produto não encontrado na listagem de estoque | Confirme o ID e se o produto tem controlar_estoque=true |
| 429 | Limite de requisicoes excedido | Rate limit ultrapassado | Implemente retry com backoff exponencial |
Exemplo de Resposta de Erro (400) -- Validação
json{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Erro de validacao", "details": { "tipo": ["\"compra\" nao é um valor valido. Valores aceitos: entrada, saida."], "quantidade": ["Quantidade deve ser maior que zero"] } } }
Exemplo de Resposta de Erro (400) -- Produto não controla estoque
json{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Produto 'Servico de Consultoria' (ID 88) nao controla estoque" } }
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). 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 | 30 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 posições de estoque - Implemente retry com backoff exponencial ao receber
429 - Para lançamentos em lote, respeite o limite de 30 escritas/minuto (um lançamento a cada 2 segundos)
Paginação
O endpoint de listagem retorna 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) |
Cenários de Uso
Sincronização de estoque com e-commerce
Quando uma loja virtual vende produtos, registre a saída de estoque no Bunto para manter os saldos atualizados:
pythonimport requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } # Loja virtual vendeu 3 unidades da Camiseta Basica itens_vendidos = [ {"produto_id": 1, "quantidade": 3}, {"produto_id": 15, "quantidade": 1}, ] for item in itens_vendidos: lancamento = { "produto_id": item["produto_id"], "tipo": "saida", "quantidade": item["quantidade"], "observacao":f"Venda e-commerce - Pedido #WX-4521", } resposta = requests.post(f"{BASE_URL}/estoque/", headers=headers, json=lancamento) dados = resposta.json() if dados["success"]: print(f"Saida registrada: {dados['data']['produto_nome']} x {dados['data']['quantidade']}") else: print(f"Erro no produto {item['produto_id']}: {dados}")
Importação de inventário (contagem física)
Após uma contagem física, consulte o estoque atual e crie entradas ou saídas de ajuste para cada produto:
pythonimport requests from decimal import Decimal BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } # Resultado da contagem física contagem = { 1: Decimal("150"), # Camiseta Basica: contamos 150 15: Decimal("45"), # Bermuda Jeans: contamos 45 23: Decimal("298"), # Meia Esportiva: contamos 298 } for produto_id, quantidade_real in contagem.items(): # Consultar estoque atual no sistema resposta = requests.get(f"{BASE_URL}/estoque/{produto_id}/", headers=headers) dados = resposta.json() if not dados["success"]: print(f"Erro ao consultar produto {produto_id}: {dados}") continue estoque_sistema = Decimal(dados["data"]["estoque_total"]) diferenca = quantidade_real - estoque_sistema if diferenca == 0: print(f"Produto {produto_id}: estoque correto ({estoque_sistema})") continue # Criar lancamento de ajuste lancamento = { "produto_id": produto_id, "tipo": "entrada" if diferenca > 0 else "saida", "quantidade": abs(diferenca), "observacao":f"Ajuste de inventário - Contagem 12/02/2026", } resposta = requests.post(f"{BASE_URL}/estoque/", headers=headers, json=lancamento) resultado = resposta.json() if resultado["success"]: tipo_label = "entrada" if diferenca > 0 else "saida" print( f"Produto {produto_id}: ajuste de {tipo_label} de {abs(diferenca)} " f"(sistema: {estoque_sistema} -> real: {quantidade_real})" ) else: print(f"Erro no ajuste do produto {produto_id}: {resultado}")
Integração com marketplace (baixa automática)
Registre baixas de estoque quando vendas são realizadas em marketplaces como Wix ou Mercado Livre:
javascriptconst BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; /** * Registra saida de estoque para itens vendidos em marketplace. * Chamado pelo webhook do marketplace quando uma venda é confirmada. */ async function registrar_baixa_marketplace(pedido_marketplace) { const resultados = []; for (const item of pedido_marketplace.itens) { const lancamento = { produto_id: item.produto_id_bunto, tipo: "saida", quantidade: item.quantidade, observacao: `Venda ${pedido_marketplace.plataforma} - Pedido #${pedido_marketplace.numero}`, }; const resposta = await fetch(`${BASE_URL}/estoque/`, { method: "POST", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(lancamento), }); const dados = await resposta.json(); resultados.push({ produto_id: item.produto_id_bunto, sucesso: dados.success, mensagem: dados.success ? `Saida de ${dados.data.quantidade} registrada` : dados.error?.message ?? "Erro desconhecido", }); // Respeitar rate limit de escrita (30/min) await new Promise((resolve) => setTimeout(resolve, 2100)); } return resultados; } // Exemplo de uso (chamado pelo webhook do marketplace) const pedido = { plataforma: "Wix", numero: "WX-2026-0089", itens: [ { produto_id_bunto: 1, quantidade: 2 }, { produto_id_bunto: 23, quantidade: 3 }, ], }; const resultados = await registrar_baixa_marketplace(pedido); resultados.forEach((r) => { console.log(`Produto ${r.produto_id}: ${r.mensagem}`); });
Exemplo Completo -- Cliente Python
pythonimport os import time import requests from decimal import Decimal class BuntoEstoque: """Cliente para o endpoint de estoque da API v1 do Bunto ERP.""" def __init__(self, token=None): self.token = token or os.environ["BUNTO_API_TOKEN"] self.base_url = "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 posições de estoque com filtros opcionais.""" resposta = self._requisicao("GET", "/estoque/", params=filtros) return resposta.json() def obter(self, produto_id): """Obtém estoque detalhado de um produto (com depósitos).""" resposta = self._requisicao("GET", f"/estoque/{produto_id}/") return resposta.json() def registrar_entrada(self, produto_id, quantidade, deposito_id=None, custo_unitario=None, observacao=None): """Registra entrada de estoque.""" dados = { "produto_id": produto_id, "tipo": "entrada", "quantidade": float(quantidade), } if deposito_id is not None: dados["deposito_id"] = deposito_id if custo_unitario is not None: dados["custo_unitario"] = float(custo_unitario) if observacao is not None: dados["observacao"] = observacao resposta = self._requisicao("POST", "/estoque/", json=dados) return resposta.json() def registrar_saida(self, produto_id, quantidade, deposito_id=None, observacao=None): """Registra saida de estoque.""" dados = { "produto_id": produto_id, "tipo": "saida", "quantidade": float(quantidade), } if deposito_id is not None: dados["deposito_id"] = deposito_id if observacao is not None: dados["observacao"] = observacao resposta = self._requisicao("POST", "/estoque/", json=dados) return resposta.json() def listar_todos(self, **filtros): """Lista todas as posições de estoque (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 = BuntoEstoque() # Listar todos os produtos com estoque positivo produtos = api.listar_todos(com_estoque="true") print(f"Produtos com estoque: {len(produtos)}") for produto in produtos: print(f" [{produto['produto_codigo']}] {produto['produto_nome']}: {produto['estoque_total']} {produto['unidade']}") # Consultar estoque detalhado de um produto detalhe = api.obter(1) if detalhe["success"]: dados = detalhe["data"] print(f"\n{dados['produto_nome']} - Estoque total: {dados['estoque_total']}") for deposito in dados["depositos"]: print(f" {deposito['deposito_nome']}: {deposito['quantidade']}") # Registrar entrada de mercadoria resultado = api.registrar_entrada( produto_id=1, quantidade=50, custo_unitario=22.50, observacao="Compra fornecedor Têxtil Brasil - NF 12345", ) if resultado["success"]: print(f"\nEntrada registrada! ID do lancamento: {resultado['data']['id']}") # Registrar saida por venda resultado = api.registrar_saida( produto_id=1, quantidade=3, observacao="Venda balcão - Cupom FC-0891", ) if resultado["success"]: print(f"Saida registrada! ID do lancamento: {resultado['data']['id']}")
Códigos de Status HTTP
| Código | Significado | Quando ocorre |
|---|---|---|
| 200 | Sucesso | Consulta de posição de estoque (GET) |
| 201 | Criado | Lançamento de estoque criado com sucesso (POST) |
| 400 | Erro de validação | Dados inválidos, produto sem controle de estoque, depósito não encontrado |
| 401 | Não autenticado | Token ausente, inválido, expirado ou revogado |
| 403 | Sem permissão | Token não tem escopo para estoque |
| 404 | Não encontrado | Produto não encontrado na consulta de estoque |
| 405 | Método não permitido | Tentativa de usar PUT, PATCH ou DELETE |
| 429 | Muitas requisições | Rate limit excedido |
| 500 | Erro interno | Erro inesperado no servidor |