# El Corte Inglés API — search Spain's biggest department store (elcorteingles.es) and pull one product in full: every image, the complete colour x size matrix with a stable variant id, EAN-13, price and stock on every row, the specification table, brand, availability, star rating and top customer reviews — no account, no cookies, no browser

> Search or browse elcorteingles.es. Give a Spanish free-text `query` ('zapatillas running', 'movil samsung', 'lavadora'), an El Corte Inglés product code or a bare EAN-13, or a `category` path to browse ('electronica/moviles-y-smartphones', 'moda-mujer/zapatos'). Every row carries El Corte Inglés' own product code, the product URL to feed straight into `product_detail`, the name, brand, EAN-13, price range across colours, the colour list, the variant count, how many of those variants are actually buyable, the image, the category hierarchy and whether the listing is a marketplace seller's. Sort by price, discount, rating, newness, name or stock; page through the whole result set. `category` browsing is the route El Corte Inglés' robots.txt allows and `meta.robots` reports which route answered.
> ReefAPI engine `elcorteingles` · 2 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/elcorteingles/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /elcorteingles/v1/search — 1 credit
Search or browse elcorteingles.es. Give a Spanish free-text `query` ('zapatillas running', 'movil samsung', 'lavadora'), an El Corte Inglés product code or a bare EAN-13, or a `category` path to browse ('electronica/moviles-y-smartphones', 'moda-mujer/zapatos'). Every row carries El Corte Inglés' own product code, the product URL to feed straight into `product_detail`, the name, brand, EAN-13, price range across colours, the colour list, the variant count, how many of those variants are actually buyable, the image, the category hierarchy and whether the listing is a marketplace seller's. Sort by price, discount, rating, newness, name or stock; page through the whole result set. `category` browsing is the route El Corte Inglés' robots.txt allows and `meta.robots` reports which route answered.

**Parameters:**
- `query` (string, optional) — What to look for, in Spanish, across the whole elcorteingles.es catalogue ('zapatillas running', 'movil samsung', 'lavadora bosch', 'perfume mujer'). You may also pass an El Corte Inglés product code ('A56390869') or a bare EAN-13 ('8806097643135') — the site resolves both to the single matching product. Give `query` OR `category` (or both — `category` then scopes nothing, the keyword route wins and `meta.search_mode` says so). NOTE: keyword search uses elcorteingles.es' /search-nwx/ path, which their robots.txt disallows for crawlers; `category` browsing is the robots-clean route to the same rows and `meta.robots` reports which one answered your call.
- `category` (string, optional) — Browse one El Corte Inglés category instead of keyword searching — the path between elcorteingles.es/ and the trailing slash. A department on its own works (`electronica`, `deportes`, `libros`, `juguetes`, `hogar`, `moda-mujer`, `perfumeria`, `bebes`) and so does a real sub-category (`electronica/moviles-y-smartphones`, `electrodomesticos/lavadoras`, `moda-mujer/zapatos`, `deportes/ciclismo`, `libros/booktok`). Returns the same product rows, the same 12-per-page pagination and the same sorting as keyword search, and it is the route El Corte Inglés' robots.txt ALLOWS. ⚠ A sub-category they do not have does NOT 404 on their side — they quietly serve the parent department's page instead, with the site-wide 10,004 total and rows that have nothing to do with what you asked for. This API detects that (their page states which category it really served) and returns NOT_FOUND naming the fallback, rather than handing you a plausible wrong answer.
- `page` (integer, optional, default 1) — Which page of results to start from (1-834). El Corte Inglés serves 12 tiles per page and publishes no way to ask for more — page size is fixed at their end (`itemsPerPage`, `size` and `limit` are all silently ignored, measured). Their result set is capped at 10,004 products, i.e. 834 pages. Page until `meta.pagination.has_more` is false — asking for a page past the end returns NOT_FOUND naming the real last page, never an empty list.
- `max_results` (integer, optional, default 12) — How many products to return (1-60). Because El Corte Inglés fixes its own page at 12, asking for more fetches more of their pages — one upstream page request per 12 results, up to 5 pages per call. Each of those pages is roughly half a megabyte to a megabyte and a half of HTML on a residential exit, so this is the single biggest cost lever on this endpoint: `meta.pages_fetched` and `meta.bytes` report exactly what your call spent.
- `sort` (enum, optional) — Result ordering. These are El Corte Inglés' OWN sort keys, taken verbatim from the sort menu their pages publish — not invented, and each one measurably changes the result order. Omit for their recommended order. An unknown value is rejected here rather than sent: elcorteingles.es answers an unknown sort key with HTTP 503, not with an ignored parameter. [one of: featuredDesc, priceAsc, priceDesc, bestSellerQtyDesc, newInAsc, stockDesc, nameAsc, nameDesc, discountPerDesc, ratingDesc]

**Returns:** products[]{product_id, product_type, url, path, name, brand, brand_slug, gtin13, categories[], hierarchy[], image, colour_count, colours[], variant_count, in_stock_variant_count, price, price_min, price_max, currency, availability, is_marketplace, sellers[], is_gift_card, is_collection, size_guide, group_by}. meta.pagination{page, per_page, pages_fetched, total_results, total_pages, returned, has_more, next_page} — `total_results` is El Corte Inglés' OWN published figure for the query, and it is hard-capped by them at 10,004; `total_pages` is the last page that has products, so page until `has_more` is false rather than guessing. meta.search_mode is `query` | `category` | `id_lookup`; meta.sort echoes the ordering the site confirmed it applied; meta.robots says `allowed` or `disallowed_by_robots` for the path that answered. meta.tiles_seen / sponsored_slots / rejected_rows reconcile against El Corte Inglés' own 12-tile grid: `sponsored_slots` are paid placements carrying no product data (4 per unsorted keyword page, 0 on category pages) and `rejected_rows` are rows that did not look like products at all — that one is normally 0, and a non-zero value is your signal that their layout moved. A sponsored slot can never appear in `products[]`. NO SILENT EMPTIES: this endpoint returns ok:true with an empty `products[]` in exactly ONE situation — a keyword search where El Corte Inglés itself publishes a result count of 0. Paging past the end returns NOT_FOUND naming the real last page; a path that is not a product listing returns NOT_FOUND; and a page where the site claims results but publishes no readable rows returns a retryable PARSE_ERROR rather than an empty list. HONEST LIMITS: El Corte Inglés serves exactly 12 tiles per page and publishes NO page-size parameter, so a bigger `max_results` costs one extra page fetch per 12 rows. Some of those 12 tiles are paid placements carrying no product data, so an organic page is 8-12 rows and `returned` can legitimately be under 12. Search rows carry the colour/price/stock summary but NOT the specification table, the full image gallery, per-variant EANs or reviews — that is `product_detail`. The supermarket catalogue (/supermercado/) is NOT searchable here: it is a separate application whose result page is a 5-7 MB document that renders its rows client-side; `product_detail` does support supermarket products by URL or by their B-code.

**Example request body:**
```json
{
  "query": "zapatillas running",
  "max_results": 12
}
```

### POST /elcorteingles/v1/product_detail — 2 credits
Get one El Corte Inglés product in full, by URL, product code or EAN-13. ONE call returns the complete image gallery, the full colour x size variant matrix with a stable native variant id, an EAN-13, a price, a strike-through price and a live buyable flag on EVERY row, the specification table as El Corte Inglés publishes it (grouped, with their own glossary text), the brand, the availability, the star rating and the top customer reviews inline, plus the seller behind each variant (El Corte Inglés itself or a marketplace merchant), the active promotions and the EU-Omnibus 30-day lowest price. Supermarket products are supported too and return their EAN, gallery and full nutrition panel instead of a size matrix.

**Parameters:**
- `url` (string, optional) — The product's elcorteingles.es URL, exactly as `search` returns it in `products[].url`. This is the ZERO-EXTRA-COST path: the URL is the only key El Corte Inglés' product page resolves, because it embeds a category and a slug that cannot be derived from an id. Give `url`, `product_id` or `ean`.
- `product_id` (string, optional) — El Corte Inglés' own product code — `A56390869` for their catalogue, `MP_0623819_261BZ152012640` for a marketplace listing, `B001018009401193` for a supermarket item. Accepted for convenience, but be aware it costs ONE EXTRA upstream call: elcorteingles.es serves no product-by-id route, so the code is resolved through their own search first (measured: 1 result, every time). Pass `url` when you already have it.
- `ean` (string, optional) — A bare EAN-13 / GTIN barcode. Resolved through El Corte Inglés' own search the same way `product_id` is (one extra call), which makes this endpoint usable for catalogue matching straight from a barcode. Returns NOT_FOUND if El Corte Inglés does not carry that barcode.
- `include_reviews` (boolean, optional, default true) — Fetch the star rating and the top customer reviews (default true). El Corte Inglés does not publish either on its own product page — they come from Bazaarvoice, the review platform their page loads, in one extra ~2 KB request. Measured coverage is 27 of 48 live products across 9 categories: home, appliances and toys are well covered, books and fashion carry none at all. Set false to skip the call entirely.
- `max_reviews` (integer, optional, default 8) — How many reviews to return (1-8). Bazaarvoice's feed publishes at most 8 per page and this endpoint deliberately does not page through them — `rating.count` tells you the true total, which is frequently far larger (110 on one measured product).

**Returns:** product{product_id, product_type, url, path, name, full_name, brand, brand_slug, gtin13, description, categories[], breadcrumb[], category_path, price, price_min, price_max, list_price, currency, discount_percent, availability, in_stock, gallery[], videos[], colours[]{name, sku, image, thumbnail, images[], videos[], available, preselected}, variant_axes[], variant_count, in_stock_variant_count, variants[]{variant_id, gtin13, eci_reference, object_id, colour, axis, size, size_manufacturer, title, price, list_price, discount_percent, currency, lowest_recent_price, availability, in_stock, status, stock_reference, seller_id, is_marketplace, origin, offer_type, sellers[], images[], url, promotions[], nutrition}, specifications[]{group, attributes[]{name, values[], labels[], value, glossary[]}}, is_marketplace, sellers[], is_gift_card, is_digital, size_guide, promotions[], shipping, rating{value, best, count, source}, reviews[]{review_id, rating, title, text, author, date}}. meta.sources says, for THIS product, where each of gallery / variants / specifications / brand / availability actually came from, and meta.coverage counts how many of its variants carry an EAN, a price and a stock flag — so you see the completeness of the row you were given rather than trusting an average. FIELD NOTES: `variant_id` is the variant's own `sku` and `gtin13` its own EAN-13, both verbatim strings — a marketplace variant's sku is the merchant's offer id, which is why both are returned. `price` is what you pay today and `list_price` the struck-through price, null when there is no discount. `lowest_recent_price` is El Corte Inglés' own EU-Omnibus 30-day-lowest disclosure. `rating` and `reviews` come from Bazaarvoice, NOT from El Corte Inglés, and are null / empty for the many products with no reviews (measured 27 of 48 across 9 categories carry a rating; books and fashion carry none). El Corte Inglés publishes NO stock QUANTITY anywhere — only a buyable / not-buyable flag per variant — and no dimensions, weight or per-store stock.

**Example request body:**
```json
{
  "ean": "8806097643135",
  "include_reviews": true
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=elcorteingles
- Human docs page: https://reefapi.com/docs/elcorteingles
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
