Continente API: preços, promoções e rótulos do continente.pt em JSON
Com esta API, recebe em JSON aquilo que o continente.pt mostra a quem compra sem iniciar sessão: o preço de cada artigo, o preço riscado quando há desconto imediato, o PVPR do fabricante quando a loja o indica, o preço por kg ou por litro, a embalagem e, na ficha, os EAN e o rótulo completo (ingredientes, alergénios, origem, tabela nutricional). O sortido depende da loja que entrega na sua morada: com `postal_code` a pesquisa passa a mostrar a gama dessa loja, e a resposta diz qual é. Não é um canal para fornecedores nem para marcas que vendem ao Continente: não envia catálogos nem encomendas, apenas lê a loja online do lado do cliente.
Endpoints
| endpoint | O que retorna | Obrigatórios |
|---|---|---|
| search | Pesquisa como na caixa do site (em português dá melhores resultados): até 35 artigos por página, cada um com preço e a unidade a que se refere (`un`, `kg`, `lt`), preço riscado, PVPR, desconto, promoção por quantidade (`multibuy`), preço por kg/l, embalagem, marca e disponibilidade. Filtros por categoria, marca, dieta (biológico, vegan, sem glúten, sem lactose…) e intervalo de preço; seis ordenações. | query |
| category | Uma categoria inteira pelo seu id (por exemplo `laticinios-leite`), com as mesmas colunas, filtros e paginação da pesquisa. | todos opcionais |
| promotions | Os artigos que estão neste momento com desconto (o filtro «Com Desconto» do site): preço da promoção, preço anterior, percentagem ou valor do desconto e promoções por quantidade com as condições do site. Pode restringir por palavra, categoria, marca ou dieta. | todos opcionais |
| product | A ficha de um artigo pelo id que a pesquisa devolve: preços, janela de validade da promoção, EAN, quantidade máxima por encomenda, caminho de categorias, imagens e o rótulo (denominação legal, produtor, ingredientes, alergénios, conservação, origem, conteúdo líquido e tabela nutricional). | product_id |
| categories | A árvore de categorias do menu da loja: id, nome, endereço e subcategorias. Os ids servem para `category` e para o filtro de categoria. | todos opcionais |
| store | Que loja Continente entrega num código postal português (formato NNNN-NNN): nome e id da loja, ou `covered: false` quando não há entrega. | postal_code |
Cada chamada é cobrada em créditos. Chamadas com erro ou bloqueadas são gratuitas.
Exemplo que funciona
Pesquisa «bacalhau» de 28 de outubro de 2026, loja por defeito: 137 artigos. Há três tipos de preço de referência e não são a mesma coisa. Nas Postas Médias Continente, `regular_price` 8,99 € é o preço antes do desconto imediato de 16 %. No desfiado Riberalves, os 13,99 € estão em `recommended_retail_price`: é o PVPR do fabricante, não um preço a que o Continente o tenha vendido, e por isso `on_offer` vem false. Nas ovas Frip, `price` é por kg (23,30 €/kg) e o valor por unidade fica em `unit_price`. Das 20 linhas, 7 traziam PVPR e 3 desconto imediato. A ficha do desfiado Riberalves acrescenta o que o nome não diz: ingredientes «Bacalhau-do-Pacífico e sal», origem Oceano Pacífico Nordeste.
curl -X POST https://api.reefapi.com/continente/v1/search \
-H "x-api-key: A_SUA_CHAVE" \
-H "content-type: application/json" \
-d '{"query": "bacalhau", "per_page": 20}'{
"ok": true,
"data": {
"store": { "postal_code": null, "store_name": null, "store_id": null, "resolved_from": "site default for an anonymous visitor ..." },
"query": "bacalhau",
"sort": "relevance",
"total": 137,
"page": 1,
"per_page": 20,
"has_more": true,
"results": [
{
"rank": 2,
"product_id": "5734372",
"name": "Bacalhau Desfiado 9 Meses de Cura MSC Congelado Riberalves",
"brand": "Riberalves",
"price": 8.39,
"price_unit": "un",
"regular_price": null,
"recommended_retail_price": 13.99,
"currency": "EUR",
"discount": null,
"on_offer": false,
"unit_price": 20.98,
"unit_price_unit": "kg",
"pack_size": "emb. 400 gr",
"category_path": "Supermercado/Peixaria/Bacalhau Congelado/Desfiado"
},
{
"rank": 7,
"product_id": "7291115",
"name": "Postas Médias de Bacalhau MSC Demolhado Ultracongelado Continente",
"price": 7.49,
"price_unit": "un",
"regular_price": 8.99,
"recommended_retail_price": null,
"discount": { "kind": "immediate_discount", "text": "Desconto Imediato: 16%", "value": 16.0, "unit": "%" },
"on_offer": true,
"unit_price": 12.48,
"unit_price_unit": "kg",
"pack_size": "emb. 600 gr"
},
{
"rank": 20,
"product_id": "7799798",
"name": "Ovas de Bacalhau Higienizadas Congeladas Frip",
"price": 23.3,
"price_unit": "kg",
"regular_price": 24.59,
"unit_price": 9.32,
"unit_price_unit": "un",
"pack_size": "Quant. Mínima = 400 gr"
},
...
]
},
"meta": { "record_count": 20, "total": 137, "charged_credits": 3, "cache_hit": false, "mode": "live" }
}Scraper do continente.pt: onde o preço engana
No HTML do continente.pt, o preço riscado tem um atributo `content` que guarda o preço da promoção, não o preço riscado: num artigo a 1,79 €, o texto dizia «1,99€» e o atributo «1.79». Quem lê o atributo grava duas vezes o preço de promoção e perde o desconto. E o mesmo lugar no cartão do artigo serve tanto para o preço antes do desconto como para o PVPR do fabricante; a camada de dados do site dá aos dois o mesmo nome. Aqui saem em dois campos.
O preço impresso também se parte em pedaços: «5» num elemento e «,34€» noutro. Durante a construção do motor, uma versão que trocava as etiquetas por espaços leu 5,0 em vez de 5,34; o teste com a página guardada apanhou-o antes da primeira chamada real.
Há ainda os silêncios. Uma categoria com um id que o site não conhece não dá erro: o continente.pt mostra o catálogo inteiro (66 004 artigos na medição). Um artigo indisponível traz preço 0 na camada de dados, embora a página continue a imprimir o preço. Aqui a categoria desconhecida é recusada e o artigo indisponível mantém o preço impresso com `available: false`.
Nada disto interrompe um script. Quem regista todas as semanas o preço do bacalhau até à Consoada só dá por eles mais tarde, na folha de cálculo: descontos que nunca existiram, artigos esgotados a 0 € e uma categoria que, em vez de umas dezenas de linhas, traz 66 mil.
Limites e observações honestas
- API independente: não foi criada nem é apoiada pelo Continente, e a ReefAPI não tem com a marca nenhum contrato ou parceria.
- Os descontos do Cartão Continente não aparecem: só se veem com sessão iniciada. O `price` é o preço para quem compra sem cartão.
- O sortido muda com a loja que entrega no código postal: «bacalhau» deu 137 artigos na loja por defeito, 138 em Gaia (4000-322) e 61 no Funchal (9000-018). Os preços dos artigos em comum não mudaram; na construção do motor foram 335 pares artigo×loja, sem nenhuma diferença.
- A ordenação `unit_price_asc` compara o número sem olhar à unidade: nas primeiras linhas de «bacalhau» misturavam-se 3,48 €/un (postas vendidas ao kg) e 3,90 €/kg (comida húmida para gato). Para comparar preço por kg, filtre `unit_price_unit` antes de ordenar.
- A pesquisa por palavra é larga: em «bacalhau» vieram também comida húmida para gato e um suplemento de óleo de fígado de bacalhau. Para ficar na peixaria, use `category` com o id que a ficha devolve (por exemplo `peixaria-e-talho-peixaria-bacalhau-congelado-desfiado`); repare que o próprio Continente arruma aí também o paloco do Pacífico desfiado.
- No mesmo artigo, `max_order_quantity` veio 99 na pesquisa e 10 no `product`; não verificámos qual dos dois o carrinho aplica.
- O site não publica quantidades em stock, custos de entrega nem horários disponíveis; só `available` e os limites por encomenda.
- Créditos: 3 por chamada em `search`, `category`, `promotions`, `product` e `categories`; 1 em `store`.