BuyRentKenya Property Scraper — Kenya Real Estate avatar

BuyRentKenya Property Scraper — Kenya Real Estate

Pricing

from $3.40 / 1,000 listing results

Go to Apify Store
BuyRentKenya Property Scraper — Kenya Real Estate

BuyRentKenya Property Scraper — Kenya Real Estate

Extract property listings from BuyRentKenya.com — Kenya's largest real-estate portal. Search houses, flats, land and commercial property for sale or rent by location. Clean JSON: title, price (KES), area, beds/baths, agent, images, posting date. Server-rendered pages, no login, no browser.

Pricing

from $3.40 / 1,000 listing results

Rating

0.0

(0)

Developer

Nomad.Dev

Nomad.Dev

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 hours ago

Last modified

Categories

Share

Extract property listings from BuyRentKenya.com — Kenya's largest real-estate portal. Search houses, flats & apartments, land and commercial property for sale or rent by location, and get clean structured JSON. Server-rendered pages — no login, no browser, no proxies needed.

What BuyRentKenya data does this scraper extract?

One flat JSON record per listing:

FieldMeaning
idBuyRentKenya listing id
titleListing title as posted
priceNumeric price in KES
currencyKES
locationCombined area, city, county string
county / city / areaLocation parts
bedrooms / bathroomsRoom counts (bathrooms need fetchDetails)
areaSqmPlot / floor surface where provided
propertyTypee.g. Townhouses for sale, Other Apartments for rent
listingTypesale or rent
agencyListing agency / seller name
sellerTypeagency / individual where provided
daysOnMarketDays since posting
postedAtPosting date (exact with fetchDetails, else derived)
imagesCountPhoto count (needs fetchDetails)
descriptionFull listing description (needs fetchDetails)
urlDirect link to the listing
isNewtrue on every record when onlyNewSinceLastRun is on (search mode only — see below)

Input

NameTypeDefaultDescription
searchTypestring (buy|rent)buySearch listings for sale or for rent.
propertyTypestringallCategory to search: houses, flats-apartments, land, commercial, bedsitters, or all.
locationstringnairobiLocation path slug (nairobi, mombasa, nairobi/westlands, …). Empty = all of Kenya.
minPriceinteger0Drop listings priced below this (KES). 0 = no minimum. Client-side filter.
maxPriceinteger0Drop listings priced above this (KES). 0 = no maximum. Client-side filter.
minBedroomsinteger0Drop listings with fewer bedrooms than this. Free from the search-page card; no fetchDetails needed. Search mode only.
minBathroomsinteger0Drop listings with fewer bathrooms than this. Bathrooms are detail-page-only, so this auto-enables fetchDetails if it's off. Search mode only.
maxPagesinteger3Search-result pages to crawl per category (25 listings/page). Hard cap 10 (robots.txt).
maxItemsinteger100Hard cap on total listings returned. 0 = no cap. Max 1000. Billed at $0.004/listing — see Pricing.
fetchDetailsbooleanfalseVisit each listing's detail page for bathrooms, image count, full description and exact publish date. One extra request per listing.
onlyNewSinceLastRunbooleanfalseOnly output listings not seen in a previous run with this flag on. Seen listings aren't billed. Search mode only (no-op with listingUrls — see Delta mode below).
listingUrlsarray of strings[]Scrape these specific https://www.buyrentkenya.com/listings/... URLs instead of running a search (detail mode).
concurrencyinteger4(Advanced) Parallel workers for detail-page fetches. Max 8.

How to scrape BuyRentKenya with this Actor

  1. Pick buy or rent and a property type (or all).
  2. Set location to a URL path slug: nairobi, mombasa, kiambu, nairobi/westlands, nairobi/kilimani… Leave empty for all of Kenya.
  3. Optionally set a KES price range, minBedrooms / minBathrooms, maxPages (25 listings/page, max 10 pages per the site's robots.txt) and fetchDetails for bathrooms, photos, description and exact posting date.
  4. Turn on onlyNewSinceLastRun for a recurring schedule that only pays for genuinely new listings each time.
  5. Run and export JSON, CSV or Excel — or call it over the API:
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nomad-agent/buyrentkenya-scraper").call(run_input={
"searchType": "rent",
"propertyType": "flats-apartments",
"location": "nairobi/westlands",
"maxPrice": 150000,
"fetchDetails": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["title"], "|", item["price"], item["currency"], item["url"])
curl -X POST \
"https://api.apify.com/v2/acts/nomad-agent~buyrentkenya-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"searchType": "buy", "propertyType": "houses", "location": "nairobi", "maxPages": 3}'

Detail mode: pass listingUrls (full https://www.buyrentkenya.com/listings/... URLs) to scrape specific listings instead of searching.

Delta mode (onlyNewSinceLastRun): turn this on to only get listings this Actor hasn't returned before. It keeps a small per-Actor id cache (up to ~50k listing ids, oldest evicted first) in a named key-value store; each run adds newly-delivered ids and skips (doesn't push, doesn't bill) anything already in the cache. Set isNew: true on every record it does return. It only applies to search mode — if you pass listingUrls you're asking for those exact listings by name, so the flag is a no-op there (every URL you list is always scraped and returned; the Actor logs an info line noting the no-op).

Bedroom/bathroom filters: minBedrooms and minBathrooms are applied as a final pass after search + optional fetchDetails enrichment, and — like minPrice/maxPrice — a listing with an unknown value for the filtered field is dropped once a minimum is set. minBathrooms needs detail-page data, so setting it above 0 silently (and loudly, via a log line) turns fetchDetails on for you even if you left it unchecked; without that auto-enable, bathrooms would always be null and the filter would drop every listing. Like the price filters, both bed/bath filters only apply to search mode, not to explicit listingUrls.

Output example

{
"id": "4007805",
"title": "5 Bed Townhouse with En Suite in Lavington",
"price": 75000000,
"currency": "KES",
"location": "Lavington, Nairobi",
"county": "Nairobi",
"city": "Lavington",
"area": "Lavington",
"bedrooms": 5,
"bathrooms": 6,
"propertyType": "Townhouses for sale",
"listingType": "sale",
"agency": "SRG Properties",
"daysOnMarket": 20,
"postedAt": "2026-06-11",
"imagesCount": 20,
"url": "https://www.buyrentkenya.com/listings/5-bedroom-townhouse-for-sale-lavington-4007805",
"source": "buyrentkenya",
"searchType": "buy",
"isNew": true
}

isNew is only present when onlyNewSinceLastRun is on; older integrations that don't expect the field can safely ignore it.

Integrations

Export results as JSON, CSV, Excel (XLSX), HTML or RSS straight from the Apify Console, or wire the dataset into Make, Zapier, n8n and other Apify integrations. For code, use run-sync-get-dataset-items (shown above) for a single synchronous call, the apify-client SDKs, or the Apify MCP server to drive this Actor from an LLM/agent tool loop.

Pricing

Pay per event: $0.05 per Actor start and $0.004 per listing returned. 100 listings ≈ $0.45 (the default maxItems). No subscription — pay only for what you fetch. Listings skipped by onlyNewSinceLastRun because they were already delivered in a previous run are never pushed, so they're never billed either.

Use cases

  • Kenya property market research: price levels by county, city and area
  • Track new sale/rent inventory in specific neighbourhoods (Westlands, Kilimani, Karen…)
  • Feed valuation models and rental-yield dashboards with fresh KES prices
  • Monitor agency activity and days-on-market trends
  • Aggregate listings into your own real-estate app or newsletter

FAQ

Does it need a browser or proxies? No. BuyRentKenya server-renders its pages; the Actor parses plain HTML plus embedded structured data.

Why is pagination capped at 10 pages? The site's robots.txt only permits ?page=2?page=10. The Actor respects that; narrow by location/category to cover more inventory.

Why filter price (and bedrooms/bathrooms) client-side? Filter query params (price=, bedrooms=, …) are disallowed by the site's robots.txt, so the Actor fetches the plain category pages it may crawl and filters minPrice/maxPrice/minBedrooms/minBathrooms in-Actor, after the page is fetched.

Why does setting minBathrooms turn on fetchDetails for me? Bathroom counts only exist on a listing's detail page — the search-page card never has them. Silently applying minBathrooms without fetchDetails would see every listing's bathrooms as unknown and drop everything, which is a worse failure mode than a slower, slightly pricier run that actually honors the filter you asked for. The Actor logs an info line whenever it does this auto-enable.

Does maxItems, together with onlyNewSinceLastRun, ever lose listings? No. A listing is only added to the "seen" id cache once it is actually pushed to the dataset. If a run hits its maxItems cap before delivering every new listing found, the undelivered ones stay untouched in the cache and are picked up (and billed) on the next run instead of being silently dropped.

Is it legal to scrape BuyRentKenya? The Actor reads the same public, unauthenticated pages any visitor sees and follows the site's robots.txt. Review the site's terms for your use case.