# Mubawab API scraper — Morocco and Tunisia real-estate listings (mubawab.ma, mubawab.tn): apartments, houses, villas, riads, land, shops, offices and farms for sale, for rent and as holiday rentals, filtered by city, neighbourhood, price, surface, rooms, bathrooms, amenities and keyword, with price, m², rooms, bedrooms, bathrooms, location, photos and the full listing record: description, characteristics, GPS coordinates and the advertising agency or developer.

> Search Mubawab listings in Morocco (default) or Tunisia. Pick the deal (sale, rent, holiday rental), the property type and optionally a city and neighbourhood, then narrow with price, m², rooms, bathrooms, amenities and a keyword. Every filter was measured against the unfiltered count in the same run. `total` is Mubawab's own count. When fewer listings match than a page holds, Mubawab fills the page with unrelated listings from the wider area — this action removes them and says how many in `dropped_padding`.
> ReefAPI engine `mubawab` · 2 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/mubawab/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/mubawab/v1/search — 3 credits
Search Mubawab listings in Morocco (default) or Tunisia. Pick the deal (sale, rent, holiday rental), the property type and optionally a city and neighbourhood, then narrow with price, m², rooms, bathrooms, amenities and a keyword. Every filter was measured against the unfiltered count in the same run. `total` is Mubawab's own count. When fewer listings match than a page holds, Mubawab fills the page with unrelated listings from the wider area — this action removes them and says how many in `dropped_padding`.

**Parameters:**
- `country` (enum, optional, default "ma") — Which Mubawab site to read. Both serve the same page layout; measured on 2026-10-07: 16 199 apartments for sale in Morocco, 5 133 in Tunisia. [one of: ma, tn]
- `deal` (enum, optional, default "sale") — Sale, long-term rent or holiday rental. [one of: sale, rent, vacation]
- `property_type` (enum, optional, default "apartment") — Kind of property, in Mubawab's own categories. [one of: apartment, house, villa, riad, land, commercial, office, farm, room]
- `city` (string, optional) — City as Mubawab spells it, e.g. 'casablanca', 'Rabat', 'Fès', 'Dar Bouazza', 'tunis'. Accents matter on this site ('fès', 'salé'); for the cities Mubawab links from its home page an unaccented spelling is also accepted. Leave empty for the whole country. An unknown city is an INVALID_PARAM, not an empty list.
- `district` (string, optional) — Neighbourhood inside `city`, as the site prints it on a listing (e.g. 'Maârif', 'Aïn Sebaâ', 'Centre Ville'). Needs `city`. Measured: Casablanca apartments for sale 5 301 → Maârif 191-192.
- `price_min` (integer, optional) — Lowest price in the site's currency (MAD on .ma, TND on .tn). Measured with price_max: Casablanca apartments for sale 5 301 → 2 324 between 1 000 000 and 2 000 000 MAD; price_min 2 000 000 alone → 1 873.
- `price_max` (integer, optional) — Highest price in the site's currency.
- `area_min` (integer, optional) — Smallest surface in m².
- `area_max` (integer, optional) — Largest surface in m².
- `bedrooms_min` (integer, optional) — Minimum number of BEDROOMS (chambres). Measured: the site's own 'rooms' filter counts bedrooms, not pièces — Casablanca apartments for sale 5 301 → 354 at 4+, and every returned row had 4+ bedrooms while some printed fewer pièces.
- `bathrooms_min` (integer, optional) — Minimum number of bathrooms.
- `keyword` (string, optional) — Free-text word searched in the listing text (French works best, e.g. 'piscine', 'vue mer').
- `amenities` (array, optional) — Listings must have ALL of these: new_development, resale, elevator, storage_room, central_heating, air_conditioning, double_glazing, garage, garden, furnished, pool, security, terrace. 'new_development' = units in new-build projects, 'resale' = second-hand. Unknown values are reported in `warnings`. [one of: new_development, resale, elevator, storage_room, central_heating, air_conditioning, double_glazing, garage, garden, furnished, pool, security, terrace]
- `sort` (enum, optional, default "relevance") — Result order. [one of: relevance, newest, price_asc, price_desc]
- `page` (integer, optional, default 1) — Result page. 32 listings per page (31 when the site places a promoted project box on the page). A page past the end returns no rows, `has_more: false`.
- `search_url` (string, optional) — Alternative to the parameters above: any Mubawab result-page URL copied from the site (mubawab.ma or mubawab.tn). `page` still applies.

**Returns:** results[]{id, listing_id, url, listing_kind, deal (always null: the card publishes none), title_deal, title, price{amount, currency, display, on_request, is_starting_price, period}, area_m2, rooms, bedrooms, bathrooms, location, district, city, amenities[], description_snippet, images[], image_count, listing_tier, has_whatsapp} + total + count + page + page_size + last_page + has_more + dropped_padding + promoted_boxes_dropped + search_url + query + warnings[]

**Example request body:**
```json
{
  "country": "ma",
  "deal": "sale",
  "property_type": "apartment",
  "city": "casablanca",
  "price_min": 1000000,
  "price_max": 2000000
}
```

### POST https://api.reefapi.com/mubawab/v1/detail — 3 credits
The full record of one Mubawab listing: description, price, m², rooms, bedrooms, bathrooms, every characteristic the page lists (condition, age, floor, orientation, standing, delivery date for new builds…), amenities, all photos, video, GPS coordinates, and the advertiser — agency or developer name, kind and profile link. The page's own schema.org data is returned beside it as an independent second witness, with any disagreement listed in `witness_mismatch`. `deal` (sale / rent / vacation) is the category the page itself files the ad under; when the advertiser's title names the other deal — Mubawab does file sale ads in rent results — `deal_conflict` is true.

**Parameters:**
- `id` (string, required) — The `id` of a search row, passed exactly as returned (e.g. 8429675), or the full listing URL. Moroccan and Tunisian listings share one id space, so a bare id from either market resolves without `country` (measured: a Tunisian id opened on mubawab.ma lands on the mubawab.tn page). Ordinary ads (/a/) and new-build project units (/pa/) are both accepted.
- `country` (enum, optional, default "ma") — Which Mubawab site to read. Both serve the same page layout; measured on 2026-10-07: 16 199 apartments for sale in Morocco, 5 133 in Tunisia. [one of: ma, tn]

**Returns:** listing{id, listing_id, url, listing_kind, deal, deal_source, listed_category, listed_property_type, title_deal, deal_conflict, title, description, price{...}, area_m2, rooms, bedrooms, bathrooms, property_type, characteristics{}, amenities[], location{label, district, city, latitude, longitude, location_id, address_locality, country}, seller{id, name, kind, profile_url, logo_url}, images[], image_count, video_url, project_units[], structured_data{}, witness_mismatch[]}

**Example request body:**
```json
{
  "id": "8429675"
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=mubawab
- Human docs page: https://reefapi.com/docs/mubawab
- Overview page: https://reefapi.com/mubawab-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
