MarocAnnonces API & Scraper
MarocAnnonces.com is one of Morocco's oldest classifieds sites and its biggest board for job offers and CVs, next to used cars, apartments, phones and services.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
This API reads it as JSON. `search` takes free text plus the site's own filters: category, city, price range in dirhams and photos only; for used cars also make, year, mileage and fuel; for apartments bedrooms, bathrooms and surface. `listing` returns one ad in full: the complete description, every photo, city and district, the publication date, the view count, every structured attribute (make, model, year, mileage, fuel, bedrooms, surface, job sector, contract type, education level), the advertiser's name and phone number, the recruiter or shop page when there is one, and for job offers the date the posting stays valid until. `categories` and `cities` list the 60 categories and 81 cities with the ids search accepts.
What a MarocAnnonces field actually contains
Fields that read differently from how they look. Every row was measured against live MarocAnnonces pages on 2026-10-07.
| Field | What it holds |
|---|---|
| price_mad vs price_text | price_text is the price exactly as the ad prints it ('98 000 DH'); price_mad is the same number as an integer. Job offers and CVs carry no price, so both are null there. On 13 search-to-listing pairs per run, over two runs, the search price and the ad page's price agreed 13/13 both times. |
| Seller-typed prices | MarocAnnonces does not check prices. We measured an apartment for sale in Rabat at 5,500 DH (a rent typed in the sale category) and a service ad at 1 DH. We publish what the advertiser typed and never rescale it. |
| seller.phone | The number behind the ad's 'Afficher le numéro' button, in the site's own format (0XX-XXX-XXXX), with phone_masked as the page shows it before the click. Older ads that the site still keeps online often show no phone at all: then it is null. |
| seller.name | The advertiser name as typed. Many private sellers type a placeholder such as 'xxxxx' and we return it unchanged. Recruiters and shops add seller.shop with the shop's name, page and logo. |
| published_at | Moroccan local time. Search cards and ad pages print the day and month but often not the year ('7 Oct-10:03', '02 Sep 14:52'): the year is the current one unless that date would lie in the future. published_text keeps the original wording. |
| is_premium | Paid placements the site shows above the results. They carry no date and appear on every page of the same search, so drop or de-duplicate them if you page through. The jobs search for Casablanca opened with 4. |
| has_more (no total) | MarocAnnonces prints no result count on search pages, so search returns no total. has_more follows the site's own 'next page' link. Past the real end the site returns an empty page; past page 100 it would repeat page 100, so page 101 and later are refused and page_ceiling_reached is set on page 100. |
| job | Only on job offers: the posting's date, valid_through, contract type, sector, hiring organisation and salary text, read from the job-posting data the page publishes. Its salary and sector matched the ad's own attribute list on every sampled offer. |
Search reaches the ads published in roughly the last five weeks: the used-car search ended at 365 ads with the oldest dated 2 September, while the category page counts 2,591 used cars including its older archive. Read an archive ad directly with listing if you have its number.
Real request and response JSON
Captured from the indexed primary action, search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/marocannonces/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"query": "dacia",
"category": "314"
}
}{
"ok": true,
"meta": {
"api": "marocannonces",
"endpoint": "search",
"mode": "live",
"latency_ms": 287.3,
"record_count": 20,
"bytes": 78278,
"cache_hit": false,
"upstream_requests": 1,
"charged_credits": 2,
"version": "1.0.0",
"request_id": "f5840dafc0d14c5f",
"queue_ms": 1.5,
"fetched_at": "2026-10-07T15:52:08.951Z"
},
"data": {
"page": 1,
"has_more": true,
"page_ceiling_reached": false,
"filters_applied": {
"query": "dacia",
"category_id": "314",
"category_name": "Voitures occasion"
},
"listings": [
{
"id": "10464958",
"url": "https://www.marocannonces.com/categorie/314/Voitures-occasion/annonce/10464958/Dacia-logan.html",
"title": "Dacia logan",
"price_mad": 98000,
"price_text": "98 000 DH",
"currency": "MAD",
"city": "Tanger",
"district": null,
"category_id": "314",
"category_name": "Voitures occasion",
"parent_category_id": "15",
"parent_category_name": "Auto - Moto",
"image": "https://www.marocannonces.com/user_images/314/7712361.jpg",
"published_text": "Aujourd'hui 10:03",
"published_at": "2026-10-07T10:03",
"is_premium": false
},
{
"id": "10464998",
"url": "https://www.marocannonces.com/categorie/314/Voitures-occasion/annonce/10464998/Dacia-logan-a-vendre.html",
"title": "Dacia logan a vendre",
"price_mad": 75000,
"price_text": "75 000 DH",
"currency": "MAD",
"city": "Casablanca",
"district": null,
"category_id": "314",
"category_name": "Voitures occasion",
"parent_category_id": "15",
"parent_category_name": "Auto - Moto",
"image": "https://www.marocannonces.com/user_images/314/5616637.jpg",
"published_text": "02 Oct 2026 17:02",
"published_at": "2026-10-02T17:02",
"is_premium": false
},
{
"id": "10463945",
"url": "https://www.marocannonces.com/categorie/314/Voitures-occasion/annonce/10463945/Dacia-Logan.html",
"title": "Dacia Logan",
"price_mad": 130000,
"price_text": "130 000 DH",
"currency": "MAD",
"city": "Mohammedia",
"district": null,
"category_id": "314",
"category_name": "Voitures occasion",
"parent_category_id": "15",
"parent_category_name": "Auto - Moto",
"image": "https://www.marocannonces.com/user_images/314/6533416.jpg",
"published_text": "01 Oct 2026 11:14",
"published_at": "2026-10-01T11:14",
"is_premium": false
}
]
}
}What the MarocAnnonces API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| search | Search MarocAnnonces.com, Morocco's general classifieds site: job offers and CVs, used cars, apartments and villas for sale or rent, phones, computers, household goods and services. Free text plus the site's own filters: category, city, price range, photos only; for used cars make, year, mileage and fuel; for apartments bedrooms, bathrooms and surface. Nothing is required: no parameters browses the whole site newest first. | Price-intelligence teams call search to search MarocAnnonces.com, Morocco's general classifieds site. | query, category, city, min_price, max_price, ... |
| listing | One MarocAnnonces ad in full: title, full description, price, every photo, city and district, publication date, view count, all structured attributes (make, model, year, mileage, fuel, bedrooms, surface, job sector, contract, education level …), the advertiser's name and phone number, the recruiter or shop page when there is one, and for job offers the posting's validity date. | Classifieds aggregators call listing to get one MarocAnnonces ad in full. | id, url, include_pii |
| categories | MarocAnnonces' category tree: 7 top-level categories and 53 subcategories with the ids `search` accepts. | Resale and arbitrage tools call categories to get marocAnnonces' category tree. | category |
| cities | The 81 Moroccan cities MarocAnnonces filters on, with their ids. | Lead-generation teams call cities to get the 81 Moroccan cities MarocAnnonces filters on, with their ids.. | none |
Call search from your stack
curl -X POST https://api.reefapi.com/marocannonces/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"dacia","category":"314"}'import requests
r = requests.post(
"https://api.reefapi.com/marocannonces/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "dacia",
"category": "314"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/marocannonces/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"query": "dacia",
"category": "314"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.marocannonces.search with {"query":"dacia","category":"314"}.Who uses this API and why
- Collect Moroccan job offers by city and sector with contract type, education level and the recruiter behind each offer.
- Track used-car prices in Morocco by make, year, mileage and fuel, in dirhams, with the seller's phone for each ad.
- Build a rent and sale price index for Casablanca, Rabat or Marrakech by bedrooms and surface, with the district of each apartment.
- Watch resale prices of phones and laptops across Moroccan cities from the Multimédia categories.
- Feed a lead list of recruiters, agencies and shops from the shop pages their ads link to.
Questions developers ask before integrating
Do I need a MarocAnnonces account or a Moroccan IP?
No. Every endpoint is read without an account or a login, and you call reefapi.com from anywhere.
Which categories can I search?
All of them: Emploi (job offers, CVs, internships, freelance, training), Auto-Moto (used cars, 4x4, motorbikes, trucks, boats, parts, car-sharing), property for sale and for rent (apartments, villas and riads, studios, shops, offices, land, farms), Multi Services, Ventes diverses (furniture, appliances, animals, clothing and more) and Multimédia (phones, computers, consoles, cameras). The categories endpoint lists the 60 ids.
How do I find used cars of one make, year and mileage?
Use category=314 with make, year_min/year_max, mileage_min/mileage_max and fuel. Measured on 2026-10-07 against 365 used cars in search: Diesel 249, Essence 68, Dacia 33, 2018 or newer 139, at most 100,000 km 142, 100,000-200,000 DH 138, with photos 336.
Can I separate apartments for rent from apartments for sale?
Yes, they are separate categories: 315 is apartments for sale and 321 apartments for rent. Both take bedrooms, bathrooms, surface_min and surface_max. Out of 699 apartments for rent, 2 bedrooms left 338, at least 100 m² 161, and Casablanca 249.
Do you return the advertiser's phone number and name?
Yes, exactly as the ad publishes them: the advertiser name, the phone number behind the ad's 'show number' button, and for recruiters and shops their shop page. Nothing is masked.
Why is there no total count in search results?
Because MarocAnnonces does not print one on its search pages. We return has_more instead, which follows the site's own next-page link, and an empty page once you go past the last one.
How far back does search go?
About five weeks of ads, and at most 100 pages of 20 rows per query: MarocAnnonces serves page 100 again for any later page, so we stop there and say so in page_ceiling_reached. The used-car search ended at 365 ads over 19 pages, the oldest dated 2 September 2026; job offers fill all 100 pages, so narrow them by city or keyword. Older ads the site still keeps online can be read one by one with listing.
Is the description the full ad text?
Yes. listing returns the whole description with its line breaks, every photo in full size, and every attribute the ad page lists, not the shortened search card.
What is the MarocAnnonces API?
MarocAnnonces API is a ReefAPI endpoint group for morocco's classifieds as json: job offers and cvs, used cars, flats for sale and rent, phones and services, with the advertiser's phone. It returns live JSON through POST requests under /marocannonces/v1.
Is the MarocAnnonces API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. MarocAnnonces calls use the same shared credit balance as every other ReefAPI engine.
Do I need a MarocAnnonces login or account?
No login to MarocAnnonces is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the MarocAnnonces data?
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the MarocAnnonces API use?
MarocAnnonces actions currently cost 1-2 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call MarocAnnonces from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call marocannonces actions with the same key, credit pool and JSON envelope used by normal REST requests.