Carrefour APIcarrefour.ma ↗
Access Carrefour Maroc product catalogue via API. Search products, filter by category or store banner, retrieve MAD prices, promotions, and stock status.
What is the Carrefour API?
The Carrefour Maroc API provides structured access to the carrefour.ma product catalogue across 3 endpoints, returning current MAD prices, promotion flags, stock status, and category metadata. Use list_products to search and filter the catalogue by free text, category slug, store banner, or active promotions, and get_product to retrieve a single product's full detail record including crossed price, primary category, and carrying store banners.
curl -X GET 'https://api.parse.bot/scraper/10f3d89e-1259-4669-a5a4-5de92deed70f/list_products?query=lait' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace carrefour-ma-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Carrefour Maroc SDK — browse categories, search products, fetch details."""
from parse_apis.carrefour_ma_api import CarrefourMaroc, Store, ProductNotFound
client = CarrefourMaroc()
# Browse top-level categories and pick the first one.
category = client.categories.list(limit=5).first()
if category is not None:
print(category.name, category.slug)
# Search for products in that category, limited to Carrefour stores.
for product in client.products.search(
category_slug=category.slug,
store=Store.CARREFOUR,
limit=3,
):
print(product.name, f"{product.price} {product.currency}", product.stock_status)
# Free-text search across all categories.
hit = client.products.search(query="lait", promotions_only=True, limit=1).first()
if hit is not None:
# Drill into the full product detail using the slug from the search result.
detail = client.products.get(slug=hit.slug)
print(detail.name, detail.price, detail.crossed_price, detail.is_promotion)
print("stores:", detail.stores)
# Refresh to get the latest data for the same product.
refreshed = detail.refresh()
print("refreshed price:", refreshed.price)
# Demonstrate typed error handling on a point lookup.
try:
client.products.get(slug="does-not-exist")
except ProductNotFound:
print("product not found, as expected")
print("exercised: categories.list / products.search / products.get / product.refresh")
Lists catalogue products with prices (MAD). One upstream request per call (two when store is set). Filters combine: free-text search, a category slug from list_categories, a store banner, and promotion-only. Paginated: page (1-based) and limit (max 200, default 30) are caller-controlled; the response carries the site's total count, total_pages and has_more. Note that non-promotional catalogue items frequently carry price 0 and crossed_price null on the site, as the site itself shows; promotional items carry the current price plus crossed_price (previous price) and the promotion window. Some category slugs (e.g. epicerie) currently return zero products on the site; an unknown category slug yields an empty result. Results are ordered newest-first as the site returns them.
| Param | Type | Description |
|---|---|---|
| page | integer | 1-based page number. |
| limit | integer | Products per page; values above 200 are clamped to 200. |
| query | string | Free-text search over product names (e.g. lait). Omitted = no text filter. |
| store | string | Restrict to products sold by one Carrefour store banner. Omitted = all banners. |
| category_slug | string | Category slug from list_categories.categories[*].slug. Omitted = all categories. |
| promotions_only | boolean | When true, only products currently flagged as promotions are returned. |
{
"type": "object",
"fields": {
"page": "page returned",
"limit": "page size applied",
"total": "site-reported total matching products",
"has_more": "true when a next page exists",
"products": "array of product records: id, slug (use with get_product), name, description, image_url, price (MAD number), crossed_price (previous price when on promotion, else null), currency, is_promotion, promotion_start_date/promotion_end_date (ISO or null), club_points, stock_status, primary/secondary/tertiary_category, internal_product_id, stores (banner names carrying it), updated_at",
"total_pages": "site-reported page count"
},
"sample": {
"data": {
"page": 2,
"limit": 5,
"total": 83,
"has_more": true,
"products": [
{
"id": "cmrvyuni2009ffiqd5kxpzxk8",
"name": "PACK LAIT UHT ENTIER JIBAL X 6 1L",
"slug": "pack-lait-uht-entier-jibal-x-6-1l",
"price": 54.95,
"stores": [
"Carrefour",
"Carrefour Market"
],
"currency": "MAD",
"image_url": "https://storage.googleapis.com/crftobringo-sharing-ma-prelive/ftp/CRF/images/559965-1-5.jpg",
"updated_at": "2026-07-22T10:55:21.721Z",
"club_points": 0,
"description": null,
"is_promotion": true,
"stock_status": "in_stock",
"crossed_price": 65.95,
"primary_category": "CREMERIE",
"tertiary_category": null,
"promotion_end_date": "2026-08-12T00:00:00.000Z",
"secondary_category": null,
"internal_product_id": "559965",
"promotion_start_date": "2026-07-21T00:00:00.000Z"
}
],
"total_pages": 17
},
"status": "success"
}
}About the Carrefour API
Catalogue Search and Filtering
The list_products endpoint is the primary way to explore the carrefour.ma catalogue. It accepts up to five combinable filters: a free-text query (e.g. lait), a category_slug sourced from list_categories, a store banner name, and a promotions_only boolean flag. Pagination is controlled by page (1-based) and limit (capped at 200, default 30). Each response includes total, total_pages, and has_more fields so callers can walk through large result sets. Each product record carries an id, slug, name, description, image_url, current price in MAD, and a crossed_price field that holds the pre-promotion price when a promotion is active.
Single Product Detail
The get_product endpoint accepts a slug as emitted by list_products and returns the full product record for that item. Response fields include price, crossed_price, is_promotion, stock_status (e.g. in_stock), primary_category, currency (always MAD), and stores — an array of Carrefour store banner names that carry the product. If the slug is not recognised by the site, the endpoint returns a stale_input (not found) envelope rather than a generic error.
Category Taxonomy
The list_categories endpoint takes no parameters and returns the full set of top-level site categories, each with an id, slug, name, description, image_url, and display order. The slug values from this response are what list_products accepts as its category_slug filter, making list_categories the right first call when building any category-aware browse flow.
The Carrefour API is a managed, monitored endpoint for carrefour.ma — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when carrefour.ma changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official carrefour.ma API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Track MAD price changes on specific products over time using get_product and monitoring the price and crossed_price fields.
- Build a promotion alert feed by polling list_products with promotions_only=true to surface currently discounted items.
- Compare product availability across Carrefour store banners using the stores array returned by get_product.
- Construct a category-browsing interface by fetching slugs from list_categories and passing them as category_slug to list_products.
- Aggregate grocery product data for Moroccan market research using the name, description, and price fields from list_products.
- Monitor stock status changes for specific SKUs by periodically calling get_product and observing the stock_status field.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.