https://merchant-api.ifood.com.br/promotion/v1.0Authorization:Authorization: Bearer {JWT_TOKEN}401 Unauthorized.Para detalhes sobre autenticação e gerenciamento de tokens, consulte a documentação de autenticação.| Método | Endpoint | Descrição |
|---|---|---|
POST | /merchants/{merchantId}/promotions | Criar promoções |
POST | /merchants/{merchantId}/promotions?reset=true | Substituir todas as promoções |
GET | /merchants/{merchantId}/promotions/{aggregationId}/items | Consultar status das promoções |
POST /merchants/{merchantId}/promotionsreset=true.| Parâmetro | Tipo | Descrição |
|---|---|---|
merchantId | uuid | ID único da loja |
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
reset | boolean | false | Quando true, substitui completamente todas as promoções existentes |
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
aggregationTag | string | Não | Identificador customizado para rastreamento. Deve ser único. |
promotions | array | Sim | Lista contendo as promoções a criar |
promotions[]| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
promotionName | string | Não | Nome descritivo da promoção (máx. 255 caracteres) |
channels | array | Sim | Lista de canais de venda (ex: IFOOD-APP) |
items | array | Sim | Lista de itens a promover |
promotions[].items[]| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
ean | string | Sim | Código EAN do produto (formato UPC-A, 12 dígitos) |
discountValue | number | Condicional | Percentual de desconto (0-70). Obrigatório para PERCENTAGE e PERCENTAGE_PER_X_UNITS |
initialDate | string | Sim | Data de início em formato ISO 8601 (YYYY-MM-DD) |
finalDate | string | Sim | Data de término em formato ISO 8601 (YYYY-MM-DD) |
promotionType | string | Sim | Tipo de promoção: PERCENTAGE, LXPY ou PERCENTAGE_PER_X_UNITS |
progressiveDiscount | object | Condicional | Configuração para promoções de tipo LXPY ou PERCENTAGE_PER_X_UNITS |
progressiveDiscount| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
quantityToBuy | integer | Condicional | Quantidade de itens que o cliente deve comprar (mín. 2) |
quantityToPay | integer | Condicional | Quantidade de itens que o cliente paga (apenas para LXPY) |
| Tipo | Campos obrigatórios |
|---|---|
PERCENTAGE | discountValue |
LXPY | progressiveDiscount.quantityToBuy, progressiveDiscount.quantityToPay |
PERCENTAGE_PER_X_UNITS | discountValue, progressiveDiscount.quantityToBuy |
DISCOUNT_INVALID.initialDate deve ser anterior a finalDateYYYY-MM-DD{
"aggregationTag": "promo-percentage",
"promotions": [
{
"promotionName": "Desconto 20%",
"channels": ["IFOOD-APP"],
"items": [
{
"ean": "7891234567890",
"discountValue": 20.0,
"initialDate": "2026-02-01",
"finalDate": "2026-02-28",
"promotionType": "PERCENTAGE"
}
]
}
]
}{
"aggregationTag": "promo-lxpy",
"promotions": [
{
"promotionName": "Leve 3 Pague 2",
"channels": ["IFOOD-APP"],
"items": [
{
"ean": "7891234567890",
"discountValue": null,
"initialDate": "2026-02-01",
"finalDate": "2026-02-28",
"promotionType": "LXPY",
"progressiveDiscount": {
"quantityToBuy": 3,
"quantityToPay": 2
}
}
]
}
]
}{
"aggregationTag": "promo-progressive",
"promotions": [
{
"promotionName": "50% na 3ª unidade",
"channels": ["IFOOD-APP"],
"items": [
{
"ean": "7891234567890",
"discountValue": 50.0,
"initialDate": "2026-02-01",
"finalDate": "2026-02-28",
"promotionType": "PERCENTAGE_PER_X_UNITS",
"progressiveDiscount": {
"quantityToBuy": 3
}
}
]
}
]
}{
"aggregationId": "abc123",
"message": "We have successfully received your request to create promotions"
}| Campo | Tipo | Descrição |
|---|---|---|
aggregationId | string | Identificador único da requisição. Use este valor para consultar o status do processamento |
message | string | Confirmação legível da recepção da requisição |
aggregationId retornado.POST /merchants/{merchantId}/promotions?reset=truereset=true, a API executa as seguintes ações:| Ação | Item | Resultado |
|---|---|---|
| Criar | Itens no payload que não existem | Novos itens promocionais são criados |
| Manter | Itens existentes presentes no novo payload | Itens continuam ativos com os parâmetros atualizados |
| Desativar | Itens existentes ausentes do novo payload | Itens são marcados como FINISHING e removidos |
reset=true nos seguintes cenários:| Aspecto | Recomendação |
|---|---|
| Frequência | Executar preferencialmente uma vez por dia |
| Horário | Escolher horários fora do pico de vendas (ex: 2h-6h) |
| Limite | Máximo 10.000 itens promocionais por requisição |
| Validação | Validar o payload localmente antes de enviar |
| Rastreamento | Usar aggregationTag com timestamp para auditoria |
# Agendar reset para as 3h da madrugada
0 3 * * * curl -X POST "https://merchant-api.ifood.com.br/promotion/v1.0/merchants/{merchantId}/promotions?reset=true" \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '@promotions.json'GET /merchants/{merchantId}/promotions/{aggregationId}/items| Parâmetro | Tipo | Descrição |
|---|---|---|
merchantId | uuid | ID único da loja |
aggregationId | string | ID retornado na criação (do campo aggregationId da resposta 202) |
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
ean | string | - | Filtrar por código EAN do produto |
promotionName | string | - | Filtrar por nome da promoção |
promotionType | string | - | Filtrar por tipo (PERCENTAGE, LXPY, PERCENTAGE_PER_X_UNITS) |
status | string | - | Filtrar por status (ex: ACTIVE, ERROR, PROCESSING) |
offset | integer | 0 | Número de itens a pular (para paginação) |
limit | integer | 100 | Número máximo de itens a retornar (máximo: 1000) |
curl -X GET "https://merchant-api.ifood.com.br/promotion/v1.0/merchants/{merchantId}/promotions/{aggregationId}/items?status=ACTIVE&limit=10" \
-H "Authorization: Bearer {JWT_TOKEN}"{
"promotions": [
{
"promotionItemId": "005f5ea0-1ff4-4c9b-9f48-76d94bfe4694",
"ean": "7891234567890",
"status": "ACTIVE",
"initialDate": "2026-02-01",
"finalDate": "2026-02-28",
"promotionType": "LXPY",
"promotionName": "Leve 3 Pague 2",
"progressiveDiscount": {
"quantityToBuy": 3,
"quantityToPay": 2
},
"error": null
}
],
"pagination": {
"nextOffset": 10,
"currentOffset": 0
}
}| Campo | Tipo | Descrição |
|---|---|---|
promotions | array | Lista de itens promocionais |
promotions[].promotionItemId | string | ID único do item promocional |
promotions[].ean | string | Código EAN do produto |
promotions[].status | string | Status atual da promoção (veja tabela abaixo) |
promotions[].initialDate | string | Data de início em formato ISO 8601 |
promotions[].finalDate | string | Data de término em formato ISO 8601 |
promotions[].promotionType | string | Tipo de promoção |
promotions[].promotionName | string | Nome descritivo da promoção |
promotions[].progressiveDiscount | object | Configuração de desconto (se aplicável) |
promotions[].error | string ou null | Mensagem de erro detalhada (se status = ERROR) |
pagination.nextOffset | integer | Offset para a próxima página (se houver mais resultados) |
pagination.currentOffset | integer | Offset atual |
| Status | Significado | Ação esperada |
|---|---|---|
PROCESSING | Requisição recebida e em validação no backend | Aguardar conclusão da validação |
SCHEDULED | Validação passou, aguardando initialDate | Nenhuma ação necessária |
ACTIVE | Promoção ativa e pronta para uso | Verificar aplicação em pedidos |
DUPLICATE | Outro item com mesmo EAN e período já existe | Remover duplicação e reenviar |
FINISHING | Remoção em progresso (após reset ou exclusão) | Aguardar transição para FINISHED |
FINISHED | Remoção concluída com sucesso | Verificar próximos passos |
ERROR | Erro na validação ou processamento | Consultar campo error para detalhes |
ACTIVE significa que a promoção foi validada e cadastrada no sistema. No entanto, isso não garante que a promoção apareça no app do cliente.Uma promoção ativa pode não ser visível nos seguintes casos:bag.benefits.benefits[]).POST 202): Aguarde 2-3 segundos antes de consultarPROCESSING: Aguarde mais alguns segundos e repitaACTIVE: Promoção está prontaERROR: Verifique o campo error para detalhes da falhaGET /orders/{id}/virtual-bag para obter a composição completa do pedido, incluindo benefícios aplicados.Referência: Módulo Order - Detalhes do Pedidobag.benefits.benefits[] na respostatarget = ITEMsponsorships[].liability é PARTNER ou CHAINtargetId no benefíciobag.items[].uniqueId para identificar o itemsponsorships[].amount.value de prices.grossValue.valuepreço_final = preço_bruto - desconto_aplicado