Uma promoção pode estar correta na montra da sua loja e, ainda assim, ter datas ou preços desatualizados no código. Quando isso acontece, os sistemas de pesquisa recebem uma descrição diferente da oferta que o cliente encontra.
Os dados estruturados para preços promocionais ajudam a comunicar o preço e a sua duração, mas a localização das datas depende da forma como a oferta está representada. Neste guia, mostramos onde usar validFrom, validThrough e priceValidUntil, como ler dois exemplos de JSON-LD e o que verificar antes, durante e depois da campanha.
Neste artigo

O que são dados estruturados para preços promocionais
Uma loja pode anunciar um produto por 80 euros, reduzidos para 60 euros durante uma semana. Na página, o visitante vê o preço atual, o preço anterior riscado e, eventualmente, a data em que a campanha termina. A marcação estruturada deve descrever essa mesma realidade de forma que sistemas automáticos possam interpretá-la.
Em termos simples, o produto é representado por Product e a proposta de venda por Offer. Dentro da oferta encontram-se, entre outras informações, o preço e a moeda. Dependendo da implementação, o preço pode surgir diretamente em Offer ou numa estrutura de preço chamada PriceSpecification.
A diferença não é apenas estética. É a localização do preço promocional que determina onde deve colocar as datas para seguir a orientação do Google. Se o preço ativo estiver em Offer.price, as datas pertencem a Offer. Se estiver numa PriceSpecification, validFrom e validThrough pertencem à especificação que contém esse preço.
O guia do Google para listagens de comerciantes descreve estas opções e outras propriedades das ofertas. Consulte-o antes de publicar: a documentação pode mudar e existem requisitos adicionais para as funcionalidades de pesquisa.
Importa também separar três coisas: a oferta comercial, que determina o que o cliente pode comprar; a página visível, que apresenta essa oferta; e o JSON-LD, que a descreve. A marcação não cria uma promoção nem substitui as condições apresentadas ao cliente.
Por exemplo, se a campanha acabou à meia-noite mas o produto ainda é vendido a 60 euros, não basta deixar uma data de fim antiga no código. É preciso determinar qual é efetivamente o preço em vigor e corrigir os sistemas que apresentam informação contraditória.

Onde colocar as datas: Offer ou PriceSpecification
O primeiro passo é identificar o caminho entre o produto e o preço promocional. Não procure apenas a presença de uma data no código: procure o objeto a que essa data pertence. Uma data correta no objeto errado pode não comunicar a duração pretendida.
Quando o preço está diretamente em Offer
Se o preço reduzido estiver em offers.price, coloque o início em validFrom e o fim em validThrough no mesmo objeto Offer. O Google também aceita priceValidUntil em Offer para indicar a validade do preço. A opção com validFrom e validThrough é mais expressiva quando precisa de comunicar início, fim, hora e fuso.
Imagine uma oferta ativa entre as 09:00 de 10 de novembro e as 23:59 de 16 de novembro, em Portugal continental. Se esse for o período efetivo anunciado, a oferta pode conter o preço de 60 euros e essas duas datas. Não escolha o período apenas para preencher campos: deve resultar das regras reais da campanha.
Quando o preço está numa PriceSpecification
Se o preço promocional estiver numa priceSpecification, coloque validFrom e validThrough nesse objeto específico. Se existirem várias especificações, como uma para o preço atual e outra para o preço anterior riscado, as datas da promoção devem acompanhar a especificação do preço promocional.
priceValidUntil não é a propriedade a usar em PriceSpecification. Não a desloque para dentro desse objeto por analogia com Offer. Para verificar os tipos e propriedades gerais do vocabulário, consulte também a definição de validThrough em Schema.org.
O preço em dois locais
Se o preço ativo aparecer simultaneamente em offers.price e em offers.priceSpecification, o Google indica que usa o valor de offers.price. Por isso, uma especificação com 60 euros não resolve uma oferta que mantém 80 euros em offers.price. Para evitar ambiguidade, reveja a estrutura inteira e elimine contradições.
Esta regra é particularmente relevante quando um plugin gera um preço e uma personalização acrescenta outro. Antes de alterar datas, confirme quem produz cada parte da marcação e qual é a fonte de verdade para o preço efetivamente cobrado.
| Local do preço promocional | Onde colocar as datas | Propriedades relevantes |
|---|---|---|
| Offer.price | No mesmo objeto Offer | validFrom e validThrough; priceValidUntil como data de validade do preço |
| PriceSpecification | No objeto PriceSpecification do preço promocional | validFrom e validThrough |

Como escrever datas, horas e fusos horários
Um valor de data deve ser interpretável sem obrigar o consumidor da informação a adivinhar o fuso horário. A orientação do Google recomenda datas em ISO 8601, incluindo hora e fuso, para indicar o início e o fim da promoção.
Considere 2026-11-10T09:00:00+00:00. A primeira parte representa a data; depois de T surge a hora; e +00:00 indica o desvio em relação a UTC. Uma data de fim no mesmo formato, como 2026-11-16T23:59:00+00:00, especifica um momento concreto, e não apenas um dia no calendário.
O exemplo usa +00:00 porque se refere a datas de novembro em Portugal continental. Não copie esse desvio para todas as campanhas: a hora legal muda ao longo do ano e outras regiões podem usar fusos diferentes. Gere o valor a partir do fuso configurado para a campanha e confirme o desvio aplicável a cada data.
Se a oferta terminar no final de um dia, defina o instante exato no sistema de preços e use uma representação coerente. Uma página que diz «até 16 de novembro» pode levar o comprador a esperar disponibilidade durante esse dia; uma marcação que termina logo no seu início comunica algo diferente. A redação visível e a lógica de expiração devem evitar essa dúvida.
Schema.org aceita valores do tipo Date ou DateTime para validThrough. Já priceValidUntil, associada a Offer, espera uma data. Assim, não a trate como equivalente técnico perfeito a uma data e hora com fuso em validThrough. Se a hora de fecho for importante, o par validFrom e validThrough é a escolha mais clara para a duração.
Campanhas em vários mercados
Uma promoção pode terminar à mesma hora local em Lisboa e noutro mercado, ou terminar no mesmo instante absoluto em ambos. São regras comerciais diferentes. Na primeira hipótese, as páginas de cada mercado podem precisar de valores com desvios distintos; na segunda, os relógios locais podem apresentar horas de fim diferentes.
Antes de gerar os dados estruturados para preços promocionais, escreva uma frase que descreva a regra: «termina às 23:59 na hora local de cada mercado» ou «termina no mesmo instante para todos». Depois, teste as datas de cada versão. Ter uma regra inequívoca facilita a coordenação entre marketing, loja e equipa técnica.

Exemplo prático: preço promocional em Offer
O exemplo seguinte mostra os campos essenciais de um produto fictício quando o preço ativo está diretamente em Offer. É um objeto JSON-LD ilustrativo, apresentado como texto para facilitar a leitura. Antes de o implementar, adapte o produto, a oferta e as restantes propriedades aos dados reais da página e aos requisitos atuais do Google.
{ “@context”: “https://schema.org/”, “@type”: “Product”, “name”: “Candeeiro de mesa”, “offers”: { “@type”: “Offer”, “price”: “60.00”, “priceCurrency”: “EUR”, “validFrom”: “2026-11-10T09:00:00+00:00”, “validThrough”: “2026-11-16T23:59:00+00:00” }}
Neste modelo, price, validFrom e validThrough pertencem todos a Offer. O valor 60.00 representa o preço que o cliente deve encontrar na página durante o período indicado. EUR identifica a moeda; não inclua o símbolo do euro dentro do valor de price.
As datas são apenas um exemplo e já não devem ser reutilizadas para uma campanha posterior. Depois do fim do período, a loja deve publicar o preço então disponível e deixar de apresentar estas datas como se descrevessem a oferta atual.
Se optar por priceValidUntil em Offer, pode indicar uma data como 2026-11-16 para a validade do preço. Essa propriedade, por si só, não comunica o início da campanha nem uma hora de fim com fuso. Evite combinar campos com prazos contraditórios: se usar mais do que um, confirme que descrevem a mesma regra.
O que falta antes de publicar
Um exemplo curto não substitui a documentação completa. Dependendo da página e da funcionalidade pretendida, pode precisar de outras informações, como identificação do produto, imagem, disponibilidade ou dados adicionais da oferta. Acrescente apenas informação verdadeira e aplicável; não invente propriedades para satisfazer uma ferramenta.
Na implementação efetiva, o objeto deve ser emitido no formato JSON-LD apropriado pela plataforma ou pelo mecanismo de marcação utilizado. Este artigo não inclui o bloco de integração no HTML. Se o sistema já gera Product e Offer, alterar esse gerador é geralmente mais seguro do que criar uma segunda descrição independente para o mesmo preço.

Exemplo prático: preço numa PriceSpecification
O segundo modelo coloca o preço ativo numa PriceSpecification. É útil quando a estrutura da loja descreve os preços através de especificações separadas. O ponto central mantém-se: as datas ficam no mesmo objeto que contém o preço promocional.
{ “@context”: “https://schema.org/”, “@type”: “Product”, “name”: “Candeeiro de mesa”, “offers”: { “@type”: “Offer”, “priceSpecification”: { “@type”: “UnitPriceSpecification”, “price”: “60.00”, “priceCurrency”: “EUR”, “validFrom”: “2026-11-10T09:00:00+00:00”, “validThrough”: “2026-11-16T23:59:00+00:00” } }}
UnitPriceSpecification é uma forma de especificação de preço usada no contexto de ofertas. Neste exemplo não existe offers.price; assim, não há um valor nesse campo a sobrepor-se ao preço ativo apresentado na especificação. O preço visível e as condições de compra continuam a ter de corresponder aos 60 euros indicados.
E se a página mostrar o preço anterior riscado?
O Google permite identificar o preço original riscado numa especificação separada com priceType igual a https://schema.org/StrikethroughPrice. Essa especificação é distinta da que descreve o preço promocional ativo. A separação ajuda a comunicar que 80 euros é o preço riscado e 60 euros é o preço atual, em vez de apresentar dois preços ativos concorrentes.
Não acrescente um preço riscado apenas porque a propriedade existe. Ele deve corresponder ao que é efetivamente apresentado e às condições aplicáveis à campanha. A forma de calcular e anunciar reduções pode estar sujeita a regras legais; a marcação técnica não determina, por si, se uma promoção cumpre essas regras.
Se a loja representar ambos os valores numa lista de priceSpecification, confirme que a especificação de 60 euros contém validFrom e validThrough e que a de 80 euros está identificada como preço riscado. Depois verifique se não existe um offers.price desatualizado que o Google possa interpretar como preço ativo.
A escolha entre este modelo e o anterior depende da estrutura existente. Não é necessário migrar todas as ofertas para PriceSpecification apenas para acrescentar datas. É mais importante manter uma representação coerente e sustentável do que multiplicar objetos sem necessidade.

Garantir que a marcação corresponde à oferta visível
Os dados estruturados para preços promocionais só são úteis quando descrevem uma oferta que o visitante consegue compreender na página. Uma validação técnica não resolve um desconto que aparece para alguns utilizadores, mas não para outros, nem um preço que muda no checkout sem explicação.
Preço, moeda e condições
Compare o preço no JSON-LD com o preço apresentado inicialmente e com o valor aplicável ao produto e à variante descritos. Verifique também a moeda. Se uma redução depender de um cupão, de adesão a um programa ou de uma quantidade mínima, não apresente sem contexto esse valor como se fosse o preço acessível a qualquer visitante.
Por exemplo, se a página anunciar 60 euros apenas depois de introduzir um código, mas mostrar 80 euros sem esse código, a equipa deve avaliar como representar a oferta e as suas condições segundo a documentação aplicável. Não transforme automaticamente o preço condicionado num preço geral apenas porque é mais apelativo.
Variantes e disponibilidade
Uma camisola pode ter preços diferentes por tamanho ou cor. Se a página representar uma variante concreta, verifique que o preço e as datas pertencem a essa variante. Se a interface mudar dinamicamente ao selecionar uma opção, teste também o que está presente na marcação que os sistemas de pesquisa conseguem aceder.
O mesmo cuidado aplica-se à disponibilidade. Uma promoção anunciada para um produto esgotado pode exigir uma revisão da página e dos dados da oferta. Não assuma que todos os produtos de uma campanha mantêm o mesmo estado durante todo o período.
Campanhas programadas e expiradas
Antes do início, confirme se o preço reduzido já está visível ou se ainda será ativado. Durante a campanha, preço e datas devem estar alinhados. No fim, confirme a transição para a oferta seguinte. Estes três momentos merecem testes separados: um único teste a meio da campanha não mostra se a ativação e a expiração funcionam.
Quando a campanha termina, não altere apenas o texto «promoção terminada». Verifique o preço ativo, a especificação do preço riscado, as datas e as versões em cache. Se o preço de 60 euros continuar em vigor sem prazo, represente a situação real em vez de manter uma data antiga como se ainda fosse válida.
Para uma perspetiva mais ampla sobre a relação entre informação útil e descoberta, pode também ler o nosso artigo sobre SEO para pesquisa com IA. A marcação é uma peça técnica; não substitui uma página clara para pessoas.

Como validar a implementação e acompanhar alterações
Implementar uma campanha sem definir como verificar o resultado deixa a equipa dependente de inspeções ocasionais. Um processo simples, repetido nos momentos certos, ajuda a detetar problemas antes de estes se prolongarem.
- Registe a regra comercial. Anote produto ou variante, preço normal apresentado, preço promocional, moeda, condições, início, fim e fuso horário.
- Identifique a origem dos dados. Determine se o preço e as datas vêm da plataforma de comércio eletrónico, de um plugin, de uma integração ou de código personalizado.
- Inspecione a página real. Compare o que um visitante vê com o objeto Product, Offer ou PriceSpecification emitido para essa página.
- Teste a marcação. Use o teste de resultados avançados do Google acessível a partir da documentação e analise erros, avisos e propriedades detetadas. Consulte também as ferramentas disponibilizadas no Search Console para páginas relevantes.
- Verifique após a publicação. Repita a comparação no início e no fim da campanha, incluindo páginas de variantes e versões de mercado relevantes.
- Corrija a origem. Se um valor estiver errado, altere o sistema que o gera e volte a testar, em vez de apenas esconder o sintoma numa camada intermédia.
Ao testar, anote o URL, a data e a hora da verificação, a variante selecionada e os valores observados. Essa pequena ficha facilita a comparação com o calendário da campanha e ajuda outra pessoa a reproduzir uma divergência.
Teste não é garantia de apresentação
Uma ferramenta pode confirmar que detetou determinadas propriedades ou assinalar problemas conhecidos. Isso não significa que o Google vá apresentar um preço, uma redução ou uma data nos resultados. A apresentação depende de vários fatores e das políticas aplicáveis; a marcação, por si só, não garante elegibilidade nem visibilidade.
Também não espere que uma alteração seja refletida instantaneamente. Depois de corrigir a página, os sistemas externos precisam de a voltar a processar. O mais útil é verificar que a versão publicada está correta e acompanhar os relatórios disponíveis, sem interpretar uma ausência imediata como prova de falha.
Se usa WordPress
Em WordPress, o tema, a loja e mais do que um plugin podem contribuir para a marcação. Inspecione a saída efetiva antes de adicionar uma solução nova. Duas estruturas completas para o mesmo produto, com preços ou datas diferentes, tornam o diagnóstico mais difícil.
Não é possível generalizar o comportamento de um plugin ou de uma versão sem o testar. Se precisar de personalização, planeie atualizações e testes num ambiente seguro. O nosso guia de desenvolvimento e manutenção WordPress ajuda a enquadrar esse trabalho.

Erros frequentes e uma rotina para os evitar
Os erros mais difíceis nem sempre são erros de sintaxe. Um JSON-LD bem formado pode conter valores antigos, aplicar datas ao preço errado ou representar uma promoção que já não está disponível. A tabela seguinte ajuda a transformar sintomas em verificações concretas.
| Sinal de alerta | O que verificar | Ação prática |
|---|---|---|
| Preço na página diferente do JSON-LD | Origem dos dados, variante e cache | Corrigir o gerador e testar novamente a página publicada |
| Data de fim já passou | Estado real da campanha e preço atual | Atualizar ou remover as datas que deixaram de descrever a oferta |
| Preço promocional em PriceSpecification sem datas | Objeto exato que contém o preço ativo | Adicionar validFrom e validThrough a essa especificação |
| Dois preços ativos diferentes | offers.price e priceSpecification | Eliminar a contradição e confirmar o preço efetivamente cobrado |
| Hora de fim inesperada | Fuso horário e desvio na data da campanha | Gerar novamente as datas a partir da regra comercial correta |
Quem faz o quê?
Uma campanha envolve frequentemente várias pessoas. Marketing pode definir a mensagem e o período; a equipa comercial confirma preços e condições; a equipa técnica configura a loja e a marcação. A responsabilidade final pela consistência deve estar explícita, mesmo que todas as tarefas pertençam à mesma pessoa.
Uma rotina proporcional à dimensão da loja pode ser suficiente: uma lista de campanhas ativas, uma pessoa responsável por cada alteração e uma verificação na data de fecho. Para catálogos maiores, pode fazer sentido automatizar alertas de datas expiradas e comparações entre o preço publicado e a origem dos dados. A automação precisa, ainda assim, de regras claras e supervisão.
Guarde também um registo das alterações relevantes: quando a campanha foi criada, que prazo foi aprovado e quando o preço foi atualizado. Isso facilita a resolução de dúvidas sem depender da memória de quem configurou a promoção.
Por fim, reveja periodicamente a documentação. As orientações citadas neste artigo resultam da pesquisa fornecida, realizada em 4 de novembro de 2026; não foi possível confirmar alterações publicadas no dia seguinte. Antes de uma implementação crítica, confirme a versão atual das fontes e teste o comportamento da sua própria loja.

Perguntas frequentes
Posso usar apenas priceValidUntil para indicar o fim da promoção?
Pode usá-la em Offer para indicar a data até à qual o preço é válido. No entanto, validFrom e validThrough permitem indicar também o início e expressar hora e fuso horário. Não coloque priceValidUntil em PriceSpecification.
O Google mostra sempre a duração da promoção nos resultados?
Não. A marcação pode ajudar o Google a compreender a oferta e a avaliar a elegibilidade para funcionalidades de pesquisa, mas não garante a apresentação de preços, descontos ou datas.
O que devo fazer quando uma promoção termina?
Confirme que o preço visível e o preço ativo no JSON-LD passam a refletir a oferta em vigor. Remova ou atualize as datas expiradas e volte a testar a página, incluindo eventuais variantes e versões em cache.

O que levar desta leitura
Uma promoção bem descrita começa por uma oferta clara: preço, condições e prazo têm de estar certos antes de chegarem ao JSON-LD. Depois, a regra prática é colocar as datas no objeto que contém o preço promocional e verificar a página nos momentos de ativação e de fecho.
Mais do que preencher propriedades, trata-se de manter a informação sincronizada ao longo da campanha. Se precisar de ajuda a rever a implementação da sua loja ou a planear uma solução de manutenção, pode falar com a UniversoWeb.