Buscar na documentação
ctrl+4K
Módulos
Authentication
Merchant
Catalog
Order
Events
Logistics
Shipping
Review
Financial
Soluções

Endpoints

Referência técnica completa da API de Promotion. Todos os endpoints requerem autenticação JWT e retornam JSON.
https://merchant-api.ifood.com.br/promotion/v1.0
Todos os endpoints requerem token OAuth 2.0 no header Authorization:
Authorization: Bearer {JWT_TOKEN}
O token deve ser incluído em todas as requisições. Se o token expirar ou for inválido, a API retornará 401 Unauthorized.Para detalhes sobre autenticação e gerenciamento de tokens, consulte a documentação de autenticação.
MétodoEndpointDescrição
POST/merchants/{merchantId}/promotionsCriar promoções
POST/merchants/{merchantId}/promotions?reset=trueSubstituir todas as promoções
GET/merchants/{merchantId}/promotions/{aggregationId}/itemsConsultar status das promoções

Cria novas promoções para uma loja. As promoções ficam ativas até a data final especificada.
POST /merchants/{merchantId}/promotions
Novas requisições adicionam-se às promoções existentes. Para substituir completamente todas as promoções, use o parâmetro de query reset=true.
ParâmetroTipoDescrição
merchantIduuidID único da loja
ParâmetroTipoPadrãoDescrição
resetbooleanfalseQuando true, substitui completamente todas as promoções existentes

Campo raiz

CampoTipoObrigatórioDescrição
aggregationTagstringNãoIdentificador customizado para rastreamento. Deve ser único.
promotionsarraySimLista contendo as promoções a criar

Objeto de promoção: promotions[]

CampoTipoObrigatórioDescrição
promotionNamestringNãoNome descritivo da promoção (máx. 255 caracteres)
channelsarraySimLista de canais de venda (ex: IFOOD-APP)
itemsarraySimLista de itens a promover

Objeto de item: promotions[].items[]

CampoTipoObrigatórioDescrição
eanstringSimCódigo EAN do produto (formato UPC-A, 12 dígitos)
discountValuenumberCondicionalPercentual de desconto (0-70). Obrigatório para PERCENTAGE e PERCENTAGE_PER_X_UNITS
initialDatestringSimData de início em formato ISO 8601 (YYYY-MM-DD)
finalDatestringSimData de término em formato ISO 8601 (YYYY-MM-DD)
promotionTypestringSimTipo de promoção: PERCENTAGE, LXPY ou PERCENTAGE_PER_X_UNITS
progressiveDiscountobjectCondicionalConfiguração para promoções de tipo LXPY ou PERCENTAGE_PER_X_UNITS

Objeto de desconto progressivo: progressiveDiscount

CampoTipoObrigatórioDescrição
quantityToBuyintegerCondicionalQuantidade de itens que o cliente deve comprar (mín. 2)
quantityToPayintegerCondicionalQuantidade de itens que o cliente paga (apenas para LXPY)

Campos obrigatórios por tipo de promoção

TipoCampos obrigatórios
PERCENTAGEdiscountValue
LXPYprogressiveDiscount.quantityToBuy, progressiveDiscount.quantityToPay
PERCENTAGE_PER_X_UNITSdiscountValue, progressiveDiscount.quantityToBuy

Restrições de valor

Limite máximo de desconto: O desconto não pode exceder 70% do preço de catálogo. Requisições com descontos superiores serão rejeitadas com erro DISCOUNT_INVALID.

Restrições de data

  • initialDate deve ser anterior a finalDate
  • Ambas devem estar em formato YYYY-MM-DD
  • Datas retroativas são permitidas (para promoções já iniciadas)

PERCENTAGE — Desconto percentual

Aplica um desconto percentual fixo no preço do item.Cenário: Promover um item com desconto de 20%. Cliente paga R$ 8,00 em um item de R$ 10,00.
{
  "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"
        }
      ]
    }
  ]
}

LXPY — Leve X Pague Y

Aplica desconto em combo baseado em quantidade: cliente leva X unidades e paga apenas Y.Cenário: "Leve 3, Pague 2" em um item de R$ 10,00. Cliente gasta R$ 20,00 por 3 unidades.
{
  "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
          }
        }
      ]
    }
  ]
}

PERCENTAGE_PER_X_UNITS — Desconto na Nª unidade

Aplica desconto percentual progressivo a partir de uma quantidade específica.Cenário: 50% de desconto na terceira unidade. Cliente gasta R$ 10 + R$ 10 + R$ 5 = R$ 25,00 por 3 unidades.
{
  "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
          }
        }
      ]
    }
  ]
}
A API retorna HTTP 202 Accepted, indicando que a requisição foi recebida para processamento assíncrono.
{
  "aggregationId": "abc123",
  "message": "We have successfully received your request to create promotions"
}
CampoTipoDescrição
aggregationIdstringIdentificador único da requisição. Use este valor para consultar o status do processamento
messagestringConfirmação legível da recepção da requisição

Interpretando a resposta HTTP 202

Processamento assíncronoO status HTTP 202 confirma apenas que a requisição foi recebida e enfileirada para processamento. Não indica que as promoções foram criadas com sucesso. As validações ocorrem de forma assíncrona no backend.Para verificar o status real, use o endpoint GET com o aggregationId retornado.
Substitui completamente todas as promoções ativas da loja com o novo conjunto fornecido.
POST /merchants/{merchantId}/promotions?reset=true
Quando você usa reset=true, a API executa as seguintes ações:
AçãoItemResultado
CriarItens no payload que não existemNovos itens promocionais são criados
ManterItens existentes presentes no novo payloadItens continuam ativos com os parâmetros atualizados
DesativarItens existentes ausentes do novo payloadItens são marcados como FINISHING e removidos
  • Sincronizar completamente o estado de promoções com um sistema externo
  • Remover todas as promoções ativas de uma loja
  • Garantir que apenas o conjunto especificado esteja ativo
Evite reset=true nos seguintes cenários:
  • Se você apenas quer adicionar novas promoções (use POST sem o parâmetro)
  • Durante horários de pico de vendas na loja
  • Sem ter validado o payload completo internamente
  • Se a loja tem mais de 10.000 itens promocionais
AspectoRecomendação
FrequênciaExecutar preferencialmente uma vez por dia
HorárioEscolher horários fora do pico de vendas (ex: 2h-6h)
LimiteMáximo 10.000 itens promocionais por requisição
ValidaçãoValidar o payload localmente antes de enviar
RastreamentoUsar aggregationTag com timestamp para auditoria

Exemplo de timing seguro

# 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'
Retorna detalhes dos itens de promoção com suporte a filtros e paginação.
GET /merchants/{merchantId}/promotions/{aggregationId}/items
ParâmetroTipoDescrição
merchantIduuidID único da loja
aggregationIdstringID retornado na criação (do campo aggregationId da resposta 202)
ParâmetroTipoPadrãoDescrição
eanstring-Filtrar por código EAN do produto
promotionNamestring-Filtrar por nome da promoção
promotionTypestring-Filtrar por tipo (PERCENTAGE, LXPY, PERCENTAGE_PER_X_UNITS)
statusstring-Filtrar por status (ex: ACTIVE, ERROR, PROCESSING)
offsetinteger0Número de itens a pular (para paginação)
limitinteger100Nú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
  }
}
CampoTipoDescrição
promotionsarrayLista de itens promocionais
promotions[].promotionItemIdstringID único do item promocional
promotions[].eanstringCódigo EAN do produto
promotions[].statusstringStatus atual da promoção (veja tabela abaixo)
promotions[].initialDatestringData de início em formato ISO 8601
promotions[].finalDatestringData de término em formato ISO 8601
promotions[].promotionTypestringTipo de promoção
promotions[].promotionNamestringNome descritivo da promoção
promotions[].progressiveDiscountobjectConfiguração de desconto (se aplicável)
promotions[].errorstring ou nullMensagem de erro detalhada (se status = ERROR)
pagination.nextOffsetintegerOffset para a próxima página (se houver mais resultados)
pagination.currentOffsetintegerOffset atual
StatusSignificadoAção esperada
PROCESSINGRequisição recebida e em validação no backendAguardar conclusão da validação
SCHEDULEDValidação passou, aguardando initialDateNenhuma ação necessária
ACTIVEPromoção ativa e pronta para usoVerificar aplicação em pedidos
DUPLICATEOutro item com mesmo EAN e período já existeRemover duplicação e reenviar
FINISHINGRemoção em progresso (após reset ou exclusão)Aguardar transição para FINISHED
FINISHEDRemoção concluída com sucessoVerificar próximos passos
ERRORErro na validação ou processamentoConsultar campo error para detalhes
Um status 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:
  • Outra promoção ativa com maior prioridade está configurada para o mesmo item
  • Configurações de negócio da loja limitam a quantidade de promoções simultâneas por item
  • Filtros de elegibilidade aplicados no nível do app excluem o item ou cliente
Para confirmar se uma promoção está sendo efetivamente aplicada, consulte o endpoint de detalhes do pedido e verifique se o desconto aparece nos benefícios (bag.benefits.benefits[]).Como o processamento é assíncrono, siga esta estratégia:
  1. Logo após criar (POST 202): Aguarde 2-3 segundos antes de consultar
  2. Ainda em PROCESSING: Aguarde mais alguns segundos e repita
  3. Transição para ACTIVE: Promoção está pronta
  4. Status ERROR: Verifique o campo error para detalhes da falha
Promoções aprovadas aparecem automaticamente nos pedidos do cliente. Para validar se a sua promoção foi corretamente aplicada, use o endpoint de detalhes do pedido.Consulte GET /orders/{id}/virtual-bag para obter a composição completa do pedido, incluindo benefícios aplicados.Referência: Módulo Order - Detalhes do PedidoPara validar se um desconto foi aplicado corretamente:
  1. Navegue até bag.benefits.benefits[] na resposta
  2. Filtre onde target = ITEM
  3. Identifique benefícios onde sponsorships[].liability é PARTNER ou CHAIN
Estes são benefícios cuja responsabilidade é sua (partner ou chain).
  1. Localize o targetId no benefício
  2. Correlacione com bag.items[].uniqueId para identificar o item
  3. Subtraia sponsorships[].amount.value de prices.grossValue.value
Resultado: preço_final = preço_bruto - desconto_aplicado
Esta página foi útil?
Avalie sua experiência no novo Developer portal: