Returns the products Mercadona currently presents as new at the warehouse that serves a postal code. By default it reads the general Novedades grid. With feed=all it also includes every home-page section titled “Nuevo en …” (for example “Nuevo en Perfumería”). Rows are standard product rows, so you can filter by category, brand and price like the other discovery endpoints.
HTTP Request
GET /new-products
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 (local pagination over the feed) |
per_page | integer | No | 20 | Items per page, max 20 |
feed | string | No | novedades | novedades: the general Novedades grid. all: also every home section titled “Nuevo en …” |
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 |
fresh | boolean | No | false | Bypass the 10-minute cache of the new-products feed. brand, ean, category_path and popularity_score 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 | New products |
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.total | integer | New products in the feed (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.feed | string | Feed used: novedades or all |
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, unknown feed value, per_page above 20, or an invalid price range |
| 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 |
Very recent products may not be in the daily catalog snapshot yet, so their ean, brand and popularity_score can be null and category_path empty (see the second item above).
Code Examples
| |
| |
| |
Related Endpoints
- Product Details : ingredients, allergens and photos for a new product
- Home Campaigns
: list the “Nuevo en …” sections that
feed=allmerges - Campaign Products : products of a single “Nuevo en …” section
- Brands
: exact brand names to use in the
brandfilter