Monoprix Grocery Price & Promotion Scraper (France)
Pricing
from $1.40 / 1,000 product scrapeds
Monoprix Grocery Price & Promotion Scraper (France)
Scrape Monoprix groceries (courses.monoprix.fr) by category URL or keyword: one row per product with price in EUR, unit price per kg or litre, offer wording parsed into percent and amount, brand, pack size, rayon path, image and URL. For French grocery price and promotion watching.
Pricing
from $1.40 / 1,000 product scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Scrape Monoprix groceries (courses.monoprix.fr, the Monoprix online supermarket) by rayon (category) URL or by search term and get one flat row per product: the shelf price in euros, the unit price per kg, litre or item, brand, pack size, the offer wording ("-34% remise immédiate", "-50% sur le 2ème produit", "50% cagnotté") parsed into a kind, a percentage, a euro amount and the multi-buy item it applies to, the rayon path, labels such as "Produit bio", image and product URL. Run it on a schedule and diff the dataset for a French grocery price and promotion watch, or read a whole rayon for price comparison against Carrefour, Franprix or Intermarché.
No account, no login, no browser. One request returns up to 1,000 products.
Input
| Field | Notes |
|---|---|
categoryUrls | Rayon pages from courses.monoprix.fr, one per line, e.g. https://courses.monoprix.fr/categories/bio/5b5c3312-5e79-47bf-b4ea-89a285e58d5c, or the category id alone. A rayon includes everything under it: Bio lists all 1,462 products of its 14 sub-rayons. The Promotions rayon lists every product on offer (1,326 on 2026-10-27). |
searchTerms | Search terms, one per line (lait, café moulu, Bonne Maman). Cut to 50 characters, as the site does. |
maxItems | Products per category URL and per search term (default 200, up to 10,000). |
sort | relevance (default), price-asc, price-desc, unit-price-asc, unit-price-desc. |
onlyOnPromotion | Return only products carrying an offer. The others are skipped and not charged. |
proxyConfiguration | Apify residential proxy by default (see "How it fetches"). |
Give at least one category URL or search term. A product found by two inputs is
returned once, under the first. www.monoprix.fr is a different, non-grocery
site and is refused.
About the sorts
The sorts are Monoprix's own and the actor checks each one: the first page of every input says which sort was applied, and the actor fails that input (at no charge) rather than return rows in an order that was not asked for. Monoprix answers an unknown sort with HTTP 200 and its default order (measured), which is why the check exists.
Monoprix sorts within groups: a sponsored product (is_sponsored) first,
then the products on offer, then the rest. A price sort is in order inside each
group, not across the whole list.
Output
Prices are numbers in euros; currency is EUR.
| Field | Notes |
|---|---|
source, query | category or search, and the input (URL, id or term) that first found the product. |
category_id, category_name | The rayon you asked for (null for a search). |
product_id, product_uuid, url | Monoprix's id (MPX_75619), the platform uuid, and the product page https://courses.monoprix.fr/products/<name>/<MPX id>. |
name, brand, pack_size, product_type | As listed. pack_size is the printed size (250g, 6 x 1L, 4 par pack) or the weight band for products sold by weight. product_type is REGULAR or CATCHWEIGHT. |
category_path, labels | The product's own rayon path, outermost first, and shelf badges (Produit bio). |
price | The shelf price before any offer. For a CATCHWEIGHT product it is the price of the typical weight. |
unit_price, unit_measure | Price per kg, l or each, as on the shelf label. |
promo_price, promo_unit_price | The promotional price, only when Monoprix sends one. See below: it is null in every sample. |
on_promotion, offer_text, offer_type | Whether the product carries an offer, the first offer's wording, and Monoprix's type: OFFER (a discount) or LOYALTY (credited to the loyalty wallet). |
offer_kind | Read from the wording: immediate_discount ("-34% remise immédiate"), nth_item_discount ("-50% sur le 2ème produit"), loyalty_credit ("50% cagnotté sur le 2ème produit"), free_items ("2 +1 offert"), amount_off ("-1€"), other ("Offre du moment"). |
offer_percent, offer_amount, offer_nth_item | The percentage, the euro amount, and which item of a multi-buy the offer is on (2 for "2ème"), each read from the wording; null when the wording has none. |
promotions | Every offer: promo_id, retailer_promotion_id, description, type, presentation_mode, limit_reached. Empty list when none. |
is_available, is_new, is_sponsored, is_alcohol, age_restriction | Monoprix's flags. is_sponsored marks a paid featured placement. age_restriction is 18 on alcohol, else null. |
weight_min_g, weight_typical_g, weight_max_g | CATCHWEIGHT only: the weight band the price is for, in grams. |
guaranteed_life_quantity, guaranteed_life_unit | Monoprix's guaranteed shelf life on delivery (e.g. 2 DAY). Null for non-food. |
image_url | The 500x500 product photo. |
No promotional price, by design of the source
Monoprix applies its offers in the basket. The listing carries the shelf
price and names the offer in words; it does not send a reduced price. Measured
2026-10-27: 0 of 2,280 distinct products (every one of the 1,326 in Promotions,
plus the first 1,000 in Bio) carried a promotional price. So price is the price before the
offer, the offer is in offer_* and promotions, and promo_price is
null rather than a figure computed from the wording. Compute it yourself
if you want it: for an immediate_discount, price * (1 - offer_percent / 100).
Honest nulls
A field Monoprix did not send is null, never 0 or "". pack_size is
missing on some products (7 of 1,000 sampled in Bio, 88 of 1,326 in
Promotions), guaranteed_life_* on most non-food, and
the weight_*_g fields on everything not sold by weight. Every one of the 2,280
distinct products sampled was is_available: true: the listing does not show products
that cannot be bought.
Pricing
Pay per event: a small fee per run (actor-start), charged only after your
input is validated, and a fee per product row written (product-scraped).
Rows skipped by onlyOnPromotion are not charged.
How it fetches
It calls the JSON API behind Monoprix's own rayon and search pages
(courses.monoprix.fr/api/webproductpagews/v6/product-pages), up to 1,000
products per request for a rayon and 300 for a search. That is about 0.6 KB of
compressed traffic per product, against about 3.5 KB through the rayon page's
HTML, which carries only 49 products per 1.6 MB page.
Measured 2026-10-27:
- Proxy. Monoprix is behind AWS WAF. Apify residential exits passed 10 of
10 fetches of the API, datacenter exits 4 of 10 (the rest HTTP 403). A plain
VM got one answer, then
202challenges. A refusal (202, 403, 429, 5xx) is treated as the address being blocked; the actor rotates to a fresh address and retries. - Paging. Monoprix pages with a cursor that belongs to its session cookie.
The actor carries that cookie itself, so a retry from a fresh address mid-walk
continues the same listing. The walk ends when Monoprix sends no further
cursor: Promotions came back as 1,000 + 326 = 1,326 products, its own count,
with no repeats; the search
laitas 300 + 165. - Errors. An unknown category id is HTTP 404 ("Category ... not found."), a malformed one HTTP 400; both are reported for that input and not retried.
- Not offered. Monoprix's "on offer" filter was not honoured in the form
tried, so
onlyOnPromotionfilters on the actor's side: the pages are still read in full, but you pay only for offer rows.