Developers/Documentação da API/API de Vendas

API de Vendas

CRUD completo de pedidos de venda via API. Crie pedidos com itens, gerencie situações e cancele vendas.

13/02/202621 min de leitura7 visualizações

Gerencie pedidos de venda e orçamentos da sua empresa via API. Consulte, crie, atualize e cancele pedidos de forma programática.


Visão Geral

PropriedadeValor
Base URL (produção)https://api-backend.bunto.com.br/v1/vendas/
AutenticaçãoAuthorization: Bearer bnt_xxx
FormatoJSON
Escopo necessário (leitura)vendas: read
Escopo necessário (escrita)vendas: write
Escopo necessário (cancelamento)vendas: delete

Endpoints

MétodoEndpointDescriçãoEscopo
GET/v1/vendas/Listar vendasvendas: read
GET/v1/vendas/{id}/Detalhar vendavendas: read
POST/v1/vendas/Criar vendavendas: write
PUT/v1/vendas/{id}/Atualizar venda (completo)vendas: write
PATCH/v1/vendas/{id}/Atualizar venda (parcial)vendas: write
DELETE/v1/vendas/{id}/Cancelar vendavendas: delete

Nota: O endpoint DELETE não exclui o registro. Ele altera o status do pedido para cancelado, preservando o histórico completo.


Listar Vendas

GET /v1/vendas/

Escopo necessário: vendas: read

Retorna uma lista paginada de pedidos de venda da empresa.

Parâmetros de consulta

ParâmetroTipoPadrãoDescrição
paginainteger1Número da página
por_paginainteger25Registros por página (máximo: 100)
buscastring-Busca por número do pedido ou número do pedido da loja virtual
statusstring-Filtrar por status (veja tabela de status abaixo)
tipo_pedidostring-Filtrar por tipo: venda ou orcamento
data_iniciodate-Filtrar vendas a partir desta data (formato: YYYY-MM-DD)
data_fimdate-Filtrar vendas até esta data (formato: YYYY-MM-DD)
ordenarstringdata_vendaCampo de ordenação: data_venda, total_venda, numero_pedido
direcaostringdescDireção da ordenação: asc ou desc

Campos retornados na listagem

CampoTipoDescrição
idintegerIdentificador único do pedido
numero_pedidostring ou nullNúmero do pedido gerado pelo sistema
data_vendadatetimeData e hora da venda
tipo_pedidostringTipo do pedido: venda ou orcamento
statusstringCódigo do status atual (ex: em_aberto, aprovado)
status_displaystringTexto formatado do status (ex: "Em Aberto", "Aprovado")
cliente_nomestring ou nullNome do cliente associado
vendedor_nomestring ou nullNome do vendedor responsável
total_itensdecimalSoma dos valores dos itens (antes de descontos e acréscimos)
descontodecimalValor total de desconto aplicado
total_vendadecimalValor final do pedido
numero_itensintegerQuantidade de itens no pedido
origem_pedido_canal_vendastring ou nullCanal de origem do pedido (ex: "Wix", "Mercado Livre")

Exemplo com cURL

bash
curl 'https://api-backend.bunto.com.br/v1/vendas/?pagina=1&por_pagina=10&status=em_aberto&tipo_pedido=venda&ordenar=data_venda&direcao=desc' \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json'

Exemplo com Python

python
import requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } # Listar vendas em aberto do mês atual resposta = requests.get( f"{BASE_URL}/vendas/", headers=headers, params={ "status": "em_aberto", "tipo_pedido": "venda", "data_inicio": "2026-02-01", "data_fim": "2026-02-28", "ordenar": "data_venda", "direcao": "desc", "por_pagina": 25, }, ) dados = resposta.json() if dados["success"]: vendas = dados["data"]["resultados"] paginacao = dados["data"]["paginacao"] print(f"Total de vendas: {paginacao['total_registros']}") for venda in vendas: print(f" - [{venda['numero_pedido']}] {venda['cliente_nome']} - R$ {venda['total_venda']} ({venda['status_display']})") else: print(f"Erro: {dados}")

Exemplo com JavaScript

javascript
const BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const params = new URLSearchParams({ status: "em_aberto", tipo_pedido: "venda", data_inicio: "2026-02-01", data_fim: "2026-02-28", ordenar: "data_venda", direcao: "desc", por_pagina: "25", }); const resposta = await fetch(`${BASE_URL}/vendas/?${params}`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const vendas = dados.data.resultados; const paginacao = dados.data.paginacao; console.log(`Total de vendas: ${paginacao.total_registros}`); vendas.forEach((venda) => { console.log( ` - [${venda.numero_pedido}] ${venda.cliente_nome} - R$ ${venda.total_venda} (${venda.status_display})` ); }); }

Resposta de sucesso (200)

json
{ "success": true, "message": "38 registros encontrados", "data": { "resultados": [ { "id": 1523, "numero_pedido": "PV-001523", "data_venda": "2026-02-11T16:45:00-03:00", "tipo_pedido": "venda", "status": "em_aberto", "status_display": "Em Aberto", "cliente_nome": "Ana Carolina da Silva", "vendedor_nome": "Carlos Eduardo Mendes", "total_itens": "1250.00", "desconto": "62.50", "total_venda": "1187.50", "numero_itens": 3, "origem_pedido_canal_venda": null }, { "id": 1522, "numero_pedido": "PV-001522", "data_venda": "2026-02-11T14:20:00-03:00", "tipo_pedido": "venda", "status": "em_aberto", "status_display": "Em Aberto", "cliente_nome": "Distribuidora Santos Ltda", "vendedor_nome": "Carlos Eduardo Mendes", "total_itens": "4890.00", "desconto": "0.00", "total_venda": "4890.00", "numero_itens": 8, "origem_pedido_canal_venda": "Wix" } ], "paginacao": { "pagina_atual": 1, "total_paginas": 2, "total_registros": 38, "por_pagina": 25, "proxima": "https://api-backend.bunto.com.br/v1/vendas/?pagina=2&por_pagina=25&status=em_aberto", "anterior": null } } }

Detalhar Venda

GET /v1/vendas/{id}/

Escopo necessário: vendas: read

Retorna todos os dados de um pedido de venda, incluindo a lista completa de itens.

Parâmetros de rota

ParâmetroTipoDescrição
idintegerID do pedido de venda

Campos retornados no detalhe

Além de todos os campos da listagem, o detalhe inclui:

CampoTipoDescrição
numero_manualinteger ou nullNúmero manual do pedido
data_saidadate ou nullData de saída da mercadoria (formato: YYYY-MM-DD)
data_previstadate ou nullData prevista de entrega (formato: YYYY-MM-DD)
pedido_comprastring ou nullNúmero do pedido de compra do cliente
numero_propostastring ou nullNúmero da proposta comercial vinculada
numero_pedido_loja_virtualstring ou nullNúmero do pedido na loja virtual/marketplace
origem_pedido_loja_virtualstring ou nullNome da loja virtual de origem (ex: "Shopify", "WooCommerce")
desconto_tipostringTipo de desconto aplicado: percentual ou valor
outras_despesasdecimalValor de outras despesas adicionais
frete_pago_clientedecimalValor do frete cobrado do cliente
condicao_pagamentostring ou nullDescrição da condição de pagamento (ex: "30/60/90 dias")
peso_brutodecimal ou nullPeso bruto total em kg
qtd_volumesinteger ou nullQuantidade de volumes para transporte
transportador_nomestring ou nullNome do transportador responsável
observacoesstring ou nullObservações gerais do pedido
itensarrayLista de itens do pedido (veja tabela abaixo)

Objeto itens[]

CampoTipoDescrição
idintegerID do item
produto_nomestringNome/descrição do produto
codigostringCódigo (SKU) do produto
quantidadedecimalQuantidade do item
preco_unitariodecimalPreço unitário do item
descontodecimalValor de desconto no item
totaldecimalValor total do item (quantidade x preco_unitario - desconto)

Exemplo com cURL

bash
curl https://api-backend.bunto.com.br/v1/vendas/1523/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json'

Exemplo com Python

python
import requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } venda_id = 1523 resposta = requests.get(f"{BASE_URL}/vendas/{venda_id}/", headers=headers) dados = resposta.json() if dados["success"]: venda = dados["data"] print(f"Pedido: {venda['numero_pedido']}") print(f"Cliente: {venda['cliente_nome']}") print(f"Status: {venda['status_display']}") print(f"Total: R$ {venda['total_venda']}") print(f"Itens ({len(venda['itens'])}):") for item in venda["itens"]: print(f" - [{item['codigo']}] {item['produto_nome']} x{item['quantidade']} = R$ {item['total']}") else: print(f"Erro: {dados}")

Exemplo com JavaScript

javascript
const BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const vendaId = 1523; const resposta = await fetch(`${BASE_URL}/vendas/${vendaId}/`, { headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, }); const dados = await resposta.json(); if (dados.success) { const venda = dados.data; console.log(`Pedido: ${venda.numero_pedido}`); console.log(`Cliente: ${venda.cliente_nome}`); console.log(`Status: ${venda.status_display}`); console.log(`Total: R$ ${venda.total_venda}`); console.log(`Itens (${venda.itens.length}):`); venda.itens.forEach((item) => { console.log( ` - [${item.codigo}] ${item.produto_nome} x${item.quantidade} = R$ ${item.total}` ); }); }

Resposta de sucesso (200)

json
{ "success": true, "message": "Registro encontrado", "data": { "id": 1523, "numero_pedido": "PV-001523", "data_venda": "2026-02-11T16:45:00-03:00", "tipo_pedido": "venda", "status": "em_aberto", "status_display": "Em Aberto", "cliente_nome": "Ana Carolina da Silva", "vendedor_nome": "Carlos Eduardo Mendes", "total_itens": "1250.00", "desconto": "62.50", "total_venda": "1187.50", "numero_itens": 3, "origem_pedido_canal_venda": null, "numero_manual": null, "data_saida": null, "data_prevista": "2026-02-18", "pedido_compra": null, "numero_proposta": "PC-000089", "numero_pedido_loja_virtual": null, "origem_pedido_loja_virtual": null, "desconto_tipo": "percentual", "outras_despesas": "0.00", "frete_pago_cliente": "35.00", "condicao_pagamento": "30/60 dias", "peso_bruto": "4.500", "qtd_volumes": 2, "transportador_nome": "Transportadora Rápido SP", "observacoes":"Entregar no horário comercial. Portaria B.", "itens": [ { "id": 4501, "produto_nome": "Camiseta Básica Algodão", "codigo":"CAM-001", "quantidade": "10.000", "preco_unitario": "49.90", "desconto": "24.50", "total": "474.50" }, { "id": 4502, "produto_nome": "Bermuda Jeans Masculina", "codigo":"BER-002", "quantidade": "5.000", "preco_unitario": "129.90", "desconto": "32.25", "total": "617.25" }, { "id": 4503, "produto_nome": "Meia Esportiva Cano Alto", "codigo":"MEI-015", "quantidade": "10.000", "preco_unitario": "15.80", "desconto": "5.75", "total": "152.25" } ] } }

Criar Venda

POST /v1/vendas/

Escopo necessário: vendas: write

Cria um novo pedido de venda ou orcamento. O pedido é criado com status em_aberto e o número do pedido é gerado automaticamente pelo sistema.

Campos do body

CampoTipoObrigatórioDescrição
cliente_idintegerSimID do cliente (deve existir no cadastro da empresa)
itensarraySimLista de itens do pedido (veja tabela abaixo)
vendedor_idintegerNãoID do vendedor responsável
tipo_pedidostringNãoTipo do pedido: venda (padrão) ou orcamento
data_saidadateNãoData de saída da mercadoria (formato: YYYY-MM-DD)
data_previstadateNãoData prevista de entrega (formato: YYYY-MM-DD)
observacoesstringNãoObservações gerais do pedido
condicao_pagamentostringNãoDescrição da condição de pagamento
descontodecimalNãoValor ou percentual de desconto (padrão: 0)
desconto_tipostringNãoTipo de desconto: percentual (padrão) ou valor
outras_despesasdecimalNãoValor de outras despesas (padrão: 0)
frete_pago_clientedecimalNãoValor do frete cobrado do cliente (padrão: 0)
numero_pedido_loja_virtualstringNãoNúmero do pedido na loja virtual (máximo 50 caracteres)
origem_pedido_loja_virtualstringNãoNome da loja virtual de origem (máximo 50 caracteres)
origem_pedido_canal_vendastringNãoCanal de venda de origem (máximo 50 caracteres)
deposito_idintegerNãoID do depósito para reserva de estoque

Objeto itens[] (criação)

CampoTipoObrigatórioDescrição
produto_idintegerSimID do produto (deve existir no cadastro da empresa)
quantidadedecimalSimQuantidade do item
preco_unitariodecimalSimPreço unitário do item em R$
descontodecimalNãoValor de desconto no item (padrão: 0)

Exemplo com cURL

bash
curl -X POST https://api-backend.bunto.com.br/v1/vendas/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "cliente_id": 142, "vendedor_id": 5, "tipo_pedido": "venda", "data_prevista": "2026-02-25", "condicao_pagamento": "30/60 dias", "desconto": 5, "desconto_tipo": "percentual", "frete_pago_cliente": 45.00, "observacoes":"Entregar no horário comercial. Confirmar por telefone.", "deposito_id": 1, "itens": [ { "produto_id": 1, "quantidade": 20, "preco_unitario": 49.90, "desconto": 0 }, { "produto_id": 2, "quantidade": 10, "preco_unitario": 129.90, "desconto": 15.00 }, { "produto_id": 45, "quantidade": 5, "preco_unitario": 299.90, "desconto": 0 } ] }'

Exemplo com Python

python
import requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } novo_pedido = { "cliente_id": 142, "vendedor_id": 5, "tipo_pedido": "venda", "data_prevista": "2026-02-25", "condicao_pagamento": "30/60 dias", "desconto": 5, "desconto_tipo": "percentual", "frete_pago_cliente": 45.00, "observacoes":"Entregar no horário comercial. Confirmar por telefone.", "deposito_id": 1, "itens": [ { "produto_id": 1, "quantidade": 20, "preco_unitario": 49.90, "desconto": 0, }, { "produto_id": 2, "quantidade": 10, "preco_unitario": 129.90, "desconto": 15.00, }, { "produto_id": 45, "quantidade": 5, "preco_unitario": 299.90, "desconto": 0, }, ], } resposta = requests.post(f"{BASE_URL}/vendas/", headers=headers, json=novo_pedido) dados = resposta.json() if dados["success"]: venda = dados["data"] print(f"Pedido criado com sucesso!") print(f"Numero: {venda['numero_pedido']}") print(f"Total: R$ {venda['total_venda']}") print(f"Itens: {len(venda['itens'])}") else: print(f"Erro ao criar pedido: {dados}")

Exemplo com JavaScript

javascript
const BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const novoPedido = { cliente_id: 142, vendedor_id: 5, tipo_pedido: "venda", data_prevista: "2026-02-25", condicao_pagamento: "30/60 dias", desconto: 5, desconto_tipo: "percentual", frete_pago_cliente: 45.0, observacoes: "Entregar no horário comercial. Confirmar por telefone.", deposito_id: 1, itens: [ { produto_id: 1, quantidade: 20, preco_unitario: 49.9, desconto: 0, }, { produto_id: 2, quantidade: 10, preco_unitario: 129.9, desconto: 15.0, }, { produto_id: 45, quantidade: 5, preco_unitario: 299.9, desconto: 0, }, ], }; const resposta = await fetch(`${BASE_URL}/vendas/`, { method: "POST", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(novoPedido), }); const dados = await resposta.json(); if (dados.success) { const venda = dados.data; console.log(`Pedido criado com sucesso!`); console.log(`Numero: ${venda.numero_pedido}`); console.log(`Total: R$ ${venda.total_venda}`); console.log(`Itens: ${venda.itens.length}`); } else { console.error(`Erro ao criar pedido:`, dados); }

Resposta de sucesso (201)

json
{ "success": true, "message": "Pedido criado com sucesso", "data": { "id": 1524, "numero_pedido": "PV-001524", "data_venda": "2026-02-12T10:30:00-03:00", "tipo_pedido": "venda", "status": "em_aberto", "status_display": "Em Aberto", "cliente_nome": "Ana Carolina da Silva", "vendedor_nome": "Carlos Eduardo Mendes", "total_itens": "3296.50", "desconto": "164.83", "total_venda": "3176.68", "numero_itens": 3, "origem_pedido_canal_venda": null, "numero_manual": null, "data_saida": null, "data_prevista": "2026-02-25", "pedido_compra": null, "numero_proposta": null, "numero_pedido_loja_virtual": null, "origem_pedido_loja_virtual": null, "desconto_tipo": "percentual", "outras_despesas": "0.00", "frete_pago_cliente": "45.00", "condicao_pagamento": "30/60 dias", "peso_bruto": null, "qtd_volumes": null, "transportador_nome": null, "observacoes":"Entregar no horário comercial. Confirmar por telefone.", "itens": [ { "id": 4510, "produto_nome": "Camiseta Básica Algodão", "codigo":"CAM-001", "quantidade": "20.000", "preco_unitario": "49.90", "desconto": "0.00", "total": "998.00" }, { "id": 4511, "produto_nome": "Bermuda Jeans Masculina", "codigo":"BER-002", "quantidade": "10.000", "preco_unitario": "129.90", "desconto": "15.00", "total": "1284.00" }, { "id": 4512, "produto_nome": "Tênis Esportivo Running Pro", "codigo":"TEN-045", "quantidade": "5.000", "preco_unitario": "299.90", "desconto": "0.00", "total": "1499.50" } ] } }

Atualizar Venda

Atualização completa

PUT /v1/vendas/{id}/

Atualização parcial

PATCH /v1/vendas/{id}/

Escopo necessário: vendas: write

Atualiza os campos do pedido de venda. Use PUT para atualização completa ou PATCH para atualização parcial (apenas os campos enviados serão alterados).

Importante: Este endpoint atualiza apenas os campos do pedido (datas, observações, condição de pagamento, etc.). Ele não atualiza os itens do pedido. Para alterar itens, utilize a criação de um novo pedido.

Campos atualizáveis

Todos os campos do body de criação podem ser enviados, exceto itens.

Exemplo com cURL (PATCH)

bash
curl -X PATCH https://api-backend.bunto.com.br/v1/vendas/1524/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4' \ -H 'Content-Type: application/json' \ -d '{ "data_prevista": "2026-03-05", "condicao_pagamento": "A vista", "observacoes":"Cliente solicitou antecipação do prazo de entrega." }'

Exemplo com Python

python
import requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } venda_id = 1524 # Atualização parcial (PATCH) - apenas os campos que mudaram atualizacao = { "data_prevista": "2026-03-05", "condicao_pagamento": "A vista", "observacoes":"Cliente solicitou antecipação do prazo de entrega.", } resposta = requests.patch( f"{BASE_URL}/vendas/{venda_id}/", headers=headers, json=atualizacao, ) dados = resposta.json() if dados["success"]: venda = dados["data"] print(f"Pedido {venda['numero_pedido']} atualizado com sucesso") print(f"Nova data prevista: {venda['data_prevista']}") else: print(f"Erro ao atualizar: {dados}")

Exemplo com JavaScript

javascript
const BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const vendaId = 1524; const atualizacao = { data_prevista: "2026-03-05", condicao_pagamento: "A vista", observacoes: "Cliente solicitou antecipação do prazo de entrega.", }; const resposta = await fetch(`${BASE_URL}/vendas/${vendaId}/`, { method: "PATCH", headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(atualizacao), }); const dados = await resposta.json(); if (dados.success) { const venda = dados.data; console.log(`Pedido ${venda.numero_pedido} atualizado com sucesso`); console.log(`Nova data prevista: ${venda.data_prevista}`); } else { console.error(`Erro ao atualizar:`, dados); }

Resposta de sucesso (200)

json
{ "success": true, "message": "Pedido atualizado com sucesso", "data": { "id": 1524, "numero_pedido": "PV-001524", "data_venda": "2026-02-12T10:30:00-03:00", "tipo_pedido": "venda", "status": "em_aberto", "status_display": "Em Aberto", "cliente_nome": "Ana Carolina da Silva", "vendedor_nome": "Carlos Eduardo Mendes", "total_itens": "3296.50", "desconto": "164.83", "total_venda": "3176.68", "numero_itens": 3, "origem_pedido_canal_venda": null, "numero_manual": null, "data_saida": null, "data_prevista": "2026-03-05", "pedido_compra": null, "numero_proposta": null, "numero_pedido_loja_virtual": null, "origem_pedido_loja_virtual": null, "desconto_tipo": "percentual", "outras_despesas": "0.00", "frete_pago_cliente": "45.00", "condicao_pagamento": "A vista", "peso_bruto": null, "qtd_volumes": null, "transportador_nome": null, "observacoes":"Cliente solicitou antecipação do prazo de entrega.", "itens": [ { "id": 4510, "produto_nome": "Camiseta Básica Algodão", "codigo":"CAM-001", "quantidade": "20.000", "preco_unitario": "49.90", "desconto": "0.00", "total": "998.00" }, { "id": 4511, "produto_nome": "Bermuda Jeans Masculina", "codigo":"BER-002", "quantidade": "10.000", "preco_unitario": "129.90", "desconto": "15.00", "total": "1284.00" }, { "id": 4512, "produto_nome": "Tênis Esportivo Running Pro", "codigo":"TEN-045", "quantidade": "5.000", "preco_unitario": "299.90", "desconto": "0.00", "total": "1499.50" } ] } }

Cancelar Venda

DELETE /v1/vendas/{id}/

Escopo necessário: vendas: delete

Cancela um pedido de venda. O registro não é excluído do banco de dados -- o status do pedido é alterado para cancelado, preservando o histórico completo.

Exemplo com cURL

bash
curl -X DELETE https://api-backend.bunto.com.br/v1/vendas/1524/ \ -H 'Authorization: Bearer bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4'

Exemplo com Python

python
import requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = {"Authorization": f"Bearer {TOKEN}"} venda_id = 1524 resposta = requests.delete(f"{BASE_URL}/vendas/{venda_id}/", headers=headers) dados = resposta.json() if dados["success"]: print("Pedido cancelado com sucesso!") else: print(f"Erro ao cancelar: {dados}")

Exemplo com JavaScript

javascript
const BASE_URL = "https://api-backend.bunto.com.br/v1"; const TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4"; const vendaId = 1524; const resposta = await fetch(`${BASE_URL}/vendas/${vendaId}/`, { method: "DELETE", headers: { Authorization: `Bearer ${TOKEN}`, }, }); const dados = await resposta.json(); if (dados.success) { console.log("Pedido cancelado com sucesso!"); } else { console.error(`Erro ao cancelar:`, dados); }

Resposta de sucesso (200)

json
{ "success": true, "message": "Pedido cancelado com sucesso" }

Importante: Após o cancelamento, o pedido continuará aparecendo nas listagens com status=cancelado. Pedidos cancelados não podem ser reabertos via API.


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": { "cliente_id": ["Este campo e obrigatorio."], "itens": ["Este campo e obrigatorio."] } } }

Item inválido (400)

Retornado quando um item do pedido possui dados inválidos.

json
{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Erro de validacao", "details": { "itens": [ { "produto_id": ["Produto com ID 999 nao encontrado."], "quantidade": ["Certifique-se de que este valor seja maior que 0."] } ] } } }

Cliente não encontrado (400)

json
{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Cliente com ID 999 nao encontrado", "details": { "cliente_id": ["Cliente com ID 999 nao encontrado"] } } }

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 pedido 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." }

Rate Limiting

Os limites de requisição são aplicados por token (não por IP).

OperaçãoMétodosLimite
LeituraGET, HEAD, OPTIONS120 requisições/minuto
EscritaPOST, PUT, PATCH30 requisições/minuto
CancelamentoDELETE10 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âmetroTipoPadrãoMáximoDescrição
paginainteger1-Número da página
por_paginainteger25100Registros 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

CampoTipoDescrição
pagina_atualintegerNúmero da página atual
total_paginasintegerTotal de páginas disponíveis
total_registrosintegerTotal de registros encontrados
por_paginaintegerRegistros por página
proximastring ou nullURL da próxima página (null se for a última)
anteriorstring ou nullURL da página anterior (null se for a primeira)
python
import requests BASE_URL = "https://api-backend.bunto.com.br/v1" TOKEN = "bnt_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4" headers = {"Authorization": f"Bearer {TOKEN}"} todas_vendas = [] url = f"{BASE_URL}/vendas/?por_pagina=100&status=finalizado" while url: resposta = requests.get(url, headers=headers) dados = resposta.json() if not dados["success"]: break todas_vendas.extend(dados["data"]["resultados"]) url = dados["data"]["paginacao"]["proxima"] print(f"Total obtido: {len(todas_vendas)} vendas finalizadas")

Valores de Referência

Status do Pedido

ValorDescrição
em_abertoEm Aberto
aprovadoAprovado
preparando_envioPreparando Envio
faturadoFaturado
pronto_envioPronto para Envio
enviadoEnviado
entregueEntregue
nao_entregueNão Entregue
dados_incompletosDados Incompletos
em_processamentoEm Processamento
finalizadoFinalizado
canceladoCancelado

Tipo de Pedido

ValorDescrição
vendaPedido de Venda
orcamentoOrçamento

Tipo de Desconto

ValorDescrição
percentualDesconto em percentual sobre o total de itens
valorDesconto em valor absoluto (R$)

Exemplos Completos

Importar pedidos de marketplace (Python)

python
import os import time import requests class BuntoVendas: """Cliente para o endpoint de vendas 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 requisição 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 vendas com filtros opcionais.""" resposta = self._requisicao("GET", "/vendas/", params=filtros) return resposta.json() def obter(self, venda_id): """Obtém detalhes de uma venda.""" resposta = self._requisicao("GET", f"/vendas/{venda_id}/") return resposta.json() def criar(self, dados): """Cria um novo pedido de venda.""" resposta = self._requisicao("POST", "/vendas/", json=dados) return resposta.json() def atualizar(self, venda_id, dados): """Atualiza parcialmente uma venda.""" resposta = self._requisicao("PATCH", f"/vendas/{venda_id}/", json=dados) return resposta.json() def cancelar(self, venda_id): """Cancela uma venda.""" resposta = self._requisicao("DELETE", f"/vendas/{venda_id}/") return resposta.json() def listar_todas(self, **filtros): """Lista todas as vendas com paginação automática.""" filtros["por_pagina"] = 100 filtros["pagina"] = 1 todas = [] while True: resultado = self.listar(**filtros) if not resultado["success"]: break todas.extend(resultado["data"]["resultados"]) paginacao = resultado["data"]["paginacao"] if paginacao["proxima"] is None: break filtros["pagina"] += 1 return todas # Uso: importar pedidos de marketplace externo api = BuntoVendas() # Dados vindos do marketplace pedidos_marketplace = [ { "cliente_id": 142, "tipo_pedido": "venda", "numero_pedido_loja_virtual": "WIX-78901", "origem_pedido_loja_virtual": "Wix", "origem_pedido_canal_venda": "Wix", "frete_pago_cliente": 25.90, "itens": [ {"produto_id": 1, "quantidade": 2, "preco_unitario": 49.90}, {"produto_id": 45, "quantidade": 1, "preco_unitario": 299.90}, ], }, { "cliente_id": 87, "tipo_pedido": "venda", "numero_pedido_loja_virtual": "WIX-78902", "origem_pedido_loja_virtual": "Wix", "origem_pedido_canal_venda": "Wix", "frete_pago_cliente": 0, "itens": [ {"produto_id": 2, "quantidade": 3, "preco_unitario": 129.90}, ], }, ] for pedido in pedidos_marketplace: resultado = api.criar(pedido) if resultado["success"]: venda = resultado["data"] print( f"Pedido {venda['numero_pedido']} criado - " f"Origem: {pedido['numero_pedido_loja_virtual']} - " f"Total: R$ {venda['total_venda']}" ) else: print(f"Erro ao importar {pedido['numero_pedido_loja_virtual']}: {resultado}") # Respeitar rate limit de escrita (30/min) time.sleep(2.1)

Consultar vendas por período (JavaScript/Node.js)

javascript
class BuntoVendas { constructor(token) { this.token = token ?? process.env.BUNTO_API_TOKEN; this.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", `/vendas/?${params}`); } async listarTodas(filtros = {}) { filtros.por_pagina = "100"; filtros.pagina = "1"; const todas = []; while (true) { const resultado = await this.listar(filtros); if (!resultado.success) break; todas.push(...resultado.data.resultados); if (resultado.data.paginacao.proxima === null) break; filtros.pagina = String(Number(filtros.pagina) + 1); } return todas; } } // Relatório de vendas do mês const api = new BuntoVendas(); const vendasMes = await api.listarTodas({ status: "finalizado", data_inicio: "2026-02-01", data_fim: "2026-02-28", ordenar: "total_venda", direcao: "desc", }); let totalFaturado = 0; for (const venda of vendasMes) { totalFaturado += parseFloat(venda.total_venda); } console.log(`Vendas finalizadas em fevereiro: ${vendasMes.length}`); console.log(`Total faturado: R$ ${totalFaturado.toFixed(2)}`); // Top 5 vendas do mês console.log("\nTop 5 vendas:"); vendasMes.slice(0, 5).forEach((venda, i) => { console.log( ` ${i + 1}. [${venda.numero_pedido}] ${venda.cliente_nome} - R$ ${venda.total_venda}` ); });

Códigos de Status HTTP

CódigoSignificadoQuando ocorre
200SucessoConsulta, atualização ou cancelamento bem-sucedido
201CriadoPedido criado com sucesso via POST
400Erro de validaçãoDados invalidos, cliente não encontrado, produto inválido
401Não autenticadoToken ausente, inválido, expirado ou revogado
403Sem permissãoToken não tem escopo para vendas
404Não encontradoPedido não existe ou pertence a outra empresa
429Muitas requisiçõesRate limit excedido
500Erro internoErro inesperado no servidor
APICRUDcURLJavaScriptPythonRESTVendas
Recursos para IA