DEV Community

Cover image for How to Scrape tap.az Real Estate Listings Without a Paid API
Tim Zinin
Tim Zinin

Posted on Originally published at apify.com

How to Scrape tap.az Real Estate Listings Without a Paid API

The problem

Tap.az is Azerbaijan's biggest classifieds marketplace, and its real-estate section is where apartment sales and rentals in Baku and across the country actually get posted. There is no official API, so anyone who wants listing data — a market researcher tracking prices, an agency building an inventory feed, a buyer monitoring new supply — is left refreshing search pages by hand and copying titles, prices and links into a spreadsheet.

Writing your own scraper is harder than it looks. Tap.az sits behind Cloudflare and blocks every proxy exit except a residential one geographically pinned to Azerbaijan — the README records that a foreign-exit residential proxy and every datacenter proxy both get the block page. On top of that, the site's category feed mixes sale and rental listings together with no filter parameter to split them, so a naive collector dumps both into one undifferentiated pile.

What the actor does

The Tap.az Azerbaijan Real Estate Listings actor scrapes public Tap.az real-estate search-result pages by category and returns structured listing rows — no Tap.az account, no API key, no browser on your side. For every ad found it extracts:

  • title, price as a number in AZN, and deal_type (sale or rent, inferred from the listing title text since the source offers no filter);
  • rooms, area_sqm (null when the title doesn't state them), and location (city/district as Tap.az's own region field states it);
  • a preview image URL, the direct listing URL, and the source posting timestamp as a full ISO-8601 string with timezone offset;
  • found, category, source_portal and scraped_at provenance fields.

Sale and rent listings come back in a single run — you filter client-side on deal_type. Because the source blocks non-Azerbaijani exits, the actor's proxyConfiguration defaults to a residential proxy pinned to Azerbaijan; leave that default on unless you have your own working setup. Explicit found: false rows are returned for unrecognized category pages or failed requests, so an empty result is never a silent mystery — and those rows are never charged.

The boundaries are stated plainly in the README: only the menziller (apartments) category is verified, and the actor reads only what the search-results list shows — no full photo gallery, no exact coordinates (lat/lng are always null), no seller phone from the detail page.

Example: input and output

{
    "category": "menziller",
    "max_items": 5,
    "max_pages": 1
}
Enter fullscreen mode Exit fullscreen mode

A real row from a verification run (2026-07-30):

{
    "category": "menziller",
    "found": true,
    "url": "https://tap.az/elanlar/dasinmaz-emlak/menziller/48233404",
    "title": "2-otaqlı yeni tikili, Nardaran qəs., 58 m²",
    "price": 240000,
    "currency": "AZN",
    "deal_type": "sale",
    "property_type": "apartment",
    "rooms": 2,
    "area_sqm": 58,
    "location": "Bakı",
    "lat": null,
    "lng": null,
    "posted_date": "2026-07-30T09:44:39+04:00",
    "description": "",
    "images": [
        "https://tap.azstatic.com/uploads/thumbnail/2026%2F07%2F23%2F09%2F43%2F29%2F90cac49e-bbf8-411d-8956-b9f0b05ee510%2F53196_nAyYWEoz-LqNr7wEzxbVYQ.jpg"
    ],
    "source_portal": "tap.az",
    "scraped_at": "2026-07-30T07:20:28.128Z"
}
Enter fullscreen mode Exit fullscreen mode

A rental row from the same run shows the same shape with "deal_type": "rent" and a monthly price ("price": 800).

Pricing and the free limit

Pay per event: $0.005 per run start plus $0.002 per result row. A run that collects 100 listings costs about $0.205. Rows where the source returned nothing — an unrecognized category or a failed request — are returned for transparency but never charged.

Apify's free plan gives $5 of usage credits per month. At this tariff, $5 covers about 24 full 100-listing runs (24 × $0.205 = $4.92). One caveat from the README: residential proxy bandwidth is billed separately to your Apify account, the same as any other actor's residential proxy usage — measured at roughly 0.03–0.1 MB per fetched listing page during acceptance testing.

Try it

The default category is already filled in — press Start and pull the dataset: Tap.az Azerbaijan Real Estate Listings

For AI agents and MCP

The actor takes JSON in and returns structured JSON dataset rows via the Apify API, so an agent can start a run, read the dataset, and branch on the found flag — real listings carry price, rooms, area and deal type, while found: false rows explain themselves in a note field. Results export to JSON, CSV or Excel, or flow into a pipeline through a webhook. The README documents an MCP server setup for the actor alongside JavaScript, Python and CLI examples.

Top comments (0)