# LuLu Hypermarket API — Gulf supermarket prices from luluhypermarket.com in UAE, Saudi Arabia, Qatar, Kuwait, Bahrain and Oman: price paid and regular price, discount, promotion badges, stock, pack sizes, price per kg/l, barcodes and specifications

> Search LuLu Hypermarket's online shop in one Gulf country: price paid and regular price in the local currency, discount, promotion badges, stock count, pack size and price per kg/l/pc, other pack sizes with their prices, brand, barcodes, category path. `query` required; filters brand, product_type, category_id, min_price/max_price, min_discount, organic; sort; page.
> ReefAPI engine `luluhypermarket` · 4 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/luluhypermarket/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 calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **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). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/luluhypermarket/v1/search — 2 credits
Search LuLu Hypermarket's online shop in one Gulf country: price paid and regular price in the local currency, discount, promotion badges, stock count, pack size and price per kg/l/pc, other pack sizes with their prices, brand, barcodes, category path. `query` required; filters brand, product_type, category_id, min_price/max_price, min_discount, organic; sort; page.

**Parameters:**
- `query` (string, required) — Search words as typed on the shop (English or Arabic). Several words BROADEN the result (any word may match), they do not narrow it.
- `country` (enum, optional, default "ae") — Which LuLu online shop: ae (UAE, AED), sa (Saudi Arabia, SAR), qa (Qatar, QAR), kw (Kuwait, KWD), bh (Bahrain, BHD), om (Oman, OMR). Prices, stock, range, badges and order limits all follow the country (Almarai milk 2 L: 12.50 AED, 12.85 SAR, 11.00 QAR out of stock, 1.035 KWD, 1.250 BHD, 1.330 OMR on 2026-10-15). Default ae; the response always names it. [one of: ae, sa, qa, kw, bh, om]
- `language` (enum, optional, default "en") — en (default) or ar: names, descriptions and badges in Arabic where the shop has them. [one of: en, ar]
- `category_id` (string, optional) — Narrow to one category id (a facet `categories[].category_id` or a `categories` node's category_id).
- `brand` (string, optional) — One brand as the shop prints it (a row's `brand`, e.g. Almarai, Al Rawabi). Matched against the listing's own brand list; an unknown brand returns 0 with the brands present.
- `product_type` (string, optional) — LuLu's product type as a row's `product_type` prints it (e.g. Full Fat, Laban, UHT Milk).
- `min_price` (number, optional) — Lowest price in the country's currency. The shop filters product GROUPS: a row is kept when any of its pack sizes is in range, so a row's own `price` can be outside it (its `pack_options` show the matching pack).
- `max_price` (number, optional) — Highest price in the country's currency (same group rule as min_price).
- `min_discount` (number, optional) — Only items cut by at least this percent (1-100). Same group rule as the price filter: a row is kept when any of its pack sizes has the cut (17/20 rows had it on their own price, 3/20 on a pack option; 2026-10-15, 'milk' AE).
- `organic` (boolean, optional) — true: only items the shop labels organic.
- `sort` (enum, optional, default "relevance") — relevance · price_asc · price_desc · newest · discount (biggest % first). The shop can pin a promoted item on top of a sorted page; such rows carry `pinned: true`. [one of: relevance, price_asc, price_desc, newest, discount]
- `page` (integer, optional, default 1) — Result page. The shop serves the first 10,000 products of any listing (page 500 at 20 per page); `last_reachable_page` says where a listing stops.
- `page_size` (integer, optional, default 20) — Products per page, 1-20 (default 20).

**Returns:** country, country_name, currency, currency_decimals, language, query, category{category_id, name, path}, filters, sort, total, total_capped, page, page_size, last_page, last_reachable_page, has_more, returned, facets{categories[], brands[], product_types[], pack_sizes[], price_range}, results[]{rank, product_id (-> product.product_id), sku, base_code, name, brand, barcodes[], price (what a shopper pays), regular_price (before the cut; null when no cut), discount_amount, discount_percent, on_offer, currency, currency_decimals, tax_rate_percent, badges[], pack_size, unit_price (per kg / l / pc, computed from pack_size), unit_price_unit, pack_quantity, pack_options[]{label, pack_quantity, product_id, sku, name, price, regular_price, in_stock, url}, in_stock, stock, max_order_quantity, delivery_type, product_type, category_path[], dietary[], hidden_in_country, pinned, image, url}

**Example request body:**
```json
{
  "query": "milk",
  "country": "ae"
}
```

### POST https://api.reefapi.com/luluhypermarket/v1/category — 2 credits
List one LuLu category (its path from `categories`, e.g. grocery-food-cupboard-beverage, or a numeric category id) with the same row fields, filters and sorts as `search`.

**Parameters:**
- `category` (string, required) — A category path as `categories` returns it (grocery, grocery-food-cupboard-beverage), a shop category URL, or a numeric category id (5017).
- `country` (enum, optional, default "ae") — Which LuLu online shop: ae (UAE, AED), sa (Saudi Arabia, SAR), qa (Qatar, QAR), kw (Kuwait, KWD), bh (Bahrain, BHD), om (Oman, OMR). Prices, stock, range, badges and order limits all follow the country (Almarai milk 2 L: 12.50 AED, 12.85 SAR, 11.00 QAR out of stock, 1.035 KWD, 1.250 BHD, 1.330 OMR on 2026-10-15). Default ae; the response always names it. [one of: ae, sa, qa, kw, bh, om]
- `language` (enum, optional, default "en") — en (default) or ar: names, descriptions and badges in Arabic where the shop has them. [one of: en, ar]
- `brand` (string, optional) — One brand as the shop prints it (a row's `brand`, e.g. Almarai, Al Rawabi). Matched against the listing's own brand list; an unknown brand returns 0 with the brands present.
- `product_type` (string, optional) — LuLu's product type as a row's `product_type` prints it (e.g. Full Fat, Laban, UHT Milk).
- `min_price` (number, optional) — Lowest price in the country's currency. The shop filters product GROUPS: a row is kept when any of its pack sizes is in range, so a row's own `price` can be outside it (its `pack_options` show the matching pack).
- `max_price` (number, optional) — Highest price in the country's currency (same group rule as min_price).
- `min_discount` (number, optional) — Only items cut by at least this percent (1-100). Same group rule as the price filter: a row is kept when any of its pack sizes has the cut (17/20 rows had it on their own price, 3/20 on a pack option; 2026-10-15, 'milk' AE).
- `organic` (boolean, optional) — true: only items the shop labels organic.
- `sort` (enum, optional, default "relevance") — relevance · price_asc · price_desc · newest · discount (biggest % first). The shop can pin a promoted item on top of a sorted page; such rows carry `pinned: true`. [one of: relevance, price_asc, price_desc, newest, discount]
- `page` (integer, optional, default 1) — Result page. The shop serves the first 10,000 products of any listing (page 500 at 20 per page); `last_reachable_page` says where a listing stops.
- `page_size` (integer, optional, default 20) — Products per page, 1-20 (default 20).

**Returns:** country, country_name, currency, currency_decimals, language, query, category{category_id, name, path}, filters, sort, total, total_capped, page, page_size, last_page, last_reachable_page, has_more, returned, facets{categories[], brands[], product_types[], pack_sizes[], price_range}, results[]{rank, product_id (-> product.product_id), sku, base_code, name, brand, barcodes[], price (what a shopper pays), regular_price (before the cut; null when no cut), discount_amount, discount_percent, on_offer, currency, currency_decimals, tax_rate_percent, badges[], pack_size, unit_price (per kg / l / pc, computed from pack_size), unit_price_unit, pack_quantity, pack_options[]{label, pack_quantity, product_id, sku, name, price, regular_price, in_stock, url}, in_stock, stock, max_order_quantity, delivery_type, product_type, category_path[], dietary[], hidden_in_country, pinned, image, url}

**Example request body:**
```json
{
  "category": "grocery-food-cupboard-beverage"
}
```

### POST https://api.reefapi.com/luluhypermarket/v1/product — 1 credit
One LuLu product by the `product_id` a search row returns (or its shop URL), in one country: prices, discount, badges, stock, every pack size with its own price and stock flag, barcodes, images, description, highlights, ingredients and the full specification sheet.

**Parameters:**
- `product_id` (string, required) — The `product_id` a search row returns (e.g. 276), or the product's shop URL (https://gcc.luluhypermarket.com/en-ae/<name>/p/<sku>/).
- `country` (enum, optional, default "ae") — Which LuLu online shop: ae (UAE, AED), sa (Saudi Arabia, SAR), qa (Qatar, QAR), kw (Kuwait, KWD), bh (Bahrain, BHD), om (Oman, OMR). Prices, stock, range, badges and order limits all follow the country (Almarai milk 2 L: 12.50 AED, 12.85 SAR, 11.00 QAR out of stock, 1.035 KWD, 1.250 BHD, 1.330 OMR on 2026-10-15). Default ae; the response always names it. [one of: ae, sa, qa, kw, bh, om]
- `language` (enum, optional, default "en") — en (default) or ar: names, descriptions and badges in Arabic where the shop has them. [one of: en, ar]

**Returns:** product{product_id, sku, base_code, name, brand, barcodes[], price, regular_price, discount_amount, discount_percent, on_offer, currency, currency_decimals, tax_rate_percent, badges[], pack_size, unit_price, unit_price_unit, pack_quantity, pack_options[], in_stock, stock, max_order_quantity, delivery_type, product_type, category_path[], dietary[], hidden_in_country, image, images[], url, description, short_description, highlights[], ingredients, specifications[]{key, label, value}, substitute_skus[], seller_offers}, country, country_name, currency, language

**Example request body:**
```json
{
  "product_id": "276",
  "country": "ae"
}
```

### POST https://api.reefapi.com/luluhypermarket/v1/categories — 3 credits
LuLu's category tree from the shop menu (318 nodes on 2026-10-15): name, path, id where the menu gives one, children. Paths and ids feed `category`.

**Parameters:**
- `category` (string, optional) — Return only this node's subtree (its path, e.g. grocery); omit for the whole tree.
- `country` (enum, optional, default "ae") — Which LuLu online shop: ae (UAE, AED), sa (Saudi Arabia, SAR), qa (Qatar, QAR), kw (Kuwait, KWD), bh (Bahrain, BHD), om (Oman, OMR). Prices, stock, range, badges and order limits all follow the country (Almarai milk 2 L: 12.50 AED, 12.85 SAR, 11.00 QAR out of stock, 1.035 KWD, 1.250 BHD, 1.330 OMR on 2026-10-15). Default ae; the response always names it. [one of: ae, sa, qa, kw, bh, om]
- `language` (enum, optional, default "en") — en (default) or ar: names, descriptions and badges in Arabic where the shop has them. [one of: en, ar]

**Returns:** parent, country, total_categories, categories[]{name, category, category_id, url, depth, parent, children[]}

**Example request body:**
```json
{
  "country": "ae"
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

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