# Sarouty Scraper - Morocco Real Estate (`atlasdata-labs/sarouty-scraper-morocco-real-estate`) Actor

Scrape Sarouty.ma property listings across Morocco: sale and rent prices in MAD, surface, price per m², bedrooms, city and district. Direct data access, no browser or proxy needed. Clean, deduplicated, no personal contact data.

- **URL**: https://apify.com/atlasdata-labs/sarouty-scraper-morocco-real-estate.md
- **Developed by:** [Atlas Data](https://apify.com/atlasdata-labs) (community)
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listing scrapeds

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

## Sarouty Scraper - Morocco Real Estate Listings

Extract property listings from Sarouty.ma, one of Morocco's main real estate portals. Type a city, choose buy or rent, pick a property type, and get clean, structured data in seconds: price, surface, price per m², bedrooms, district, agency, publication date and photos. Export to JSON, CSV or Excel, or connect it to your tools through the Apify API.

**Keywords:** Sarouty scraper, Morocco real estate scraper, Morocco property data, Marrakech real estate, Casablanca apartments, Rabat property prices, Tangier villas, price per m² Morocco, immobilier Maroc, annonces immobilières Maroc, prix m² Maroc.

*[Version française plus bas](#version-française)*

### What does Sarouty Scraper do?

- 🏙️ **Any city or district in Morocco:** "Marrakech", "Casablanca", or a precise district like "Agdal, Rabat"
- 🏠 **20 property types:** apartments, villas, riads, houses, land, farms, offices, shops, restaurants and more
- 🎯 **Filters:** price, surface, bedrooms, bathrooms
- ⚡ **Fast:** around 1,000 listings in a few seconds
- 💰 **All-inclusive price:** $1.50 per 1,000 listings, no hidden platform costs
- 📐 **Analysis-ready:** price per m² for sales, monthly rent per m² for rentals, prices as numbers, placeholder values (like a 1 MAD price) removed
- 🔒 **Privacy-friendly:** agent names, phone numbers and emails are never collected, only the agency name

No URL to copy from the website, no browser, no login.

> 💰 **All-inclusive pricing: $1.50 per 1,000 listings.** No proxy or browser costs on top: this actor calls the data source directly, so platform usage is included in the price.

### Who is it for?

**Real estate investors and Moroccans living abroad**

- Compare price per m² between cities and districts before buying
- Monitor a city or a district and spot new listings early
- Find listings priced below the local average

**Agencies, developers and property managers**

- Benchmark your listings against the market
- Track the supply of competitors in your area
- Follow price trends over time

**Analysts, researchers and proptech teams**

- Feed dashboards, price models and market studies
- Build time series by scheduling regular runs

### Real run results

| Search | Listings | Duration | Actor cost\* |
|---|---|---|---|
| Marrakech, buy, apartments | 319 | ~5 s | ~$0.48 |
| All Morocco, buy, apartments | 1,114 | ~5 s | ~$1.68 |
| Marrakech, buy, apartments, 1-3 M MAD, 2+ bedrooms, max 150 m² | 168 | ~2 s | ~$0.26 |

\*Total cost including the run start, at the price below. Listing counts change every day as listings are published and removed.

### Pricing

Pay per event: you only pay for the listings you get. Platform usage is included: no proxy, browser or compute costs on top.

| Event | Price |
|---|---|
| Run start | $0.005 |
| Per listing | $0.0015 ($1.50 per 1,000 listings) |

**Tip:** set a *Maximum charge per run* in the run options to control your budget on large searches.

### How to use it

1. Click **Try for free** to open the actor in Apify Console.
2. Type one or more cities (or "District, City").
3. Choose **Buy** or **Rent** and a property type.
4. Optionally add filters (price, surface, bedrooms).
5. Click **Start**, then export the results as JSON, CSV or Excel.

**First run recommendation:** start with one city and set *Max listings* to 50. Check the fields and the cost, then scale up.

### Input

| Field | Description | Example |
|---|---|---|
| Cities or districts | One per line. A city, or "District, City" for a precise district. Empty = all of Morocco. | Marrakech, Agdal, Rabat |
| Transaction | buy or rent | buy |
| Property type | any (residential), any_commercial, all, or a specific type | apartment |
| Min / Max price (MAD) | Price range. For rentals, monthly rent. | 1000000 / 3000000 |
| Min / Max surface (m²) | Surface range | 60 / 150 |
| Min / Max bedrooms | Number of bedrooms | 2 / 4 |
| Min bathrooms | Minimum number of bathrooms (often missing at the source) | 2 |
| Max pages per search | Optional limit, 100 listings per page | 5 |
| Max listings | Optional limit on the total number of listings | 500 |

**Property types:** apartment, studio, duplex, triplex, villa, house, riad, chalet, land, farm, building, office, shop, commercial villa, restaurant, factory, warehouse.

Simple input:

```json
{
    "locations": ["Marrakech"],
    "transaction": "buy",
    "property_type": "apartment"
}
```

With filters and several locations:

```json
{
    "locations": ["Casablanca", "Agdal, Rabat"],
    "transaction": "rent",
    "property_type": "apartment",
    "max_price": 15000,
    "min_bedrooms": 2,
    "min_surface": 70
}
```

### Output

Each item is one listing:

```json
{
    "source": "sarouty",
    "source_listing_id": "907965",
    "listing_url": "https://www.sarouty.ma/en/buy/apartment-marrakech-route-de-casablanca-907965/",
    "title": "Appartement à Bd Abdelkrim El Khattabi, Piscine + Ascenseur, Marrakech : à vendre",
    "transaction_type": "sale",
    "property_type": "apartment",
    "property_type_raw": "Appartement",
    "category": "Residential",
    "city": "Marrakech",
    "district": "Route de Casablanca",
    "price_mad": 1500000,
    "currency": "MAD",
    "price_period": null,
    "surface_m2": 136,
    "price_per_m2": 11029.41,
    "rent_per_m2": null,
    "bedrooms": 2,
    "bathrooms": null,
    "furnished": null,
    "agency_name": "L'Immobilier Sans Frontières",
    "publication_date": "2026-09-02T09:02:41.000Z",
    "image_url": "https://...",
    "images_count": 10,
    "scraped_at": "2026-10-07T13:04:29.463Z"
}
```

| Field | Description |
|---|---|
| `price_mad` | Price in Moroccan dirhams. For rentals, the monthly rent. |
| `price_period` | `null` for sales, `"month"` for rentals |
| `price_per_m2` | Sales only: `price_mad / surface_m2`, when the surface is known |
| `rent_per_m2` | Rentals only: monthly rent per m² |
| `furnished` | `true`, `false`, or `null` when unknown |
| `publication_date` | Date the listing was published on Sarouty |
| `source_listing_id` | Stable ID, useful to track a listing across runs |

### Guide: monitor a market over time

1. Run the actor once for your target city to get a baseline.
2. In Apify Console, open **Schedules** and create a daily or weekly schedule with the same input.
3. Each run creates a new dataset. Compare them using `source_listing_id` to detect new listings, removed listings and price changes.
4. Connect the **Google Sheets** integration to get an automatically updated spreadsheet, or a **Slack** notification when each run finishes.

### Guide: compare districts without coding

1. Run a city with your property type (for example Marrakech, buy, apartment).
2. Export to CSV and open it in Excel or Google Sheets.
3. Create a pivot table: district in rows, average of `price_per_m2` in values.
4. Sort by price per m² to see the most and least expensive districts, then filter listings below the district average to spot potential deals.

### Use it from your code

Replace `YOUR_API_TOKEN` with your Apify API token.

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("atlasdata-labs/sarouty-scraper-morocco-real-estate").call(run_input={
    "locations": ["Marrakech"],
    "transaction": "buy",
    "property_type": "apartment",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items))
```

**Node.js**

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('atlasdata-labs/sarouty-scraper-morocco-real-estate').call({
    locations: ['Marrakech'],
    transaction: 'buy',
    property_type: 'apartment',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length);
```

**cURL** (runs the actor and returns the listings directly)

```bash
curl -X POST "https://api.apify.com/v2/acts/atlasdata-labs~sarouty-scraper-morocco-real-estate/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"locations": ["Marrakech"], "transaction": "buy", "property_type": "apartment"}'
```

### Use it with AI assistants (MCP)

Sarouty Scraper can be used by AI assistants that support the Model Context Protocol, through the Apify MCP server:

```
https://mcp.apify.com?tools=atlasdata-labs/sarouty-scraper-morocco-real-estate
```

Then ask, for example: *"Get apartments for sale in Marrakech under 2 million MAD and give me the average price per m² by district."*

### Integrations

Send the results to Google Sheets, Slack, Make, Zapier, Airbyte, webhooks or your own database with Apify integrations.

### FAQ

**Why did I get fewer listings than the total shown on Sarouty?**
Listings are published and removed continuously, and they can move between pages during a run. Duplicates are removed automatically. Filters on surface, bedrooms and bathrooms also exclude listings where that information is missing.

**Why is the number of bathrooms often empty?**
Many agencies don't fill it in on Sarouty. The actor returns what the source provides.

**Can I search several cities in one run?**
Yes, add one city per line. You pay the run start only once.

**What if a district name exists in several cities?**
Add the city: "Agdal, Rabat" instead of "Agdal". The log tells you which location was used.

### Is it legal?

The actor only collects publicly available listing data and deliberately excludes personal data about agents. You remain responsible for how you use the data, in line with applicable laws (including data protection rules) and the website's terms of use.

### Built by Atlas Data

For ready-made analyses of the Moroccan property market (median price per m² by district, weekly updates), visit [atlas-data.fr](https://atlas-data.fr).

### Disclaimer

This actor is an independent tool. It is not affiliated with, endorsed by, or sponsored by Sarouty. All trademarks belong to their respective owners.

***

### Version française

#### Ce que fait cet actor

Extrayez les annonces immobilières de Sarouty.ma : tapez une ville, choisissez achat ou location et un type de bien, et obtenez en quelques secondes des données propres : prix, surface, prix au m², chambres, quartier, agence, date de publication et photos. Export JSON, CSV ou Excel.

- 🏙️ **Toutes les villes et quartiers du Maroc :** "Marrakech", ou "Agdal, Rabat" pour un quartier précis
- 🏠 **20 types de biens :** appartements, villas, riads, maisons, terrains, bureaux, magasins...
- 🎯 **Filtres :** prix, surface, chambres, salles de bain
- ⚡ **Rapide :** environ 1 000 annonces en quelques secondes
- 🔒 **Aucune donnée personnelle :** seul le nom de l'agence est conservé

#### Pour qui ?

- **Investisseurs et MRE :** comparer les prix au m² par ville et par quartier, repérer les nouvelles annonces et les biens sous le prix du marché
- **Agences et promoteurs :** se situer face au marché et suivre l'offre concurrente
- **Analystes et proptech :** alimenter tableaux de bord, modèles de prix et études

#### Utilisation

1. Indiquez une ou plusieurs villes (ou "Quartier, Ville")
2. Choisissez achat ou location et le type de bien
3. Ajoutez des filtres si besoin (prix, surface, chambres)
4. Lancez, puis exportez en JSON, CSV ou Excel

**Conseil :** pour un premier essai, limitez à 50 annonces. Pour suivre le marché, programmez l'actor chaque jour ou chaque semaine.

#### Tarif

0,005 $ par lancement, puis 1,50 $ pour 1 000 annonces, tout compris : aucun coût de proxy, de navigateur ou de plateforme en plus.

#### Analyses prêtes à l'emploi

Pour des analyses du marché immobilier marocain (prix médian au m² par quartier, mises à jour chaque semaine), rendez-vous sur [atlas-data.fr](https://atlas-data.fr).

#### Clause de non-responsabilité

Cet actor est un outil indépendant, non affilié à Sarouty, ni approuvé ou sponsorisé par Sarouty. Les marques citées appartiennent à leurs propriétaires respectifs.

# Actor input Schema

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

One per line: a city ("Marrakech") or a district with its city ("Agdal, Rabat"). Leave empty to search all of Morocco.

## `transaction` (type: `string`):

Buy or rent.

## `property_type` (type: `string`):

Type of property.

## `max_pages` (type: `integer`):

Leave empty to fetch all pages.

## `max_items` (type: `integer`):

Stop after this many listings in total. Leave empty for no limit.

## `min_price` (type: `integer`):

Minimum price. For rentals, monthly rent.

## `max_price` (type: `integer`):

Maximum price. For rentals, monthly rent.

## `min_surface` (type: `integer`):

Minimum surface. Listings without this information are excluded when this filter is set.

## `max_surface` (type: `integer`):

Maximum surface. Listings without this information are excluded when this filter is set.

## `min_bedrooms` (type: `integer`):

Minimum number of bedrooms. Listings without this information are excluded when this filter is set.

## `max_bedrooms` (type: `integer`):

Maximum number of bedrooms. Listings without this information are excluded when this filter is set.

## `min_bathrooms` (type: `integer`):

Minimum number of bathrooms. Often missing on Sarouty, use with care. Listings without this information are excluded when this filter is set.

## Actor input object example

```json
{
  "locations": [
    "Marrakech"
  ],
  "transaction": "buy",
  "property_type": "apartment",
  "max_items": 50
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "locations": [
        "Marrakech"
    ],
    "transaction": "buy",
    "property_type": "apartment",
    "max_items": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("atlasdata-labs/sarouty-scraper-morocco-real-estate").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 = {
    "locations": ["Marrakech"],
    "transaction": "buy",
    "property_type": "apartment",
    "max_items": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("atlasdata-labs/sarouty-scraper-morocco-real-estate").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 '{
  "locations": [
    "Marrakech"
  ],
  "transaction": "buy",
  "property_type": "apartment",
  "max_items": 50
}' |
apify call atlasdata-labs/sarouty-scraper-morocco-real-estate --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,atlasdata-labs/sarouty-scraper-morocco-real-estate"
        }
    }
}
```

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/M0jf7SrtekwPKM2iO/builds/CRnbDv5cwRCy4TgFa/openapi.json
