API

OLX Portugal API: anúncios do olx.pt em JSON

Aqui lê-se, sem iniciar sessão, o mesmo que qualquer comprador vê no olx.pt: o anúncio com o seu preço (e se o anunciante o aceita negociar), o estado do artigo, a freguesia e o distrito, as fotografias. A resposta chega em JSON. Não é a integração que stands e imobiliárias usam para publicar e gerir os seus anúncios; serve quem está a procurar. Portugal escolhe-se com `"country": "pt"`; sem esse parâmetro o pedido vai para o olx.pl.

Endpoints

endpointO que retornaObrigatórios
searchPesquisa por palavra-chave e/ou categoria: ordenação, estado (novo ou usado), intervalo de preço em euros, só com envio OLX, só com fotografias, e filtro por distrito ou freguesia. 40 por página por defeito (até 50); os anúncios pagos que o OLX intercala na lista são retirados. Precisa de query ou de category_id.todos opcionais
countQuantos anúncios correspondem à pesquisa e aos filtros, sem descarregar nenhum, e quantos desses o OLX deixa percorrer página a página.todos opcionais
locationsConverte nomes em ids de localização. Sem parâmetros devolve os distritos e as ilhas; com region_id, as freguesias desse distrito; com query, procura o nome em todo o país.todos opcionais
offerO anúncio completo pelo id numérico: descrição, preço, estado, atributos da categoria (por exemplo «Tipo» e «Marca»), fotografias, ponto no mapa e formas de contacto disponíveis.id
categoriesAs categorias e sugestões de filtro que o OLX associa a uma pesquisa, mais as definições gerais de filtros.todos opcionais
filtersAs definições de filtros do olx.pt, com as chaves filter_enum e filter_float que se passam diretamente no parâmetro `filters`.todos opcionais
userO perfil público de um vendedor.user_id
user_offersTodos os anúncios ativos de um vendedor, paginados por offset.user_id
suggestedOs anúncios que o OLX apresenta como semelhantes a um anúncio concreto.id
breadcrumbsO caminho de categorias de uma categoria ou de um anúncio.todos opcionais

Cada chamada é cobrada em créditos. Chamadas com erro ou bloqueadas são gratuitas.

Exemplo que funciona

Procurar «Porto» em locations devolveu 14 resultados, entre eles Porto Moniz (Madeira) e Porto Judeu (Terceira); o distrito do Porto é o region_id 13. Nesta pesquisa havia 442 anúncios de Bimby, o mesmo número que count deu. Repare em `city`: no olx.pt é uma freguesia ou união de freguesias, não a cidade. E em `price.type`: nesta pesquisa, todas as linhas "arranged" vinham com `negotiable: true` (preço negociável) e todas as "price" com `negotiable: false`.

Requisição
curl -X POST https://api.reefapi.com/olx/v1/search \
  -H "x-api-key: A_SUA_CHAVE" \
  -H "content-type: application/json" \
  -d '{"query": "bimby", "country": "pt", "region_id": 13}'
Resposta (resumida)
{
  "ok": true,
  "data": {
    "offers": [
      {
        "id": 674181570,
        "url": "https://www.olx.pt/d/anuncio/bimby-tm5-com-copo-extra-e-acessrios-IDJCNqi.html",
        "title": "Bimby TM5 com copo extra e acessórios",
        "price": { "value": 180, "type": "arranged", "currency": "EUR", "negotiable": true, "label": "180 €" },
        "condition": { "key": "used", "label": "Usado" },
        "city": "Águas Santas",
        "region": "Porto",
        "region_id": 13
      },
      {
        "id": 674785650,
        "title": "Bimby TM5 + Cook-Key | Como Nova | 100% Funcional",
        "price": { "value": 450, "type": "arranged", "currency": "EUR", "negotiable": true, "label": "450 €" },
        "condition": { "key": "used", "label": "Usado" },
        "city": "Custóias, Leça Do Balio E Guifões",
        "region": "Porto"
      },
      {
        "id": 672325063,
        "title": "Bimby TM6 Sparkle Preta - Como Nova | Pouquíssimo Uso",
        "price": { "value": 590, "type": "price", "currency": "EUR", "negotiable": false, "label": "590 €" },
        "city": "Moreira",
        "region": "Porto"
      },
      ...
    ],
    "promoted_indices": [0, 1, 2, 12],
    "total": 442,
    "has_more": true,
    "next_offset": 40
  },
  "meta": { "record_count": 39, "country": "pt", "promoted_filtered": 4, "cache_hit": false, "mode": "live" }
}

Scraper do OLX em Python: onde costuma partir

Os anúncios pagos não ficam numa caixa à parte: o OLX encaixa-os na lista em posições que mudam de página para página (nesta pesquisa, 0, 1, 2 e 12). Um scraper que pagina por offset sem os tirar vê-os reaparecer e conclui que a paginação está a repetir resultados. Aqui saem da resposta e o número removido fica em `meta.promoted_filtered`.

Os ids de categoria não passam de um país para outro. Um id que funciona no olx.pl dá erro 400 noutra edição — medimo-lo na ucraniana —, por isso quem adapta um scraper polaco ao mercado português tem de ir buscar os ids ao `categories` do próprio olx.pt.

Há ainda um pormenor de formato: o mesmo pedido de anúncio, com uma barra no fim do endereço, recebe 403 de alguns servidores, e isso parece um bloqueio sem o ser. O motor pede o anúncio sem a barra.

As três situações têm algo em comum: parecem outra coisa. Os destaques parecem paginação repetida, o id de categoria parece erro do pedido e a barra final parece um bloqueio. Quem segue semana a semana o preço das Bimby usadas no Porto perde mais tempo a perceber isto do que a escrever o parser.

Limites e observações honestas

  • Esta API não pertence ao OLX e não é fornecida em parceria com o OLX.
  • Sem `"country": "pt"` o pedido vai para o olx.pl, que é o valor por defeito.
  • Pela pesquisa só se chega aos primeiros 1000 anúncios de cada combinação de filtros; é um limite do próprio OLX. O total real está em `count`, e `paginatable_count` diz quantos se conseguem percorrer.
  • O preço é o que o anunciante escreveu. Um anúncio de uma Bimby TM7 nova a 36 € explicava na descrição que se tratava de compra a crédito; o campo `price` não distingue estes casos, por isso convém filtrar valores fora do normal antes de calcular médias.
  • O número de telefone não faz parte da resposta; `contact.phone` indica apenas se o anunciante deixou um.
  • As respostas não ficam guardadas: cada chamada vai ao olx.pt no momento em que é feita.