# Nykaa API — India's biggest beauty marketplace as JSON: product search, MRP and selling price with the real discount, shade-level prices and stock, customer reviews with the rating histogram and aspect sentiment, brand and category catalogues with filters that bite, from nykaa.com — prices in INR, no API key, no login

> Search Nykaa exactly as a shopper does and get the product grid: the price actually paid, the printed MRP, the real discount, rating and rating count, shade count, stock and the product id. Two things this action does for you: it reads the same index the website shows (a cheaper keyword route on the same host answers 0 for 'nykaa foundation', where the site answers 116), and when Nykaa redirects a head term such as 'lipstick' to a category it follows that and tells you, so you get the catalogue instead of nothing. 🔴 Nykaa server-renders only the FIRST 20 matches of a search: `total_results` is its own count, and a deeper walk goes through `category` with the `category_id` this action hands back.
> ReefAPI engine `nykaa` · 11 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/nykaa/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/nykaa/v1/search — 2 credits
Search Nykaa exactly as a shopper does and get the product grid: the price actually paid, the printed MRP, the real discount, rating and rating count, shade count, stock and the product id. Two things this action does for you: it reads the same index the website shows (a cheaper keyword route on the same host answers 0 for 'nykaa foundation', where the site answers 116), and when Nykaa redirects a head term such as 'lipstick' to a category it follows that and tells you, so you get the catalogue instead of nothing. 🔴 Nykaa server-renders only the FIRST 20 matches of a search: `total_results` is its own count, and a deeper walk goes through `category` with the `category_id` this action hands back.

**Parameters:**
- `query` (string, required) — What a shopper would type on nykaa.com — a product, a brand, a category, or a concern phrase such as 'serum for oily skin'.
- `sort` (enum, optional) — Result order. Nykaa's own default is `popularity`. It refuses any order it does not know, so these seven are all that exist. [one of: popularity, price_asc, price_desc, discount, customer_top_rated, new_arrival, name]
- `price_min` (integer, optional) — Lowest selling price in INR. Use with `price_max`; the source takes the pair as one band.
- `price_max` (integer, optional) — Highest selling price in INR. Measured on the Lipstick category: 718 products unfiltered, 295 under 500, 84 between 1000 and 1999.
- `min_discount` (integer, optional) — Only products discounted by at least this percentage. Measured on Lipstick: 718 unfiltered, 453 discounted at all, 184 at 20 % or more, 92 at 30 %, 36 at 40 %.
- `min_rating` (integer, optional) — Only products whose average customer rating is at least this many stars (1-4; Nykaa publishes no 5-only filter). Measured on the query 'kajal waterproof': 329 unfiltered, 309 at 3+, 278 at 4+.
- `brand_id` (string, optional) — Narrow to one brand. The id comes from `facets.brand` on this action (set `include_facets`) or from `brands`. Measured: brand 3899 in category 249 returns exactly the 26 the facet promises. Nykaa offers no brand facet on a KEYWORD search, only on a category or brand listing.
- `color_id` (string, optional) — Narrow to one colour family; the id comes from `facets.color`. 🔴 This one matches at SHADE level, so on a category its own count can exceed the unfiltered product count.
- `finish_id` (string, optional) — Finish, e.g. matte / creme / satin / glossy. Id from `facets.finish`. Measured on Lipstick: 454 of 718 are matte.
- `concern_id` (string, optional) — Skin or hair concern (acne, pigmentation, dryness, hair fall). Id from `facets.concern` — this is the axis Indian beauty shoppers actually buy on.
- `formulation_id` (string, optional) — Formulation (liquid, cream, powder, pencil, gel). Id from `facets.formulation`.
- `ingredient_id` (string, optional) — Hero ingredient (hyaluronic acid, niacinamide, salicylic acid, retinol). Id from `facets.ingredient_v1`.
- `gender_id` (string, optional) — Gender the product is listed for. Id from `facets.gender` (10711 female, 10712 unisex on the categories measured).
- `country_of_origin` (string, optional) — ISO country code of manufacture, as Nykaa files it. Id from `facets.country_of_origin` — 'IN' and 'KR' are the two a buyer of Indian beauty data usually wants.
- `preference_id` (string, optional) — Claim or preference (paraben free, cruelty free, vegan, dermatologically tested). Id from `facets.preference`.
- `skin_type_id` (string, optional) — Skin type the product is listed for (oily, dry, normal, combination, sensitive). Id from `facets.skin_type`.
- `include_facets` (boolean, optional, default false) — Also return `facets`: every filter Nykaa offers for this listing — brands, colours, finishes, concerns, ingredients, formulations, price bands, ratings, discounts, country of origin — each with its id and the number of products behind it. This is where every `*_id` parameter above comes from.

**Returns:** products[]{product_id, url, name, product_title, brand, price_inr, mrp_inr, discount_percent, discount_percent_listed, currency, rating, rating_count, in_stock, stock_quantity, shade_count, variant_type, sku, image, category_path[], offer, offer_count, tags}, total_results, listing_type (search|category), query, did_you_mean, approximate_results, category_id, category_name, promo_tiles_dropped, facets (optional)

**Example request body:**
```json
{
  "query": "maybelline mascara"
}
```

### POST https://api.reefapi.com/nykaa/v1/category — 1 credit
Walk one category with filters that bite: price band, minimum discount, minimum rating, one brand, colour, finish, concern, ingredient, formulation, skin type, country of origin, and any of Nykaa's seven sort orders. Same product rows as `search`, and unlike search this one pages all the way down. Category ids come from `categories`, from `suggest`, or from any product's `category_path`.

**Parameters:**
- `category_id` (string, required) — Numeric category id (249 = Lipstick), or a nykaa.com category URL. A Nykaa brand page is a category too, so a brand id works here as well.
- `page` (integer, optional, default 1) — 1-based page number. Nykaa serves 20 products a page and ignores every page-size parameter it is given, so this is the only way to go deeper. `total_results` says how far you can go.
- `sort` (enum, optional) — Result order. Nykaa's own default is `popularity`. It refuses any order it does not know, so these seven are all that exist. [one of: popularity, price_asc, price_desc, discount, customer_top_rated, new_arrival, name]
- `price_min` (integer, optional) — Lowest selling price in INR. Use with `price_max`; the source takes the pair as one band.
- `price_max` (integer, optional) — Highest selling price in INR. Measured on the Lipstick category: 718 products unfiltered, 295 under 500, 84 between 1000 and 1999.
- `min_discount` (integer, optional) — Only products discounted by at least this percentage. Measured on Lipstick: 718 unfiltered, 453 discounted at all, 184 at 20 % or more, 92 at 30 %, 36 at 40 %.
- `min_rating` (integer, optional) — Only products whose average customer rating is at least this many stars (1-4; Nykaa publishes no 5-only filter). Measured on the query 'kajal waterproof': 329 unfiltered, 309 at 3+, 278 at 4+.
- `brand_id` (string, optional) — Narrow to one brand. The id comes from `facets.brand` on this action (set `include_facets`) or from `brands`. Measured: brand 3899 in category 249 returns exactly the 26 the facet promises. Nykaa offers no brand facet on a KEYWORD search, only on a category or brand listing.
- `color_id` (string, optional) — Narrow to one colour family; the id comes from `facets.color`. 🔴 This one matches at SHADE level, so on a category its own count can exceed the unfiltered product count.
- `finish_id` (string, optional) — Finish, e.g. matte / creme / satin / glossy. Id from `facets.finish`. Measured on Lipstick: 454 of 718 are matte.
- `concern_id` (string, optional) — Skin or hair concern (acne, pigmentation, dryness, hair fall). Id from `facets.concern` — this is the axis Indian beauty shoppers actually buy on.
- `formulation_id` (string, optional) — Formulation (liquid, cream, powder, pencil, gel). Id from `facets.formulation`.
- `ingredient_id` (string, optional) — Hero ingredient (hyaluronic acid, niacinamide, salicylic acid, retinol). Id from `facets.ingredient_v1`.
- `gender_id` (string, optional) — Gender the product is listed for. Id from `facets.gender` (10711 female, 10712 unisex on the categories measured).
- `country_of_origin` (string, optional) — ISO country code of manufacture, as Nykaa files it. Id from `facets.country_of_origin` — 'IN' and 'KR' are the two a buyer of Indian beauty data usually wants.
- `preference_id` (string, optional) — Claim or preference (paraben free, cruelty free, vegan, dermatologically tested). Id from `facets.preference`.
- `skin_type_id` (string, optional) — Skin type the product is listed for (oily, dry, normal, combination, sensitive). Id from `facets.skin_type`.
- `include_facets` (boolean, optional, default false) — Also return `facets`: every filter Nykaa offers for this listing — brands, colours, finishes, concerns, ingredients, formulations, price bands, ratings, discounts, country of origin — each with its id and the number of products behind it. This is where every `*_id` parameter above comes from.

**Returns:** products[] (same shape as search), total_results, page, category_id, category_name, category_ancestors[], promo_tiles_dropped, facets (optional)

**Example request body:**
```json
{
  "category_id": "249"
}
```

### POST https://api.reefapi.com/nykaa/v1/brand — 1 credit
One brand's whole Nykaa catalogue, paged and filterable exactly like a category. Pass the brand id if you have it, or just the brand NAME and this action resolves it for you (one extra upstream lookup) and reports the id it used.

**Parameters:**
- `brand` (string, required) — A brand name ('maybelline', 'lakme', 'the ordinary'), its numeric Nykaa id, or a nykaa.com brand URL. A name costs one extra upstream lookup; an id costs none.
- `page` (integer, optional, default 1) — 1-based page number. Nykaa serves 20 products a page and ignores every page-size parameter it is given, so this is the only way to go deeper. `total_results` says how far you can go.
- `sort` (enum, optional) — Result order. Nykaa's own default is `popularity`. It refuses any order it does not know, so these seven are all that exist. [one of: popularity, price_asc, price_desc, discount, customer_top_rated, new_arrival, name]
- `price_min` (integer, optional) — Lowest selling price in INR. Use with `price_max`; the source takes the pair as one band.
- `price_max` (integer, optional) — Highest selling price in INR. Measured on the Lipstick category: 718 products unfiltered, 295 under 500, 84 between 1000 and 1999.
- `min_discount` (integer, optional) — Only products discounted by at least this percentage. Measured on Lipstick: 718 unfiltered, 453 discounted at all, 184 at 20 % or more, 92 at 30 %, 36 at 40 %.
- `min_rating` (integer, optional) — Only products whose average customer rating is at least this many stars (1-4; Nykaa publishes no 5-only filter). Measured on the query 'kajal waterproof': 329 unfiltered, 309 at 3+, 278 at 4+.
- `brand_id` (string, optional) — Narrow to one brand. The id comes from `facets.brand` on this action (set `include_facets`) or from `brands`. Measured: brand 3899 in category 249 returns exactly the 26 the facet promises. Nykaa offers no brand facet on a KEYWORD search, only on a category or brand listing.
- `color_id` (string, optional) — Narrow to one colour family; the id comes from `facets.color`. 🔴 This one matches at SHADE level, so on a category its own count can exceed the unfiltered product count.
- `finish_id` (string, optional) — Finish, e.g. matte / creme / satin / glossy. Id from `facets.finish`. Measured on Lipstick: 454 of 718 are matte.
- `concern_id` (string, optional) — Skin or hair concern (acne, pigmentation, dryness, hair fall). Id from `facets.concern` — this is the axis Indian beauty shoppers actually buy on.
- `formulation_id` (string, optional) — Formulation (liquid, cream, powder, pencil, gel). Id from `facets.formulation`.
- `ingredient_id` (string, optional) — Hero ingredient (hyaluronic acid, niacinamide, salicylic acid, retinol). Id from `facets.ingredient_v1`.
- `gender_id` (string, optional) — Gender the product is listed for. Id from `facets.gender` (10711 female, 10712 unisex on the categories measured).
- `country_of_origin` (string, optional) — ISO country code of manufacture, as Nykaa files it. Id from `facets.country_of_origin` — 'IN' and 'KR' are the two a buyer of Indian beauty data usually wants.
- `preference_id` (string, optional) — Claim or preference (paraben free, cruelty free, vegan, dermatologically tested). Id from `facets.preference`.
- `skin_type_id` (string, optional) — Skin type the product is listed for (oily, dry, normal, combination, sensitive). Id from `facets.skin_type`.
- `include_facets` (boolean, optional, default false) — Also return `facets`: every filter Nykaa offers for this listing — brands, colours, finishes, concerns, ingredients, formulations, price bands, ratings, discounts, country of origin — each with its id and the number of products behind it. This is where every `*_id` parameter above comes from.

**Returns:** products[] (same shape as search), total_results, page, brand_id, brand_name, resolved_from (set when a name was resolved), promo_tiles_dropped, facets (optional)

**Example request body:**
```json
{
  "brand": "maybelline"
}
```

### POST https://api.reefapi.com/nykaa/v1/product — 1 credit
The full Nykaa product record: selling price and printed MRP with the real discount, brand, rating and how many people rated it, how many wrote a review, the 1-5 star histogram, Nykaa's own review summary and its ranked aspect sentiment ('Color Payoff: Positive'), the barcode (GTIN), seller, country of origin, expiry date, return window, live stock, shade count, every image, the description, ingredients and how-to-use.

**Parameters:**
- `product_id` (string, required) — The product to read. Accepts the numeric id (367160) or a full nykaa.com product URL. Every listing row carries both.

**Returns:** product{product_id, url, name, product_title, brand, price_inr, mrp_inr, discount_percent, discount_percent_listed, currency, rating, rating_count, review_count, rating_histogram[]{stars, count, percent}, review_summary, review_aspects[]{aspect, sentiment, rank}, top_review, gtin, sku, seller, country_of_origin, manufacturer, expiry_date, return_period_days, returnable, in_stock, stock_quantity, shade_count, variant_type, images[], description, ingredients, how_to_use, offers[], category_path[]}

**Example request body:**
```json
{
  "product_id": "985204"
}
```

### POST https://api.reefapi.com/nykaa/v1/product/shades — 1 credit
Every shade of one product — or every pack size, for products Nykaa sells in several weights — with ITS OWN price, MRP, discount, stock count and images. A Nykaa lipstick is one product id and thirty shades, each separately priced and separately in or out of stock, and this is the only place that is published. Shades with zero stock are returned with `in_stock: false` rather than dropped, which is also why `count` here can be larger than the `shade_count` on the product record — that one is Nykaa's own headline number and leaves discontinued shades out.

**Parameters:**
- `product_id` (string, required) — The product to read. Accepts the numeric id (367160) or a full nykaa.com product URL. Every listing row carries both.

**Returns:** shades[]{variant_id, name, sku, price_inr, mrp_inr, discount_percent, currency, stock_quantity, in_stock, image, images[]}, product_id, count, in_stock_count

**Example request body:**
```json
{
  "product_id": "985204"
}
```

### POST https://api.reefapi.com/nykaa/v1/product/reviews — 2 credits
The customer reviews Nykaa publishes for a product: rating, title, the full text, the author display name, the date, how many shoppers found it helpful, whether the reviewer is a verified buyer, which shade they bought and the photos they posted. 🔴 Two honest limits. The source server-renders the same 20 reviews whatever page, sort or filter is asked for, so that is the ceiling per product and this action does not pretend to page. And those 20 are Nykaa's own 'most useful, verified buyer' selection, not a random sample: across 12 products measured, 240 of 240 were verified buyers, 240 of 240 carried photos and the ratings skew to 5. `reviews_available` is Nykaa's own total and `product` returns the real 1-5 star histogram behind it — read that, not these 20, for sentiment.

**Parameters:**
- `product_id` (string, required) — The product to read. Accepts the numeric id (367160) or a full nykaa.com product URL. Every listing row carries both.

**Returns:** reviews[]{review_id, rating, title, text, author, created_at, helpful_count, verified_buyer, shade_id, images[]}, product{product_id, name, brand, url, rating, rating_count, review_count}, count, reviews_available

**Example request body:**
```json
{
  "product_id": "985204"
}
```

### POST https://api.reefapi.com/nykaa/v1/product/similar — 1 credit
The products Nykaa itself recommends beside this one — its 'Explore Similar Products' rail, returned as full product rows with prices and ratings. A competitive set around a product without having to guess a category. Nykaa does not build a rail for every product: on 12 products measured, 6 had 9-16 recommendations and 6 had none, and an empty `products` means the source publishes none, not an error.

**Parameters:**
- `product_id` (string, required) — The product to read. Accepts the numeric id (367160) or a full nykaa.com product URL. Every listing row carries both.

**Returns:** products[] (same shape as search), product_id, count

**Example request body:**
```json
{
  "product_id": "985204"
}
```

### POST https://api.reefapi.com/nykaa/v1/suggest — 1 credit
Nykaa's own autocomplete for a partial query: the search terms it would offer, the brands and categories it maps the term to WITH their ids, and the products it would show. The cheapest way to turn a brand or category NAME into the id the other actions take.

**Parameters:**
- `query` (string, required) — A partial or full query, brand name or category name.

**Returns:** suggestions[]{text, type (brand|category|query), url, category_id, match_count}, products[]{product_id, name, url}, query

**Example request body:**
```json
{
  "query": "maybelline"
}
```

### POST https://api.reefapi.com/nykaa/v1/trending — 1 credit
What India is searching for on Nykaa right now — the popular-searches list the site prints in its own search box.

**Parameters:** none

**Returns:** trending[]{text, url, type}, count

### POST https://api.reefapi.com/nykaa/v1/categories — 2 credits
Nykaa's category tree: every department, category and sub-category with its id, name, URL and depth. These are the ids `category` takes. One call, cached for a day.

**Parameters:**
- `query` (string, optional) — Only categories whose name contains this text (case-insensitive). Omit for the whole tree.
- `depth` (integer, optional) — Only categories at this depth, counted in URL segments as Nykaa files them: 2 is a category ('makeup/face' = Face), 3 a sub-category ('makeup/face/face-foundation' = Foundation). Measured: 337 categories, depths 1-6, most at 2 and 3.

**Returns:** categories[]{category_id, name, url, path[], depth}, count

**Example request body:**
```json
{
  "query": "lipstick"
}
```

### POST https://api.reefapi.com/nykaa/v1/brands — 2 credits
Nykaa's A-Z brand index: every brand the marketplace carries, with the id its brand page is addressed by, its letter and its URL. These are the ids `brand` and `brand_id` take. One call, cached for a day.

**Parameters:**
- `query` (string, optional) — Only brands whose name contains this text (case-insensitive).
- `letter` (string, optional) — Only brands filed under this letter (A-Z, or # for names starting with a digit or symbol).
- `limit` (integer, optional, default 500) — Rows to return — the index holds several thousand brands. `total` always reports the full match count.

**Returns:** brands[]{brand_id, name, letter, url, is_top_brand}, count, total

**Example request body:**
```json
{
  "letter": "L"
}
```

## 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=nykaa
- Human docs page: https://reefapi.com/docs/nykaa
- Overview page: https://reefapi.com/nykaa-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
