BuyRentKenya Property Scraper — Kenya Real Estate
Pricing
from $3.40 / 1,000 listing results
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
Maintained by CommunityActor 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:
| Field | Meaning |
|---|---|
id | BuyRentKenya listing id |
title | Listing title as posted |
price | Numeric price in KES |
currency | KES |
location | Combined area, city, county string |
county / city / area | Location parts |
bedrooms / bathrooms | Room counts (bathrooms need fetchDetails) |
areaSqm | Plot / floor surface where provided |
propertyType | e.g. Townhouses for sale, Other Apartments for rent |
listingType | sale or rent |
agency | Listing agency / seller name |
sellerType | agency / individual where provided |
daysOnMarket | Days since posting |
postedAt | Posting date (exact with fetchDetails, else derived) |
imagesCount | Photo count (needs fetchDetails) |
description | Full listing description (needs fetchDetails) |
url | Direct link to the listing |
isNew | true on every record when onlyNewSinceLastRun is on (search mode only — see below) |
Input
| Name | Type | Default | Description |
|---|---|---|---|
searchType | string (buy|rent) | buy | Search listings for sale or for rent. |
propertyType | string | all | Category to search: houses, flats-apartments, land, commercial, bedsitters, or all. |
location | string | nairobi | Location path slug (nairobi, mombasa, nairobi/westlands, …). Empty = all of Kenya. |
minPrice | integer | 0 | Drop listings priced below this (KES). 0 = no minimum. Client-side filter. |
maxPrice | integer | 0 | Drop listings priced above this (KES). 0 = no maximum. Client-side filter. |
minBedrooms | integer | 0 | Drop listings with fewer bedrooms than this. Free from the search-page card; no fetchDetails needed. Search mode only. |
minBathrooms | integer | 0 | Drop listings with fewer bathrooms than this. Bathrooms are detail-page-only, so this auto-enables fetchDetails if it's off. Search mode only. |
maxPages | integer | 3 | Search-result pages to crawl per category (25 listings/page). Hard cap 10 (robots.txt). |
maxItems | integer | 100 | Hard cap on total listings returned. 0 = no cap. Max 1000. Billed at $0.004/listing — see Pricing. |
fetchDetails | boolean | false | Visit each listing's detail page for bathrooms, image count, full description and exact publish date. One extra request per listing. |
onlyNewSinceLastRun | boolean | false | Only 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). |
listingUrls | array of strings | [] | Scrape these specific https://www.buyrentkenya.com/listings/... URLs instead of running a search (detail mode). |
concurrency | integer | 4 | (Advanced) Parallel workers for detail-page fetches. Max 8. |
How to scrape BuyRentKenya with this Actor
- Pick buy or rent and a property type (or
all). - Set location to a URL path slug:
nairobi,mombasa,kiambu,nairobi/westlands,nairobi/kilimani… Leave empty for all of Kenya. - 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.
- Turn on onlyNewSinceLastRun for a recurring schedule that only pays for genuinely new listings each time.
- Run and export JSON, CSV or Excel — or call it over the API:
from apify_client import ApifyClientclient = 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.