# Home.cy Cyprus Real Estate Scraper: Sale and Rent (`recordsdata/home-cy-scraper`) Actor

Scrape home.cy, the Cyprus property portal: sale and rent listings with price, bedrooms, covered and plot area, map position, photos and agency, plus agency profiles and listing counts by district. Filter by place, type and price. Export JSON, CSV, Excel.

- **URL**: https://apify.com/recordsdata/home-cy-scraper.md
- **Developed by:** [RecordsData](https://apify.com/recordsdata) (community)
- **Categories:** Real estate, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $22.00 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![RecordsData](https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner?v=3)

## Home.cy Cyprus Real Estate Scraper: Sale and Rent Listings

> **Home.cy Cyprus Real Estate Scraper exports property data from home.cy, a Cyprus property portal with about 24,470 listings for sale and 2,690 for rent on 2026-11-02. Each row has the amount in euros, bedrooms, bathrooms, covered and plot area, district and area, a map position, photos, dates and the listing agency, and the actor also returns agency profiles and listing counts by district. Export JSON, CSV, Excel, XML or HTML. No login, no API key, no proxy. Pay per result.**

Home.cy publishes houses and apartments for sale and for rent in all five districts of Cyprus: Nicosia, Limassol, Larnaca, Paphos and Famagusta. This actor reads the same public pages a visitor sees, applies the site's own filters, opens every listing page and gives you clean, typed rows that are ready for a spreadsheet, a database or an AI agent.

### What can you scrape from home.cy?

| Record type (`recordTypes`) | What one row is | Size on 2026-11-02 |
|---|---|---|
| `listings` | One sale or rent ad with amount, areas, rooms, location, map position, photos, dates and agency | 24,473 for sale and 2,694 for rent |
| `agencies` | One real estate agency with rating, review count, active listings, team size and a short description | 240 agencies |
| `market-stats` | One search with the number of live listings that match, optionally split by band | any district, area, property type or operation |

Every row has typed fields, and the dataset schema lists 68 of them. Fields a listing does not have are left out, never filled with null.

### Why use this actor?

- **The whole catalog is reachable.** There is no page limit: page 1,500 of a nationwide sale search still returns listings.
- **Real filters, applied by the site:** district, area, house or apartment, subtype, bedrooms, bathrooms, amount, areas, year built, resale or new build.
- **Full detail on every listing,** including the photo list, year built, title deed, energy rating and amenities.
- **Plain HTTP requests, no browser, no proxy.** Three results take about four seconds, and the actor needs only 256 MB of memory.
- **Monitor mode** returns only listings you have not received before.
- **Privacy first.** No phone numbers, no emails, no private person names.

### How to scrape home.cy in four steps

1. Create a free account at https://console.apify.com and open the actor.
2. Choose what to collect, then add filters such as a district, a property type and a maximum amount.
3. Set the maximum number of results and click **Start**.
4. Download the dataset from the **Storage** tab as JSON, CSV or Excel.

You can also paste any home.cy search URL, listing URL, agency URL or the agency directory URL as a start URL, or give a list of listing ids.

### Input

The form has 31 fields. The main ones:

| Field | Type | Default | Meaning |
|---|---|---|---|
| `recordTypes` | array | `listings` | What to collect: `listings`, `agencies` or `market-stats` |
| `maxItems` | integer | 10 | Maximum rows (free plans: 10, paid plans: up to 1,000,000) |
| `operation` | string | `sale` | `sale`, `rent` or `both` |
| `propertyTypes` / `subtypes` | array | empty | `house`, `apartment`, and finer types such as `villa` or `penthouse` |
| `districts` / `locations` | array | empty | Districts, and area names such as `Germasogeia` or `limassol/germasogeia` |
| `bedrooms` | array | empty | Bedroom counts to keep |
| `minPrice` / `maxPrice` | number | 0 | Amount in euros (rent is per month), 0 ignores it |
| `minBathrooms`, `minCoveredArea`, `minPlotArea`, `minYearBuilt` (and `max...`) | number | 0 | Range filters, 0 ignores them |
| `condition` | string | `any` | Resale or new build |
| `fetchDetails` | boolean | true | Open every listing page for the full detail |
| `includePriceBands` | boolean | false | Split market statistics by band |
| `includeContactDetails` | boolean | false | Add agency business details |
| `startUrls` / `listingIds` | array | empty | Home.cy pages, or listing ids, to read directly |
| `onlyNew` / `stateKey` / `resetSeen` | boolean / string / boolean | false / empty / false | Monitor mode, its name, and a reset |
| `maxRunSeconds` | integer | 1800 | Longest run time in seconds |

Input for two-bedroom apartments for rent in Limassol:

```json
{
  "recordTypes": ["listings"],
  "operation": "rent",
  "propertyTypes": ["apartment"],
  "districts": ["limassol"],
  "bedrooms": [2],
  "maxPrice": 2000,
  "maxItems": 100
}
```

### What data do you get?

Every row has a `recordType`: `listing`, `agency` or `market-stat`. Fields that do not apply are left out.

#### Listing fields

| Field | Type | Example |
|---|---|---|
| `listingId` | string | `285992` |
| `url` | string | `https://home.cy/real-estate-for-sale/villa-for-sale-in-limassol-285992` |
| `operation` | string | `sale` |
| `propertyType` / `propertySubtype` | string | `house` / `villa` |
| `price` | number | `860000` |
| `currency` / `priceText` | string | `EUR` / `€860,000 plus VAT` |
| `isPlusVat` | boolean | `true` |
| `rentPeriod` | string | `month` (rentals only) |
| `pricePerM2` | number | `4778` |
| `district` / `area` | string | `limassol` / `Parekklisia` |
| `latitude` / `longitude` / `locationRadiusM` | number | `34.7509` / `33.1441` / `750` |
| `areaBuilt` / `areaLand` / `areaVeranda` | number | `180` / `606` / `60` |
| `condition` / `furnished` | string | `off_plan` |
| `amenities` | array | `["Pool", "Balcony"]` |
| `imageCount` / `images` / `thumbnailUrl` / `videoUrl` | number / array / string | `6` |
| `publishedAt` / `updatedAt` | string | `2026-10-29` |
| `agencyName` / `agencyUrl` / `agencyBranch` / `agencyRating` | string / number | `Vivo Realty` / `4.4` |
| `scrapedAt` / `error` / `hint` | string | time of extraction, message when a run has a problem |

#### Agency fields

| Field | Type | Example |
|---|---|---|
| `url` | string | `https://home.cy/vivo-realty` |
| `agencyName` / `agencyBranch` | string | `Vivo Realty` / `Limassol` |
| `agencyRating` / `agencyReviewCount` | number | `4.4` / `18` |
| `agencyVerified` | boolean | `true` |
| `agencyListingCount` / `agencyTeamSize` | number | `770` / `19` |
| `agencyRegistrationNumber` / `agencyLicenseNumber` / `agencyAddress` | string | only with `includeContactDetails` |

#### Market statistics fields

| Field | Type | Example |
|---|---|---|
| `operation` / `district` | string | `sale` / `paphos` |
| `totalListings` | number | `4352` |
| `priceBands` | array | `[{"label": "Up to 99,999", "maxPrice": 99999, "listings": 13}]` |

When `locationRadiusM` is present, `latitude` and `longitude` are the centre of a circle of that radius (200 to 1,000 meters), so treat the point as area level.

#### Sample output

```json
{
  "recordType": "listing",
  "listingId": "285992",
  "url": "https://home.cy/real-estate-for-sale/villa-for-sale-in-limassol-285992",
  "operation": "sale",
  "price": 860000,
  "currency": "EUR",
  "priceText": "€860,000 plus VAT",
  "pricePerM2": 4778,
  "district": "limassol",
  "area": "Parekklisia",
  "locationRadiusM": 750,
  "bedrooms": 3,
  "bathrooms": 2,
  "areaBuilt": 180,
  "condition": "off_plan",
  "amenities": ["Pool", "Balcony"],
  "publishedAt": "2026-10-29",
  "views": 105,
  "isPrivateSeller": false,
  "agencyName": "Vivo Realty",
  "agencyRating": 4.4
}
```

The real rows also carry `description`, `images` and `scrapedAt`; they are shortened here.

### Monitor new listings

Switch on **Only new listings (monitor mode)** and the actor remembers every listing and agency it delivered, in a named key-value store called `home-cy-seen` in your own Apify account. A scheduled run of the same search then returns only unseen rows, and rows skipped by the monitor are never charged.

### Pricing

Pay per result, no monthly fee. Rates are USD per event on the Free tier.

| Event | Charged for | Per result | Per 1,000 |
|---|---|---|---|
| Listing record | One sale or rent ad from the search | $0.022 | $22.00 |
| Listing detail record | Added when the listing page is opened (`fetchDetails`) | $0.01467 | $14.67 |
| Agency record | One agency profile | $0.02933 | $29.33 |
| Market statistics record | One search with its listing count | $0.03667 | $36.67 |

Worked examples: 1,000 listings from the search cards only (`fetchDetails` off) cost $22.00. 1,000 listings with full detail cost 1,000 x ($0.022 + $0.01467) = $36.67. All 240 agencies cost 240 x $0.02933 = $7.04. Error rows, empty searches and rows skipped by monitor mode are never charged.

### How does it compare with other Cyprus property scrapers? (read on 2026-11-03)

No other actor on the Apify Store covers home.cy. The nearest Cyprus property actors read other portals.

| | This actor | sian.agency/bazaraki-property-scraper | swerve/spitogatos-scraper |
|---|---|---|---|
| Source | home.cy | bazaraki.com | spitogatos.gr (Greece and Cyprus) |
| Published fields | 68 data fields | 69 | 50 |
| Record types | Listings, agencies, market statistics | Listings | Listings |
| Band counts and listing counts | Yes, one row per search | Not stated | Not stated |
| Monitor mode | Built in, charged only for new rows | Not stated | Not stated |
| Runs and users in 30 days | New actor | 116 runs, 3 users | 3,768 runs, 8 users |

Choose this actor when you need home.cy data in particular. It complements a classifieds source such as Bazaraki rather than replacing it.

### Is it legal to scrape home.cy? Limits and responsible use

The actor reads publicly visible pages without a login, without solving captchas and without bypassing any protection, at about 1.6 requests per second. If home.cy shows its robot check, the actor never tries to get around it: it waits, slows down and stops after three tries.cy allows generic crawlers and blocks named SEO and AI bots, but the file also says that the site terms prohibit automated systems unless prior written approval has been obtained. Check the site terms before republishing commercially, and get approval from home.cy when your use needs it. Phone numbers, emails and the names of private persons are never output, and agency business details are returned only when you switch them on.

Limits:

- Listings with an amount on request have no `price`; the `priceText` field keeps the text.
- Band counts do not overlap and add up to slightly less than the total, because a few listings state no amount.
- Free Apify plans are limited to 10 results per run.

### Use with AI agents (MCP)

Connect the Apify MCP server to Claude, Cursor or another MCP client and this actor appears as a tool: `https://mcp.apify.com?tools=RecordsData/home-cy-scraper`.

Example prompt: "Find the 20 newest two-bedroom apartments for rent in Limassol under 2,000 euros a month and list amount, area, agency and URL."

### Run it from code

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('RecordsData/home-cy-scraper').call({ operation: 'sale', districts: ['paphos'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0].title, items[0].price);
```

Python client, Make, Zapier, n8n and Apify schedules also work.

### Frequently Asked Questions

#### What does the Home.cy Cyprus Real Estate Scraper return?

Sale and rent listings of houses and apartments in Cyprus with the amount, bedrooms, bathrooms, covered and plot area, district, area, map position, photos, dates and the agency that advertises them. It can also return agency profiles and listing counts per search, so one actor covers listings, agencies and a quick market picture.

#### Do I need a proxy, a login or an API key?

No. The actor reads public pages with plain HTTP requests and needs no proxy, no account on home.cy and no API key. You only need an Apify account to run it, and the free plan returns up to 10 results per run, which is enough to test your filters before a large export.

#### How many listings can I get in one run?

As many as the filters match, up to the Max Items limit you set. Home.cy has no page limit, so a nationwide search can run through all 24,000 sale listings. Free Apify plans return up to 10 results per run, paid plans up to 1,000,000. Use the per-search cap to share the budget between several districts.

#### How do I search one district, one village or one range of amounts?

Pick districts, or write area names in **Locations** (for example `Germasogeia` or `Peyia`). When a name exists in several districts, write it as `district/area`, for example `limassol/germasogeia`. Add **Min price** and **Max price** in euros. Rent amounts are per month, so 2,000 means 2,000 euros a month.

#### How is the amount stored?

`price` is a number in euros and `priceText` keeps the text of the site, for example "€860,000 plus VAT". `isPlusVat` tells you when VAT is on top, and `rentPeriod` is `month` for rentals. `pricePerM2` is calculated for sales from the amount and the covered area. Listings with an amount on request have no `price` field.

#### Does it return phone numbers and agent names?

No. Phone numbers, emails and personal names are never output. You get the agency name, branch, rating and profile link. With **Include agency business details** on, agency rows also carry the registration number, licence number and office address that the agency publishes about itself.

#### What are market statistics?

One row per search with the number of listings that match a district, area, property type and operation. Switch on **Split market statistics by price band** to get the count in each band as well, which gives you a quick supply picture without downloading every listing. Each row is one billed event.

#### Can I get only the newest listings?

Yes. Use monitor mode, which remembers every row already delivered and returns only unseen ones on the next scheduled run, or sort by newest first and set a small Max Items. Monitor mode is the better choice for a daily feed, because skipped rows are never charged and the search stops early.

#### How much does a run cost?

The actor is billed per result. A listing record costs $0.022, so 1,000 listings from the search cards cost $22.00, and opening each listing page adds $0.01467, which makes $36.67 per 1,000 with full detail. Agency rows cost $0.02933 and market statistics rows $0.03667. Errors, empty searches and monitor skips are never charged.

#### What happens when the search finds nothing or the input is wrong?

A search without results ends the run cleanly with no rows and no charge. A wrong value, such as a minimum amount above the maximum, an unknown place name or a subtype that does not match the property type, ends the run as succeeded with one free error row that explains what to change. Nothing is charged for it.

### Support

Questions, feature requests or a field you need: write to contact.punkrecordsdata@gmail.com or open an issue on the actor page.

This actor is an independent tool and is not affiliated with home.cy.

Last updated: 2026-11-03

# Actor input Schema

## `recordTypes` (type: `array`):

Listings = one row per sale or rent ad (most common). Agencies = one row per real estate agency. Market statistics = number of listings per search. You can pick several.

## `maxItems` (type: `integer`):

Stops after this many rows, for example 50. Free plans are capped at 10. Paid plans: up to 1,000,000.

## `maxItemsPerSearch` (type: `integer`):

Only matters when your filters create several searches (several districts, types or bedroom counts). Stops one big search from using the whole budget. 0 means no per-search limit.

## `operation` (type: `string`):

Sale, rent, or both (both runs every search twice).

## `propertyTypes` (type: `array`):

Houses, apartments, or both (empty means both).

## `subtypes` (type: `array`):

Finer type, for example villa or penthouse. A subtype must match the chosen property type.

## `districts` (type: `array`):

Cyprus districts to search. Empty means the whole island.

## `locations` (type: `array`):

For example Germasogeia, Peyia, Strovolos. If a name exists in several districts write district/area, for example limassol/germasogeia.

## `bedrooms` (type: `array`):

Exact bedroom counts; each choice is a separate search. Empty means any.

## `condition` (type: `string`):

Any returns both.

## `sortBy` (type: `string`):

Order of the results. The default is the site order (newest and promoted first). With monitor mode on, keep the default so earlier runs can be skipped quickly.

## `minPrice` (type: `number`):

Lowest price in euros (monthly rent when the operation is rent). 0 means no limit.

## `maxPrice` (type: `number`):

Highest price in euros (monthly rent when the operation is rent). 0 means no limit.

## `minBathrooms` (type: `number`):

Fewest bathrooms. 0 means no limit.

## `maxBathrooms` (type: `number`):

Most bathrooms. 0 means no limit.

## `minCoveredArea` (type: `number`):

Smallest built (covered) area in square meters. 0 means no limit.

## `maxCoveredArea` (type: `number`):

Largest built (covered) area in square meters. 0 means no limit.

## `minPlotArea` (type: `number`):

Smallest plot (land) area in square meters. 0 means no limit.

## `maxPlotArea` (type: `number`):

Largest plot (land) area in square meters. 0 means no limit.

## `minYearBuilt` (type: `integer`):

Earliest construction year. 0 means no limit.

## `maxYearBuilt` (type: `integer`):

Latest construction year. 0 means no limit.

## `startUrls` (type: `array`):

A search page (every filter in the address is kept), a listing page, the agency directory or an agency page. English URL without a language prefix. Example: https://home.cy/real-estate-for-sale/apartments/limassol?bedrooms_min=2

## `listingIds` (type: `array`):

The number at the end of a listing URL, for example 285992. Each one is fetched with full detail.

## `fetchDetails` (type: `boolean`):

On: full description, all photos, map position, plot area, year built, title deed, energy rating, amenities and agency. Costs one extra page read per listing. Off: faster and cheaper, search-card fields only.

## `includeContactDetails` (type: `boolean`):

Adds registration and licence numbers, office address and map position. Business data of registered agencies only.

## `includePriceBands` (type: `boolean`):

Only for Market statistics: also counts listings per price band. Adds a few requests per row.

## `agencyName` (type: `string`):

For example vivo.

## `agencyLanguage` (type: `string`):

Agencies only: keep agencies that speak this language.

## `onlyNew` (type: `boolean`):

Delivers only listings and agencies not seen by an earlier run with the same filters. Memory is kept in your own account.

## `stateKey` (type: `string`):

One name per saved search, for example limassol-2br. Empty derives one from your filters.

## `resetSeen` (type: `boolean`):

Starts again from the first page.

## `maxRunSeconds` (type: `integer`):

The run stops cleanly after this many seconds and keeps what it has, for example 1800.

## Actor input object example

```json
{
  "recordTypes": [
    "listings"
  ],
  "maxItems": 10,
  "maxItemsPerSearch": 0,
  "operation": "sale",
  "propertyTypes": [],
  "subtypes": [],
  "districts": [],
  "locations": [],
  "bedrooms": [],
  "condition": "any",
  "sortBy": "relevance_desc",
  "minPrice": 0,
  "maxPrice": 0,
  "minBathrooms": 0,
  "maxBathrooms": 0,
  "minCoveredArea": 0,
  "maxCoveredArea": 0,
  "minPlotArea": 0,
  "maxPlotArea": 0,
  "minYearBuilt": 0,
  "maxYearBuilt": 0,
  "startUrls": [],
  "listingIds": [],
  "fetchDetails": true,
  "includeContactDetails": false,
  "includePriceBands": false,
  "agencyName": "",
  "agencyLanguage": "any",
  "onlyNew": false,
  "stateKey": "",
  "resetSeen": false,
  "maxRunSeconds": 1800
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields per row

## `fullData` (type: `string`):

Complete dataset with all fields

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "recordTypes": [
        "listings"
    ],
    "maxItems": 10,
    "operation": "sale",
    "locations": [],
    "startUrls": [],
    "listingIds": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("recordsdata/home-cy-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "recordTypes": ["listings"],
    "maxItems": 10,
    "operation": "sale",
    "locations": [],
    "startUrls": [],
    "listingIds": [],
}

# Run the Actor and wait for it to finish
run = client.actor("recordsdata/home-cy-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "recordTypes": [
    "listings"
  ],
  "maxItems": 10,
  "operation": "sale",
  "locations": [],
  "startUrls": [],
  "listingIds": []
}' |
apify call recordsdata/home-cy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,recordsdata/home-cy-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5eNsjAGJUnVYiFsf8/builds/7pvZFa22s1vmUZ1jL/openapi.json
