# Kyero Scraper — Property Listings, Coordinates & Agent Contacts (`haketa/kyero-scraper`) Actor

Scrape Kyero.com for Spanish and European properties for sale & rent. Extract price, coordinates, bedrooms, size, features, agent contacts, images and listing dates. Keyword search + URL modes. ES residential proxy for Cloudflare bypass.

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

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Kyero Scraper — European Property Listings, Coordinates & Agent Contacts

Scrape **Kyero.com**, the leading European property portal for international buyers, covering **Spain, Portugal, France, and Italy**. Extract properties for sale and rent with **price, GPS coordinates, bedrooms, size, features, agent contact details, images, and listing dates** — data that competing Kyero scrapers miss.

Unlike other Kyero actors that only parse HTML listing cards, this scraper visits each property detail page to extract **latitude/longitude coordinates, agent phone/email/website, full feature lists, and listing dates** — fields essential for serious real estate analysis that competitors leave empty.

**Spanish residential proxy required** — Kyero uses Cloudflare that geo-gates non-EU IPs. Included by default.

***

### ⚡ Quick Start

```json
{
    "country": "spain",
    "query": "barcelona",
    "maxItems": 50
}
```

👉 50 Barcelona properties with prices, coordinates, bedrooms, and agent contacts.

***

### 🌍 Countries

| Country | URL Pattern | Currency |
|---------|------------|----------|
| 🇪🇸 **Spain** | kyero.com/en/spain-property-for-sale | EUR (€) |
| 🇵🇹 **Portugal** | kyero.com/en/portugal-property-for-sale | EUR (€) |
| 🇫🇷 **France** | kyero.com/en/france-property-for-sale | EUR (€) |
| 🇮🇹 **Italy** | kyero.com/en/italy-property-for-sale | EUR (€) |

***

### Data Fields

| Category | Fields |
|----------|--------|
| **Identity** | `propertyId`, `title`, `url`, `referenceNo` |
| **Price** | `price` (numeric), `priceFormatted` (e.g. "€345,000") |
| **Property** | `propertyType`, `bedrooms`, `bathrooms`, `builtM2`, `plotM2` |
| **Location** | `address`, `latitude`, `longitude` ✅ |
| **Features** | `features` (JSON array: pool, terrace, lift, sea view...) |
| **Description** | `description` (full text) |
| **Media** | `images` (JSON array of URLs) |
| **Agent** | `agentName`, `agentPhone`, `agentEmail`, `agentWebsite` |
| **Dates** | `dateListed`, `scrapedAt` |
| **Listing** | `listingType` (for\_sale / to\_rent) |

***

### Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `country` | select | spain | Spain / Portugal / France / Italy |
| `listingType` | select | for\_sale | For Sale / To Rent |
| `query` | string | barcelona | Location keyword (barcelona, alicante, paris...) |
| `startUrls` | array | \[] | Kyero search or property URLs (overrides country/query) |
| `includeDetails` | boolean | true | Visit detail pages for coordinates, agent, features |
| `maxItems` | integer | 100 | Maximum properties (0 = no limit) |
| `maxPages` | integer | 5 | Search result pages |
| `requestDelay` | integer | 500 | Delay between detail requests (ms) |
| `maxConcurrency` | integer | 8 | Parallel detail page requests |
| `proxyConfiguration` | proxy | ES RESIDENTIAL | Required — Cloudflare geo-gating |

***

### Use Cases

- **Property investment analysis** — Coordinates enable map-based market analysis
- **Agent lead generation** — Phone + email from detail pages for B2B outreach
- **Market research** — Price/m² trends across Spanish regions
- **Relocation services** — Curated property lists for international buyers

***

### Integration

#### JavaScript

```javascript
const run = await client.actor('haketa/kyero-scraper').call({ country: 'spain', query: 'alicante', maxItems: 100 });
```

#### Python

```python
run = client.actor('haketa/kyero-scraper').call(run_input={'country': 'spain', 'query': 'alicante', 'maxItems': 100})
```

#### CLI

```bash
apify call haketa/kyero-scraper --input '{"country":"spain","query":"barcelona","maxItems":100}'
```

***

### FAQ

**Q: Why coordinates matter?**
A: Without lat/lng, you can't map properties, calculate distances to amenities, or do spatial market analysis. memo23 and other Kyero scrapers don't extract coordinates — we do.

**Q: Why ES residential proxy?**
A: Kyero uses Cloudflare which challenges non-EU IPs with "Just a moment..." pages. An ES residential proxy makes requests appear as Spanish household visitors.

**Q: Can I search for properties without a city?**
A: Yes — leave `query` empty to scrape all properties in the country. Use `maxItems` to control volume.

***

*The only Kyero scraper with GPS coordinates, agent contacts, and listing dates — data that real estate professionals actually need.*

***

### Performance & Cost

| Mode | Speed | Proxy |
|------|-------|-------|
| Search only (`includeDetails: false`) | ~20-30 props/sec | ES Residential |
| Search + details | ~5-10 props/sec | ES Residential |
| Direct URLs | ~5-10 props/sec | ES Residential |

**Typical cost**: 100 properties with full detail = ~60-90 seconds. ES residential proxy data transfer is the main cost driver.

***

### Example Output

```json
{
    "propertyId": "555123",
    "title": "Apartment in El Masnou, Barcelona province",
    "url": "https://www.kyero.com/en/property/555123",
    "price": "345000",
    "priceFormatted": "€345,000",
    "listingType": "for_sale",
    "bedrooms": "3",
    "bathrooms": "2",
    "builtM2": "120",
    "plotM2": null,
    "propertyType": "Apartment",
    "address": "El Masnou, Costa Garraf / Maresme, Barcelona province, Catalonia, Spain",
    "latitude": "41.4823",
    "longitude": "2.3178",
    "features": "[\"lift\",\"terrace\",\"pool\",\"sea_view\",\"parking\",\"air_conditioning\"]",
    "description": "Beautiful 3-bedroom apartment in El Masnou with sea views...",
    "images": "[\"https://images.kyero.com/.../1.jpg\",\"https://images.kyero.com/.../2.jpg\"]",
    "agentName": "Costa Barcelona Real Estate",
    "agentPhone": "+34 93 123 45 67",
    "agentEmail": "info@costabarcelona.com",
    "agentWebsite": "https://www.costabarcelona.com",
    "referenceNo": "CB-2024-0891",
    "dateListed": "2026-05-15",
    "scrapedAt": "2026-06-22T15:00:00.000Z"
}
```

***

### Anti-Bot Strategy

Kyero uses **Cloudflare** (not Akamai) for bot protection. Our approach:

- **Spanish residential IPs** via Apify's ES residential proxy pool
- **Browser TLS fingerprint** via got-scraping Chrome impersonation
- **Cloudflare challenge detection** — automatically retries with fresh proxy on "Just a moment..." pages
- **Moderate delays** — 500ms between requests with jitter
- **Adaptive retry** — up to 4 attempts per request, doubling backoff

***

### Common Search Queries

#### Spain (most listings)

```
barcelona, madrid, valencia, alicante, malaga, marbella, mallorca, ibiza, costa-blanca, costa-del-sol, murcia, sevilla, granada, cadiz
```

#### Portugal

```
lisbon, algarve, porto, albufeira, lagos, tavira, cascais, silver-coast, madeira
```

#### France

```
paris, nice, cannes, provence, alps, bordeaux, lyon, marseille, cote-dazur, languedoc
```

#### Italy

```
rome, milan, tuscany, florence, venice, lake-como, puglia, sardinia, sicily, umbria, naples
```

***

### Tips & Best Practices

- **Start with list-only**: `includeDetails: false` for a fast scan, then enrich interesting properties via `startUrls`
- **Narrow your query**: "barcelona" returns 10,000+ properties — add qualifiers like "barcelona-beachfront" or use price filters in `startUrls`
- **Monitor for Cloudflare blocks**: If you see "Cloudflare block" warnings, increase `requestDelay` to 1000ms
- **Cross-country comparison**: Run the same listing type across multiple countries to compare price/m²
- **Schedule for new listings**: Weekly runs with `maxPages: 1` to catch newly listed properties
- **Export coordinates**: Use the `latitude`/`longitude` fields to build property heatmaps in tools like Google Maps, Tableau, or Kepler.gl

***

### Data Quality Notes

| Field | Typical Fill Rate | Notes |
|-------|------------------|-------|
| `latitude` | 70-80% | From detail page embedded data |
| `longitude` | 70-80% | From detail page embedded data |
| `agentPhone` | 60-70% | From detail page tel: links |
| `agentEmail` | 40-50% | From detail page mailto: links |
| `agentWebsite` | 50-60% | Agency website when listed |
| `dateListed` | 30-40% | Not always shown on Kyero |
| `features` | 80-90% | Pool, terrace, lift, parking... |
| `builtM2` | 85-95% | Almost always available |
| `plotM2` | 30-40% | Only for houses/villas with land |

***

### Known Limitations

- **Pagination cap**: Kyero limits results to ~20-25 pages per search. Segment by location for larger datasets.
- **Coordinates on detail only**: Coordinates require detail page visit (`includeDetails: true`)
- **ES proxy required**: Without Spanish residential proxy, Cloudflare returns challenge pages
- **Agent contact varies**: Not all listings include agent phone/email — Kyero's page design varies by agency

***

### Legal & Responsible Use

This actor extracts publicly available property listings from Kyero.com. Users are responsible for complying with Kyero's Terms of Service and GDPR where applicable. Data is intended for legitimate real estate market research, investment analysis, and B2B agent outreach.

### 📅 Changelog & Maintenance

**Last updated:** 2026-07-02 — Actor verified and maintained. Data pipeline tested for quality, structure and freshness; selectors/endpoints confirmed against the live site.

# Actor input Schema

## `country` (type: `string`):

Which country's Kyero listings to collect. Leave the default to scrape Spain, the largest market.

## `listingType` (type: `string`):

Choose properties for sale or homes to rent.

## `query` (type: `string`):

Pick a popular area to focus on, or leave as 'Whole country' to cover the entire country selected above. For a very specific town not listed here, use the Start URLs field below.

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

Optional, for power users. Paste specific Kyero search or property page URLs to target an exact town or a single property — this overrides the country and area selected above. Example: 'https://www.kyero.com/en/spain-property-for-sale-0l55529'

## `includeDetails` (type: `boolean`):

Visit each property page to also collect the full description, GPS coordinates, price, bedrooms, all features and agent contact details. On by default. Turn off only if you want a fast ID/URL harvest and will enrich later.

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

Maximum number of properties to collect. Set to 0 for no limit.

## `maxPages` (type: `integer`):

Maximum number of search-result pages to page through per search. Set to 0 for no limit.

## `requestDelay` (type: `integer`):

Pause between requests, in milliseconds. 300-800 ms is a good balance of speed and reliability.

## `maxConcurrency` (type: `integer`):

How many property detail pages to fetch in parallel. Keeping this between 6 and 10 works well.

## `proxyConfiguration` (type: `object`):

Spanish residential proxy is required for reliable access to Kyero. Preconfigured and ready to go — leave as-is unless you have your own Spanish proxy.

## Actor input object example

```json
{
  "country": "spain",
  "listingType": "for_sale",
  "query": "marbella",
  "startUrls": [],
  "includeDetails": true,
  "maxItems": 100,
  "maxPages": 5,
  "requestDelay": 500,
  "maxConcurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  }
}
```

# Actor output Schema

## `propertyId` (type: `string`):

Kyero property ID

## `title` (type: `string`):

Property title

## `url` (type: `string`):

Property page URL

## `price` (type: `string`):

Price in EUR

## `priceFormatted` (type: `string`):

Formatted price (e.g. €345,000)

## `listingType` (type: `string`):

for\_sale / to\_rent

## `bedrooms` (type: `string`):

Number of bedrooms

## `bathrooms` (type: `string`):

Number of bathrooms

## `builtM2` (type: `string`):

Built area in square meters

## `propertyType` (type: `string`):

Apartment/Villa/Townhouse/Penthouse etc.

## `address` (type: `string`):

Full address

## `latitude` (type: `string`):

GPS latitude

## `longitude` (type: `string`):

GPS longitude

## `description` (type: `string`):

Full property description

## `images` (type: `string`):

Property image URLs (JSON array)

## `agentName` (type: `string`):

Estate agent name

## `agentPhone` (type: `string`):

Agent phone number

## `agentEmail` (type: `string`):

Agent email address

## `dateListed` (type: `string`):

Listing date

## `scrapedAt` (type: `string`):

ISO scrape timestamp

# 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 = {
    "country": "spain",
    "listingType": "for_sale",
    "query": "marbella",
    "startUrls": [],
    "includeDetails": true,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "ES"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/kyero-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 = {
    "country": "spain",
    "listingType": "for_sale",
    "query": "marbella",
    "startUrls": [],
    "includeDetails": True,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "ES",
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "country": "spain",
  "listingType": "for_sale",
  "query": "marbella",
  "startUrls": [],
  "includeDetails": true,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "ES"
  }
}' |
apify call haketa/kyero-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=haketa/kyero-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/YclRAZJuFFLzLwBNL/builds/N2dZRB50i6ZWJvjbj/openapi.json
