Validade
/expiries
Listar validades
As validades por loja e produto, com a cor do alerta (red, yellow, green) que a regra do cliente dá para os dias que faltam. Vêm de qualquer origem: o ERP, o app (coleta e auditoria) e a importação de planilha.
Ordem estável por id. Para sincronizar, use updated_since com include_inactive=true: a validade é desativada quando o lote acaba (contagem zero ou vendido na rebaixa).
Parâmetros de consulta
-
store_codestring · lista -
Código de integração da loja.
Separe por vírgula, até 100 valores. Exemplo:0012 -
product_codestring · lista -
Código interno do produto.
Separe por vírgula, até 100 valores. Exemplo:1001 -
eanstring · lista -
Código de barras.
Separe por vírgula, até 100 valores. Exemplo:7891234567890 -
alertstring · lista -
Cor do alerta:
red,yellowougreen.Separe por vírgula, até 100 valores. Exemplo:red -
expiry_fromstring -
Vencimento a partir de (AAAA-MM-DD).
Exemplo:2026-11-10 -
expiry_tostring -
Vencimento até (AAAA-MM-DD).
Exemplo:2026-12-31 -
updated_sincestring (data-hora) -
Só registros alterados a partir desta data/hora (ISO 8601).
Exemplo:2026-11-10T06:00:00-03:00 -
include_inactiveboolean -
Inclui os registros desativados (
active: false). Use na sincronização incremental para saber o que saiu.Padrão:falseExemplo:false -
pageinteger -
Página, começando em 1.
Padrão:1Exemplo:1 -
page_sizeinteger -
Itens por página. Acima de 100 a chamada é recusada com
invalid_parameter(não é cortada em silêncio).Padrão:50Máximo:100Exemplo:50
Sobre a resposta
days_to_expireé calculado no momento da consulta; negativo = vencido.source:ERP,COLETA(app),AUDITORIA,IMPORTACAOouMANUAL.audit_statusé a situação da tarefa de auditoria mais recente da validade, ounull.
Erros possíveis
| HTTP | code | Quando |
|---|---|---|
| 401 | api_key_expired | A chave passou da data de expiração. |
| 401 | api_key_revoked | A chave foi revogada na Configuração Global › API. |
| 401 | invalid_api_key | A chave não existe neste ambiente ou está errada. |
| 401 | missing_api_key | A chamada veio sem o cabeçalho "Authorization: Bearer <chave>". |
| 403 | insufficient_scope | A chave não tem o acesso que este endpoint exige. |
| 403 | module_disabled | O cliente não tem o módulo deste endpoint habilitado. |
| 403 | store_not_allowed | A chave está restrita a algumas lojas e uma das pedidas não é delas. |
| 429 | rate_limited | Limite de chamadas por minuto da chave atingido. Respeite o Retry-After. |
| 500 | internal_error | Erro interno. Tente de novo; se persistir, fale com o suporte. |
curl -X GET "https://demonstracao.appbix.com.br/external-api/v1/expiries?store_code=0012&product_code=1001&page_size=100" \
-H "Authorization: Bearer $BIX_API_KEY"
import os
import requests
response = requests.request(
"GET",
"https://demonstracao.appbix.com.br/external-api/v1/expiries?store_code=0012&product_code=1001&page_size=100",
headers={"Authorization": f"Bearer {os.environ['BIX_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
print(response.json())
const response = await fetch(
"https://demonstracao.appbix.com.br/external-api/v1/expiries?store_code=0012&product_code=1001&page_size=100",
{ method: "GET", headers: { Authorization: `Bearer ${process.env.BIX_API_KEY}` } }
);
if (!response.ok) throw new Error((await response.json()).code);
console.log(await response.json());
{
"data": [
{
"id": 7731,
"store": {
"id": 12,
"code": "0012",
"name": "Loja Centro"
},
"product": {
"id": 345,
"internal_code": "1001",
"ean": "7891234567890",
"description": "IOGURTE NATURAL 170G"
},
"expiry_date": "2026-11-20",
"days_to_expire": 10,
"alert": "yellow",
"quantity": 36.0,
"batch": "L2611",
"source": "ERP",
"audit_status": "naoiniciado",
"active": true,
"updated_at": "2026-11-10T08:30:00-03:00"
}
],
"pagination": {
"page": 1,
"page_size": 50,
"total_items": 1,
"total_pages": 1,
"has_next": false
}
}
/expiries
Enviar validades
Envia as validades que o ERP conhece (o lote que chegou com a data de validade, por loja). É a mesma ingestão usada pelas integrações de ERP do BIX.
- Só insere: a validade que já existe para a loja, o produto e a data não é alterada (volta
skipped). Quantidade e baixa do lote ficam com a operação na loja. - Lotes do mesmo produto, loja e data no mesmo envio são somados num registro só.
- O produto precisa estar no cadastro do BIX.
Envie até 500 itens em {"items": [...]}. Use o cabeçalho Idempotency-Key para poder repetir a chamada (timeout, queda de rede) sem gravar duas vezes.
Corpo da requisição
Objeto JSON com items: uma lista de 1 a 500 itens. Cada item tem:
-
store_codestring -
Código de integração da loja. Ou
store_id.Exemplo:0012 -
store_idinteger -
Id da loja no BIX. Ou
store_code. -
internal_codestring -
Código interno. Ou
ean.Exemplo:1001 -
eanstring -
Código de barras. Ou
internal_code. -
expiry_datestring obrigatório -
Data de validade: AAAA-MM-DD (também aceita DD/MM/AAAA).
Exemplo:2026-11-20 -
quantitynumber -
Quantidade do lote. Padrão 1.
Exemplo:36 -
batchstring -
Lote.
Exemplo:L2611 -
entry_datestring -
Data de entrada do lote na loja (AAAA-MM-DD).
Exemplo:2026-11-03
Sobre a resposta
A chamada responde
200sempre que o lote foi processado, mesmo com itens recusados: confira ostatusde cada item emresults(created,updated,skippedouerror).resultsvem na ordem deitems;indexé a posição do item no lote, a partir de 0.Item com erro não impede os outros: cada um é gravado ou recusado sozinho.
skippedtraz o motivo emdetail: a validade já estava cadastrada.
Erros possíveis
| HTTP | code | Quando |
|---|---|---|
| 400 | invalid_parameter | Parâmetro com valor inválido (o detail diz qual). |
| 401 | api_key_expired | A chave passou da data de expiração. |
| 401 | api_key_revoked | A chave foi revogada na Configuração Global › API. |
| 401 | invalid_api_key | A chave não existe neste ambiente ou está errada. |
| 401 | missing_api_key | A chamada veio sem o cabeçalho "Authorization: Bearer <chave>". |
| 403 | insufficient_scope | A chave não tem o acesso que este endpoint exige. |
| 403 | module_disabled | O cliente não tem o módulo deste endpoint habilitado. |
| 403 | store_not_allowed | A chave está restrita a algumas lojas e uma das pedidas não é delas. |
| 409 | idempotency_key_reused | O Idempotency-Key já foi usado, nas últimas 24 horas, numa chamada com outro corpo. |
| 429 | rate_limited | Limite de chamadas por minuto da chave atingido. Respeite o Retry-After. |
| 500 | internal_error | Erro interno. Tente de novo; se persistir, fale com o suporte. |
curl -X POST "https://demonstracao.appbix.com.br/external-api/v1/expiries" \
-H "Authorization: Bearer $BIX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"items": [{"store_code": "0012", "internal_code": "1001", "expiry_date": "2026-11-20", "quantity": 36, "batch": "L2611", "entry_date": "2026-11-03"}]}'
import os
import uuid
import requests
payload = {
"items": [
{
"store_code": "0012",
"internal_code": "1001",
"expiry_date": "2026-11-20",
"quantity": 36,
"batch": "L2611",
"entry_date": "2026-11-03"
}
]
}
response = requests.post(
"https://demonstracao.appbix.com.br/external-api/v1/expiries",
json=payload,
headers={
"Authorization": f"Bearer {os.environ['BIX_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=60,
)
response.raise_for_status()
for item in response.json()["results"]:
if item["status"] == "error":
print(item["index"], item["code"], item["detail"])
const payload = {
"items": [
{
"store_code": "0012",
"internal_code": "1001",
"expiry_date": "2026-11-20",
"quantity": 36,
"batch": "L2611",
"entry_date": "2026-11-03"
}
]
};
const response = await fetch("https://demonstracao.appbix.com.br/external-api/v1/expiries", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIX_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify(payload),
});
const body = await response.json();
body.results.filter((r) => r.status === "error").forEach((r) => console.log(r));
{
"items": [
{
"store_code": "0012",
"internal_code": "1001",
"expiry_date": "2026-11-20",
"quantity": 36,
"batch": "L2611",
"entry_date": "2026-11-03"
}
]
}
{
"summary": {
"total": 1,
"created": 1,
"updated": 0,
"skipped": 0,
"errors": 0
},
"results": [
{
"index": 0,
"status": "created",
"code": null,
"detail": null
}
]
}
/markdowns
Listar rebaixas
As rebaixas de preço por validade que o BIX calculou, no formato padrão do BIX para publicar rebaixa em um ERP (contrato bix.markdown.publication/v1): o bloco markdown traz o percentual, o preço cheio, o preço rebaixado e a vigência (starts_on a ends_on), e store e product dizem onde e o quê.
Para o seu ERP criar a promoção: busque as que estão em aguardando_pdv (etiqueta já impressa) e as encerrada (a promoção precisa sair), aplique, e confirme em POST /markdowns/publications. Use updated_since para buscar só o que mudou.
Parâmetros de consulta
-
statusstring · lista -
Situação:
aguardando_aprovacao,recusada,aguardando_impressao,aguardando_pdv,ativaouencerrada.Separe por vírgula, até 100 valores. Exemplo:aguardando_pdv -
store_codestring · lista -
Código de integração da loja.
Separe por vírgula, até 100 valores. Exemplo:0012 -
updated_sincestring (data-hora) -
Só registros alterados a partir desta data/hora (ISO 8601).
Exemplo:2026-11-10T06:00:00-03:00 -
pageinteger -
Página, começando em 1.
Padrão:1Exemplo:1 -
page_sizeinteger -
Itens por página. Acima de 100 a chamada é recusada com
invalid_parameter(não é cortada em silêncio).Padrão:50Máximo:100Exemplo:50
Sobre a resposta
ends_on: véspera da cor seguinte (verde e amarela) ou o último dia da rebaixa (vermelha).nullquando falta a data de validade.reduced_priceénullquando o BIX ainda não tem o preço cheio do produto na loja.publication_status:nao_se_aplica,pendente,publicada,erroouencerrada_erp.external.code: o código da oferta no ERP, quando já confirmado.
Erros possíveis
| HTTP | code | Quando |
|---|---|---|
| 401 | api_key_expired | A chave passou da data de expiração. |
| 401 | api_key_revoked | A chave foi revogada na Configuração Global › API. |
| 401 | invalid_api_key | A chave não existe neste ambiente ou está errada. |
| 401 | missing_api_key | A chamada veio sem o cabeçalho "Authorization: Bearer <chave>". |
| 403 | insufficient_scope | A chave não tem o acesso que este endpoint exige. |
| 403 | module_disabled | O cliente não tem o módulo deste endpoint habilitado. |
| 403 | store_not_allowed | A chave está restrita a algumas lojas e uma das pedidas não é delas. |
| 429 | rate_limited | Limite de chamadas por minuto da chave atingido. Respeite o Retry-After. |
| 500 | internal_error | Erro interno. Tente de novo; se persistir, fale com o suporte. |
curl -X GET "https://demonstracao.appbix.com.br/external-api/v1/markdowns?status=aguardando_pdv&store_code=0012&page_size=100" \
-H "Authorization: Bearer $BIX_API_KEY"
import os
import requests
response = requests.request(
"GET",
"https://demonstracao.appbix.com.br/external-api/v1/markdowns?status=aguardando_pdv&store_code=0012&page_size=100",
headers={"Authorization": f"Bearer {os.environ['BIX_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
print(response.json())
const response = await fetch(
"https://demonstracao.appbix.com.br/external-api/v1/markdowns?status=aguardando_pdv&store_code=0012&page_size=100",
{ method: "GET", headers: { Authorization: `Bearer ${process.env.BIX_API_KEY}` } }
);
if (!response.ok) throw new Error((await response.json()).code);
console.log(await response.json());
{
"data": [
{
"id": 4410,
"status": "aguardando_pdv",
"publication_status": "nao_se_aplica",
"schema": "bix.markdown.publication/v1",
"markdown": {
"id": 4410,
"color": "yellow",
"percent": 30.0,
"full_price": 7.49,
"reduced_price": 5.24,
"quantity": 18.0,
"measurement": "UN",
"starts_on": "2026-11-10",
"ends_on": "2026-11-16",
"expiry_date": "2026-11-20",
"close_reason": null
},
"store": {
"id": 12,
"code": "0012",
"name": "Loja Centro",
"cnpj": "12345678000190"
},
"product": {
"internal_code": "1001",
"ean": "7891234567890",
"description": "IOGURTE NATURAL 170G"
},
"external": {
"code": ""
},
"updated_at": "2026-11-10T08:30:00-03:00"
}
],
"pagination": {
"page": 1,
"page_size": 50,
"total_items": 1,
"total_pages": 1,
"has_next": false
}
}
/markdowns/publications
Confirmar a rebaixa no PDV
O retorno do seu ERP para cada rebaixa:
applied: a promoção entrou no PDV. A rebaixa emaguardando_pdvpassa aativa, como no botão "Aplicado no PDV" do Painel de Rebaixas do BIX;publication_statusvirapublicada.error: o ERP não conseguiu aplicar.publication_statusviraerroe a mensagem fica registrada para a operação.removed: a promoção de uma rebaixa encerrada saiu do PDV.publication_statusviraencerrada_erp.
Envie até 500 itens em {"items": [...]}. Use o cabeçalho Idempotency-Key para poder repetir a chamada (timeout, queda de rede) sem gravar duas vezes.
Corpo da requisição
Objeto JSON com items: uma lista de 1 a 500 itens. Cada item tem:
-
markdown_idinteger obrigatório -
O
idda rebaixa (deGET /markdowns).Exemplo:4410 -
resultstring obrigatório -
applied,errorouremoved.Exemplo:applied -
external_codestring -
Código da promoção no ERP (até 100 caracteres).
Exemplo:PROMO-77812 -
messagestring -
Mensagem do ERP, principalmente no
error(até 500 caracteres).
Sobre a resposta
A chamada responde
200sempre que o lote foi processado, mesmo com itens recusados: confira ostatusde cada item emresults(created,updated,skippedouerror).resultsvem na ordem deitems;indexé a posição do item no lote, a partir de 0.Item com erro não impede os outros: cada um é gravado ou recusado sozinho.
skipped: a confirmação não mudou nada (a rebaixa já estava com esse resultado).Rebaixa que não é do cliente da chave, de loja fora da chave ou de simulação volta
error(not_found).
Erros possíveis
| HTTP | code | Quando |
|---|---|---|
| 400 | invalid_parameter | Parâmetro com valor inválido (o detail diz qual). |
| 401 | api_key_expired | A chave passou da data de expiração. |
| 401 | api_key_revoked | A chave foi revogada na Configuração Global › API. |
| 401 | invalid_api_key | A chave não existe neste ambiente ou está errada. |
| 401 | missing_api_key | A chamada veio sem o cabeçalho "Authorization: Bearer <chave>". |
| 403 | insufficient_scope | A chave não tem o acesso que este endpoint exige. |
| 403 | module_disabled | O cliente não tem o módulo deste endpoint habilitado. |
| 404 | not_found | Rota inexistente. |
| 409 | idempotency_key_reused | O Idempotency-Key já foi usado, nas últimas 24 horas, numa chamada com outro corpo. |
| 429 | rate_limited | Limite de chamadas por minuto da chave atingido. Respeite o Retry-After. |
| 500 | internal_error | Erro interno. Tente de novo; se persistir, fale com o suporte. |
curl -X POST "https://demonstracao.appbix.com.br/external-api/v1/markdowns/publications" \
-H "Authorization: Bearer $BIX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"items": [{"markdown_id": 4410, "result": "applied", "external_code": "PROMO-77812"}]}'
import os
import uuid
import requests
payload = {
"items": [
{
"markdown_id": 4410,
"result": "applied",
"external_code": "PROMO-77812"
}
]
}
response = requests.post(
"https://demonstracao.appbix.com.br/external-api/v1/markdowns/publications",
json=payload,
headers={
"Authorization": f"Bearer {os.environ['BIX_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=60,
)
response.raise_for_status()
for item in response.json()["results"]:
if item["status"] == "error":
print(item["index"], item["code"], item["detail"])
const payload = {
"items": [
{
"markdown_id": 4410,
"result": "applied",
"external_code": "PROMO-77812"
}
]
};
const response = await fetch("https://demonstracao.appbix.com.br/external-api/v1/markdowns/publications", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIX_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify(payload),
});
const body = await response.json();
body.results.filter((r) => r.status === "error").forEach((r) => console.log(r));
{
"items": [
{
"markdown_id": 4410,
"result": "applied",
"external_code": "PROMO-77812"
}
]
}
{
"summary": {
"total": 1,
"created": 0,
"updated": 1,
"skipped": 0,
"errors": 0
},
"results": [
{
"index": 0,
"status": "updated",
"id": 4410,
"code": null,
"detail": null
}
]
}