Returns the Mercadona products that are currently cheaper than their previous price at the warehouse that serves a postal code. Each row is a full product row plus discount_value (EUR) and discount_percent. Price drops are calculated from the product’s previous price (previous_price_value), not from Mercadona’s own flag. Use it to build deal alerts, track promotions per city or feed a price history.
HTTP Request
GET /price-drops
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
warehouse | string | No | vlc1 | Hub or 4-digit store code (see Warehouses
). Ignored when postal_code is given. Numeric store codes are served live: brand, ean, category_path and popularity_score may be null on their rows, and a brand or level-1/2 category_id filter returns 400 for them |
postal_code | string | No | - | Spanish 5-digit postal code, resolved to the warehouse that serves it. Takes precedence over warehouse |
page | integer | No | 1 | 1-indexed page |
per_page | integer | No | 20 | Items per page, max 20 |
category_id | integer | No | - | Category id at any level (see Category Tree ) |
brand | string | No | - | Exact brand name as Mercadona writes it (see Brands
). Several brands comma-separated are OR-ed (Danone,Puleva) |
min_price | number | No | - | Lowest price_value in euros, inclusive, 0 to 10000 (e.g. 2 or 1.5). total counts only products in the range; products without a price are left out when a bound is set |
max_price | number | No | - | Highest price_value in euros, inclusive, 0 to 10000. Must be greater than or equal to min_price |
sort | string | No | discount_percent | discount_percent (biggest cut in % first), discount_value (biggest saving in euros first), popularity, price_asc, price_desc. Ties are broken by product_id. When the answer has source: live, popularity keeps Mercadona’s own price-drop order |
fresh | boolean | No | false | Bypass the 15-minute cache. Only affects answers with source: live; catalog_index answers come from the daily catalog snapshot (snapshot_date) and refresh once a day |
language | string | No | es | Language for product and category names: es, en or ca |
Response
| |
Response Fields
| Field | Type | Description |
|---|---|---|
status | boolean | true on success |
request_id | string | Unique request identifier |
cached_at | string | null | ISO timestamp when the answer came from cache, null when fetched for this request |
data | object | Response payload |
data.items[] | array of objects | Products currently on a price drop |
data.items[].product_id | string | Mercadona product id. Pass it verbatim: decimal ids like 81241.3 exist |
data.items[].name | string | Product name, translated with language |
data.items[].slug | string | URL slug of the product |
data.items[].url | string | Product URL on tienda.mercadona.es |
data.items[].thumbnail | string | Product image URL (imgix) |
data.items[].packaging | string | null | Packaging, e.g. "Tableta", "Botella", "Pieza" |
data.items[].main_feature | string | null | Highlighted feature shown under the name |
data.items[].is_water | boolean | Water product flag |
data.items[].requires_age_check | boolean | Alcohol or other age-restricted product |
data.items[].category | object | Level-0 category of the product |
data.items[].category.category_id | integer | Level-0 category id |
data.items[].category.name | string | Level-0 category name, translated with language |
data.items[].availability | object | Availability at the resolved warehouse |
data.items[].availability.in_stock | boolean | In stock at the resolved warehouse |
data.items[].availability.status | string | null | Restriction status, null when there is none |
data.items[].availability.unavailable_from | string | null | Date the product stops being available |
data.items[].availability.unavailable_weekdays | array | Weekdays the product can’t be delivered |
data.items[].availability.order_limit | integer | Maximum units per order (e.g. 999) |
data.items[].price | string | Display price in EUR, e.g. "1.25" |
data.items[].price_value | float | Numeric price in EUR |
data.items[].previous_price | string | null | Previous display price, null when there is none |
data.items[].previous_price_value | float | null | Previous numeric price in EUR |
data.items[].is_price_drop | boolean | true when the current price is below previous_price. Computed from the previous price, not Mercadona’s own flag |
data.items[].unit_price | string | Display unit price, e.g. "0.800" |
data.items[].unit_price_value | float | Numeric unit price |
data.items[].unit_price_format | string | Unit the unit price refers to, e.g. "L", "kg", "ud" |
data.items[].bulk_price_value | float | Bulk price |
data.items[].size_format | string | Size unit, e.g. "l", "kg" |
data.items[].unit_size | float | Size in size_format units |
data.items[].is_pack | boolean | Whether the product is a pack |
data.items[].pack_size | float | null | Size of each unit in the pack |
data.items[].total_units | integer | null | Units in the pack |
data.items[].unit_name | string | null | Unit name, e.g. "ud.", "briks" |
data.items[].iva_percent | integer | VAT percentage |
data.items[].approx_size | boolean | Size is approximate (e.g. fruit sold by the piece) |
data.items[].drained_weight | float | null | Drained weight |
data.items[].currency | string | Always "EUR" |
data.items[].color_variants | array | null | Colour variants |
data.items[].warehouse | string | Warehouse that answered |
data.items[].ean | string | null | EAN barcode. Can be null (always possible on numeric store codes) |
data.items[].brand | string | null | Brand name as Mercadona writes it. Can be null, e.g. for unbranded fresh produce |
data.items[].category_path | array of arrays | Category paths. Each path is a list of {category_id, name, level} objects from level 0 down. Can be empty |
data.items[].category_path[][].category_id | integer | Category id |
data.items[].category_path[][].name | string | Category name, translated with language |
data.items[].category_path[][].level | integer | Category level: 0, 1 or 2 |
data.items[].popularity_score | float | null | Mercadona’s internal popularity score. null on numeric store codes |
data.items[].discount_value | float | Saving in EUR: previous_price_value minus price_value |
data.items[].discount_percent | float | Saving as a percentage of previous_price_value |
data.total | integer | Products on a price drop (within the price range, if set) |
data.page | integer | Current page (1-indexed) |
data.per_page | integer | Items per page |
data.total_pages | integer | Total number of pages |
data.has_next_page | boolean | Whether another page follows |
data.sort | string | Sort order applied |
data.source | string | Data origin: catalog_index (daily catalog snapshot) or live |
data.snapshot_date | string | Date of the catalog snapshot used |
data.resolved_filters.warehouse | object | The warehouse that answered |
data.resolved_filters.warehouse.input | string | null | The postal_code or warehouse you sent, null if none |
data.resolved_filters.warehouse.resolved | string | Warehouse code used, e.g. mad3 |
data.resolved_filters.warehouse.source | string | How it was chosen: postal_code, param or default |
data.language | string | Language used for names: es, en or ca |
request_params | object | The query parameters you sent, echoed back as strings |
Error Responses
Invalid input returns HTTP 400, and error is a plain string:
| |
| Status Code | Cause | Description |
|---|---|---|
| 400 | Invalid parameter | Malformed warehouse, per_page above 20, min_price or max_price outside 0 to 10000, or max_price lower than min_price |
| 400 | Filter on a store code | Per the RapidAPI docs, a brand or level-1/2 category_id filter returns 400 when the warehouse is a numeric store code. Use a hub or a postal code that resolves to one |
An unknown brand is not an error: you get an empty items list.
Code Examples
| |
| |
| |
Related Endpoints
- Product Details : full sheet (ingredients, allergens, photos) for a discounted product
- Brands
: exact brand names to use in the
brandfilter - Resolve Warehouse : check which warehouse a postal code maps to
- Campaign Products : the price-drop carousel as Mercadona shows it on its home page