GET /search

Product Search

Search Mercadona products by keyword for any Spanish postal code, with prices, unit prices, EAN barcodes and brand and category facets.

Mercadona API

Free-text, typo-tolerant product search over Mercadona’s online catalog. Each result is a full product row with price, unit price, previous price, EAN barcode, brand and category path, priced for the warehouse that serves the postal code you pass. The response also includes brands and categories facets so you can narrow a broad query. Search returns at most the 100 best matches per query, which is Mercadona’s own limit. For exhaustive listings use Category Products or Brand Products .

HTTP Request

GET /search

Parameters

ParameterTypeRequiredDefaultDescription
qstringYes-Free-text query, typo-tolerant (e.g. leche). Returns at most the 100 best matches. An empty query, *, an EAN or a product id return 0 results
postal_codestringNo-Spanish 5-digit postal code. Resolved to the warehouse that serves that address and takes precedence over warehouse
warehousestringNovlc1Hub (vlc1, mad1, mad2, mad3, bcn1, svq1, alc1) or 4-digit store code from /warehouses . Ignored when postal_code is given. Invalid codes return 400
category_idintegerNo-Filter by a category id at any level (see /categories ). Each filtered query gets its own 100-result window
brandstringNo-Exact brand name as Mercadona writes it (see /brands ). Several brands comma-separated are OR-ed
pageintegerNo11-indexed page. Pages past total_pages are empty
per_pageintegerNo20Results per page, max 20
languagestringNoeses, en or ca. Translates names and category names, and the query is matched against names in this language
freshbooleanNofalseBypass the 10-minute cache and fetch live data

Language affects matching. The query is matched against product names in the chosen language: q=leche finds hundreds of products with language=es, but with language=en search milk, and with language=ca search llet.

Numeric store codes are served live: popularity_score is null on their rows, and brand, ean or category_path may be null.

Response

Request: GET /search?q=leche&postal_code=28001&per_page=2. The categories facet is trimmed to 2 items per level.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
{
  "status": true,
  "request_id": "4a44b45a-d9bd-9470-b17d-49ceef2a",
  "cached_at": null,
  "data": {
    "results": [
      {
        "product_id": "10381",
        "name": "Leche semidesnatada Hacendado",
        "slug": "leche-semidesnatada-hacendado-pack-6",
        "url": "https://tienda.mercadona.es/product/10381/leche-semidesnatada-hacendado-pack-6",
        "thumbnail": "https://prod-mercadona.imgix.net/images/b91d8b8bafd5eabab8961aabbe16c28b.jpg?fit=crop&h=300&w=300",
        "packaging": null,
        "main_feature": null,
        "is_water": false,
        "requires_age_check": false,
        "category": {
          "category_id": 6,
          "name": "Huevos, leche y mantequilla"
        },
        "availability": {
          "in_stock": true,
          "status": null,
          "unavailable_from": null,
          "unavailable_weekdays": [],
          "order_limit": 999
        },
        "price": "4.98",
        "price_value": 4.98,
        "previous_price": "5.04",
        "previous_price_value": 5.04,
        "is_price_drop": true,
        "unit_price": "0.830",
        "unit_price_value": 0.83,
        "unit_price_format": "L",
        "bulk_price_value": 0.83,
        "size_format": "l",
        "unit_size": 6.0,
        "is_pack": true,
        "pack_size": 1.0,
        "total_units": 6,
        "unit_name": "briks",
        "iva_percent": 4,
        "approx_size": false,
        "drained_weight": null,
        "currency": "EUR",
        "color_variants": null,
        "warehouse": "mad3",
        "ean": "8402001002090",
        "brand": "Hacendado",
        "category_path": [
          [
            {
              "category_id": 6,
              "name": "Huevos, leche y mantequilla",
              "level": 0
            },
            {
              "category_id": 72,
              "name": "Leche y bebidas vegetales",
              "level": 1
            }
          ]
        ],
        "popularity_score": 34027.0
      },
      {
        "product_id": "10379",
        "name": "Leche entera Hacendado",
        "slug": "leche-entera-hacendado-pack-6",
        "url": "https://tienda.mercadona.es/product/10379/leche-entera-hacendado-pack-6",
        "thumbnail": "https://prod-mercadona.imgix.net/images/b4db71bda48058bb37cd556c55b2fc64.jpg?fit=crop&h=300&w=300",
        "packaging": "Pack-6",
        "main_feature": null,
        "is_water": false,
        "requires_age_check": false,
        "category": {
          "category_id": 6,
          "name": "Huevos, leche y mantequilla"
        },
        "availability": {
          "in_stock": true,
          "status": null,
          "unavailable_from": null,
          "unavailable_weekdays": [],
          "order_limit": 999
        },
        "price": "5.76",
        "price_value": 5.76,
        "previous_price": null,
        "previous_price_value": null,
        "is_price_drop": false,
        "unit_price": "0.960",
        "unit_price_value": 0.96,
        "unit_price_format": "L",
        "bulk_price_value": 0.96,
        "size_format": "l",
        "unit_size": 6.0,
        "is_pack": true,
        "pack_size": 1.0,
        "total_units": 6,
        "unit_name": "briks",
        "iva_percent": 4,
        "approx_size": false,
        "drained_weight": null,
        "currency": "EUR",
        "color_variants": null,
        "warehouse": "mad3",
        "ean": "8402001002076",
        "brand": "Hacendado",
        "category_path": [
          [
            {
              "category_id": 6,
              "name": "Huevos, leche y mantequilla",
              "level": 0
            },
            {
              "category_id": 72,
              "name": "Leche y bebidas vegetales",
              "level": 1
            }
          ]
        ],
        "popularity_score": 31277.0
      }
    ],
    "total": 309,
    "page": 1,
    "per_page": 2,
    "total_pages": 50,
    "has_next_page": true,
    "brands": {
      "Hacendado": 191,
      "": 16,
      "Asturiana": 12,
      "+Proteínas": 10,
      "Puleva": 9,
      "L-casei": 5,
      "Peques 3": 5,
      "Alitey": 3,
      "Don Simón": 3,
      "Nestlé": 2
    },
    "categories": [
      {
        "category_id": 6,
        "name": "Huevos, leche y mantequilla",
        "level": 0,
        "count": 147,
        "categories": [
          {
            "category_id": 72,
            "name": "Leche y bebidas vegetales",
            "level": 1,
            "count": 113,
            "categories": [
              {
                "category_id": 347,
                "name": "Bebidas vegetales",
                "level": 2,
                "count": 29,
                "categories": []
              },
              {
                "category_id": 344,
                "name": "Leche desnatada",
                "level": 2,
                "count": 22,
                "categories": []
              }
            ]
          },
          {
            "category_id": 75,
            "name": "Mantequilla y margarina",
            "level": 1,
            "count": 25,
            "categories": [
              {
                "category_id": 353,
                "name": "Nata",
                "level": 2,
                "count": 11,
                "categories": []
              },
              {
                "category_id": 351,
                "name": "Mantequilla",
                "level": 2,
                "count": 7,
                "categories": []
              }
            ]
          }
        ]
      },
      {
        "category_id": 11,
        "name": "Postres y yogures",
        "level": 0,
        "count": 50,
        "categories": [
          {
            "category_id": 108,
            "name": "Yogures líquidos",
            "level": 1,
            "count": 24,
            "categories": [
              {
                "category_id": 413,
                "name": "Yogures líquidos",
                "level": 2,
                "count": 13,
                "categories": []
              },
              {
                "category_id": 414,
                "name": "L-Casei",
                "level": 2,
                "count": 7,
                "categories": []
              }
            ]
          },
          {
            "category_id": 104,
            "name": "Yogures naturales y sabores",
            "level": 1,
            "count": 6,
            "categories": [
              {
                "category_id": 867,
                "name": "Yogures naturales",
                "level": 2,
                "count": 5,
                "categories": []
              },
              {
                "category_id": 408,
                "name": "Yogures de sabores",
                "level": 2,
                "count": 1,
                "categories": []
              }
            ]
          }
        ]
      }
    ],
    "resolved_filters": {
      "warehouse": {
        "input": "28001",
        "resolved": "mad3",
        "source": "postal_code"
      }
    },
    "language": "es"
  },
  "request_params": {
    "per_page": "2",
    "q": "leche",
    "postal_code": "28001"
  }
}

Response Fields

FieldTypeDescription
statusbooleantrue when the request succeeded
request_idstringUnique request identifier
cached_atstring | nullISO timestamp when the answer came from cache, null when fetched for this request
dataobjectResponse payload
data.results[]arrayMatching products, best match first
data.results[].product_idstringMercadona product id. Pass it verbatim: decimal ids like 81241.3 exist
data.results[].namestringProduct name, translated with language
data.results[].slugstringURL slug of the product page
data.results[].urlstringProduct URL on tienda.mercadona.es
data.results[].thumbnailstringProduct image URL (300x300)
data.results[].packagingstring | nullPackaging label, e.g. "Pack-6" or "Brik"
data.results[].main_featurestring | nullHighlighted feature, when Mercadona sets one
data.results[].is_waterbooleanWater product flag
data.results[].requires_age_checkbooleanAlcohol or other age-restricted product
data.results[].categoryobjectLevel-0 category of the product
data.results[].category.category_idintegerLevel-0 category id
data.results[].category.namestringLevel-0 category name, translated with language
data.results[].availabilityobjectAvailability at the resolved warehouse
data.results[].availability.in_stockbooleanIn stock at the resolved warehouse
data.results[].availability.statusstring | nullRestriction status, null when unrestricted
data.results[].availability.unavailable_fromstring | nullDate the product stops being available
data.results[].availability.unavailable_weekdaysarrayWeekdays the product can’t be delivered
data.results[].availability.order_limitintegerMaximum units per order, e.g. 999
data.results[].pricestringDisplay price in euros, e.g. "4.98"
data.results[].price_valuefloatNumeric price in euros
data.results[].previous_pricestring | nullPrevious display price, null when there is none
data.results[].previous_price_valuefloat | nullPrevious numeric price
data.results[].is_price_dropbooleantrue when the current price is below the previous price (computed by the API, not a Mercadona flag)
data.results[].unit_pricestringDisplay unit price, e.g. "0.830"
data.results[].unit_price_valuefloatNumeric unit price
data.results[].unit_price_formatstringUnit the unit price refers to, e.g. "L" or "kg"
data.results[].bulk_price_valuefloatBulk price
data.results[].size_formatstringSize unit, e.g. "l"
data.results[].unit_sizefloatSize expressed in size_format units
data.results[].is_packbooleanProduct is sold as a pack
data.results[].pack_sizefloat | nullSize of each unit in the pack
data.results[].total_unitsinteger | nullNumber of units in the pack
data.results[].unit_namestring | nullName of each unit, e.g. "briks"
data.results[].iva_percentintegerVAT percentage
data.results[].approx_sizebooleanSize is approximate
data.results[].drained_weightfloat | nullDrained weight, for canned or preserved products
data.results[].currencystringAlways "EUR"
data.results[].color_variantsarray | nullColour variants, null when the product has none
data.results[].warehousestringWarehouse that answered for this row
data.results[].eanstringEAN-13 barcode
data.results[].brandstringBrand name as Mercadona writes it
data.results[].category_patharrayCategory paths of the product. Each path is an array of objects from level 0 down
data.results[].category_path[][].category_idintegerCategory id
data.results[].category_path[][].namestringCategory name, translated with language
data.results[].category_path[][].levelintegerCategory level: 0, 1 or 2
data.results[].popularity_scorefloat | nullMercadona’s internal popularity score. null on numeric store codes
data.totalintegerTotal matches. Exact up to 100, an estimate beyond that
data.pageintegerCurrent page
data.per_pageintegerResults per page
data.total_pagesintegerNumber of pages, capped by the 100-result limit
data.has_next_pagebooleanWhether another page is available
data.brandsobjectBrand facet: {brand name: count} over the matches. Can include an empty-string key "" for products with no brand
data.categories[]arrayCategory facet tree over the matches
data.categories[].category_idintegerCategory id
data.categories[].namestringCategory name
data.categories[].levelintegerCategory level: 0, 1 or 2
data.categories[].countintegerMatches in this category
data.categories[].categories[]arrayChild categories with the same shape, nested down to level 2
data.resolved_filtersobjectWhat your filters resolved to
data.resolved_filters.warehouseobjectWarehouse resolution
data.resolved_filters.warehouse.inputstring | nullThe postal_code or warehouse you sent
data.resolved_filters.warehouse.resolvedstringWarehouse that answered, e.g. mad3
data.resolved_filters.warehouse.sourcestringpostal_code, param or default
data.languagestringLanguage used
request_paramsobjectQuery parameters you sent, echoed back as strings

Error Responses

Invalid input returns HTTP 400 with error as a plain string. Missing q:

1
2
3
4
5
{
  "status": false,
  "request_id": "c52553ca-846a-5c27-e2e4-70de3665",
  "error": "Invalid parameter 'q': Field required"
}

Invalid warehouse value:

1
2
3
4
5
6
7
8
9
{
  "status": false,
  "request_id": "b757e855-4127-3b96-509a-8b573904",
  "error": "Invalid parameter 'warehouse': String should match pattern '^(?:[a-z]{3}[0-9]|[0-9]{4})$'",
  "request_params": {
    "q": "leche",
    "warehouse": "xyz"
  }
}
Status CodeCauseDescription
400Missing qq is required. error is "Invalid parameter 'q': Field required"
400Invalid warehouseMust be a hub code (3 letters + 1 digit) or a 4-digit store code
200 with 0 resultsQuery matched nothingAn empty query, *, an EAN or a product id return no results. Look up barcodes and ids with /product-details

A search that matches nothing is not an error: you get status: true with an empty data.results.

Code Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import requests

url = "https://mercadona-api.p.rapidapi.com/search"

params = {
    "q": "leche",
    "postal_code": "28001",
    "per_page": 20
}

headers = {
    "X-RapidAPI-Key": "YOUR_API_KEY",
    "X-RapidAPI-Host": "mercadona-api.p.rapidapi.com"
}

response = requests.get(url, headers=headers, params=params)
data = response.json()["data"]

print(f"Warehouse: {data['resolved_filters']['warehouse']['resolved']}, matches: {data['total']}")
for product in data["results"]:
    print(f"{product['name']} ({product['brand']}): {product['price']} EUR, EAN {product['ean']}")
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const url = "https://mercadona-api.p.rapidapi.com/search";

const params = new URLSearchParams({
  q: "leche",
  postal_code: "28001",
  per_page: "20"
});

const response = await fetch(`${url}?${params}`, {
  headers: {
    "X-RapidAPI-Key": "YOUR_API_KEY",
    "X-RapidAPI-Host": "mercadona-api.p.rapidapi.com"
  }
});

const { data } = await response.json();
console.log(`Matches: ${data.total}`);
for (const product of data.results) {
  console.log(`${product.name}: ${product.price} EUR (${product.unit_price}/${product.unit_price_format})`);
}
1
2
3
4
5
6
curl -G "https://mercadona-api.p.rapidapi.com/search" \
  --data-urlencode "q=leche" \
  --data-urlencode "postal_code=28001" \
  --data-urlencode "per_page=20" \
  -H "X-RapidAPI-Key: YOUR_API_KEY" \
  -H "X-RapidAPI-Host: mercadona-api.p.rapidapi.com"
Start building today

Get your API key and make your first request in under a minute.

Get Your API Key on RapidAPI