Skip to main content
Thirdwatchthirdwatch
E-commerce & products

Track Myntra vs AJIO and Nykaa Prices in Real Time (2026)

Build a cross-marketplace India fashion price tracker with Thirdwatch's Myntra, AJIO and Nykaa scrapers. Diff alerts, fuzzy SKU match, Python recipes inside.

May 12, 2026 · 5 min read · 1,193 words
See the scraper →

Thirdwatch's Myntra, AJIO and Nykaa Scrapers feed a structured cross-marketplace India fashion-and-beauty price tracker — daily snapshot the same SKU watchlist on all three platforms, compute price deltas, surface arbitrage and brand-protection signals. Built for India e-commerce ops teams, brand-protection functions, arbitrage operators, and price-comparison consumer apps.

Why track Myntra vs AJIO and Nykaa

India fashion e-commerce is a three-way race. According to RedSeer Strategy Consultants' 2024 India fashion e-commerce report, Myntra, AJIO and Nykaa together capture more than 70% of online fashion-and-beauty GMV in India. They differ on seller composition, private-label depth and promotional cycle. The same Levi's jeans can sell for ₹2,499 on Myntra, ₹2,299 on AJIO and ₹2,799 on Nykaa Fashion in the same weekend, and reverse the next. For brand teams and arbitrage operators, the price delta is operational signal, not market noise.

The job-to-be-done is structured. A brand team managing 500 SKUs across all three marketplaces wants daily delta reports. A reseller arbitrage operator detects 10%+ gaps in near-real-time. A consumer-app builder ingests all three as the data layer for an India price-comparison product. A category researcher benchmarks Myntra-exclusive brands against AJIO private labels at the price-band level. All reduce to triple-marketplace daily snapshot plus SKU matching plus delta computation.

How does this compare to the alternatives?

Three options for cross-marketplace India fashion price tracking:

Approach Reliability Setup time Maintenance
DIY Python against three SPAs Low — each marketplace ships SSR data differently and rate-limits aggressively 1-2 weeks Continuous; three independent change surfaces
Generic scraping API Medium — raw HTML works, but you write three extractors and three SKU-matchers 3-5 days High; you own all extractor maintenance
Thirdwatch Myntra + AJIO + Nykaa Scrapers Production-tested with production-grade anti-bot tooling 10 minutes Thirdwatch tracks all three sites

Indian price-comparison SaaS exists but mostly serves electronics; few cover fashion cross-marketplace at the SKU level. The three Thirdwatch actors give you the raw records to build your own analytics or consumer-facing product. See the e-commerce scraping guide for the underlying patterns.

How to track cross-marketplace fashion pricing in 4 steps

Step 1: How do I run all three actors from one script?

One Apify token works across all three actors. Fan out in parallel using concurrent.futures to keep wall-clock latency tight.

export APIFY_TOKEN="apify_api_xxxxxxxxxxxxxxxx"
import os, requests
from concurrent.futures import ThreadPoolExecutor

TOKEN = os.environ["APIFY_TOKEN"]
WATCHLIST = ["levi's mens jeans", "nike air force 1",
             "lakme mascara", "maybelline lipstick"]

ACTORS = {
    "myntra": "thirdwatch~myntra-scraper",
    "ajio":   "thirdwatch~ajio-scraper",
    "nykaa":  "thirdwatch~nykaa-scraper",
}

def pull(actor_id):
    r = requests.post(
        f"https://api.apify.com/v2/acts/{actor_id}/run-sync-get-dataset-items",
        params={"token": TOKEN},
        json={"queries": WATCHLIST, "maxResults": 50},
        timeout=900,
    )
    return r.json()

with ThreadPoolExecutor(max_workers=3) as pool:
    results = dict(zip(
        ACTORS.keys(),
        pool.map(pull, ACTORS.values()),
    ))

for name, rows in results.items():
    print(f"{name}: {len(rows)} records")

Step 2: How do I normalise records across the three schemas?

Schemas align on the obvious fields but use different names. Build a tiny adapter layer.

import pandas as pd

def normalise(rows, source):
    df = pd.DataFrame(rows)
    if source == "myntra":
        df = df.rename(columns={
            "product_name": "title",
            "original_price": "mrp",
            "rating_count": "reviews",
        })
    elif source == "ajio":
        df = df.rename(columns={
            "name": "title",
            "mrp_price": "mrp",
            "review_count": "reviews",
        })
    elif source == "nykaa":
        df = df.rename(columns={
            "name": "title",
            "mrp": "mrp",
            "review_count": "reviews",
        })
    df["source"] = source
    return df[["source", "brand", "title", "price", "mrp", "rating", "reviews", "url"]]

frames = [normalise(rows, src) for src, rows in results.items()]
all_df = pd.concat(frames, ignore_index=True)
print(all_df.head())

Step 3: How do I match the same SKU across all three?

There's no shared identifier — use brand plus token-set fuzzy match.

from rapidfuzz import fuzz

def match_key(row):
    return f"{(row.brand or '').lower()} | {(row.title or '').lower()}"

all_df["key"] = all_df.apply(match_key, axis=1)
myntra = all_df[all_df.source == "myntra"]

triples = []
for _, m in myntra.iterrows():
    for other_src in ("ajio", "nykaa"):
        candidates = all_df[all_df.source == other_src]
        best, best_score = None, 0
        for _, c in candidates.iterrows():
            score = fuzz.token_set_ratio(m.key, c.key)
            if score > best_score:
                best_score, best = score, c
        if best is not None and best_score >= 85:
            triples.append({
                "brand": m.brand, "title": m.title,
                "myntra_price": m.price,
                f"{other_src}_price": best.price,
                "score": best_score,
            })

matched = pd.DataFrame(triples)
matched["myntra_vs_other_pct"] = (
    (matched.filter(regex="_price$").min(axis=1) - matched.myntra_price)
    / matched.myntra_price * 100
).round(1)
print(matched.head(15))

Step 4: How do I forward 10%+ gaps to Slack?

Persist matched triples, dedup on brand+title, alert on first detection.

import requests as r, json, pathlib, datetime

gaps = matched[matched.myntra_vs_other_pct <= -10]
for _, row in gaps.iterrows():
    msg = (f":scales: *{row.brand} {row.title[:60]}* — "
           f"Myntra ₹{int(row.myntra_price):,}, "
           f"cheapest elsewhere ₹{int(row.filter(regex='_price$').min()):,} "
           f"({row.myntra_vs_other_pct:+.1f}%)")
    r.post("https://hooks.slack.com/services/.../...",
           json={"text": msg}, timeout=10)

today = datetime.date.today().isoformat()
pathlib.Path(f"snapshots/triples-{today}.json").write_text(
    matched.to_json(orient="records"))
print(f"{len(gaps)} cross-marketplace gaps alerted")

A 10%+ gap with both legs in stock is a meaningful signal. Below that, cashback and tier-coupon noise usually accounts for the delta.

Sample output

A matched triple from the tracker looks like the example below. Each marketplace contributes one record per SKU; the matcher pairs them on brand+title.

[
  {
    "source": "myntra",
    "brand": "Levi's",
    "title": "Levi's Men's 511 Slim Fit Jeans",
    "price": 2499,
    "mrp": 3999,
    "rating": 4.4,
    "reviews": 1280,
    "url": "https://www.myntra.com/jeans/levis/.../buy"
  },
  {
    "source": "ajio",
    "brand": "Levi's",
    "title": "Levi's Men 511 Slim Fit Mid-Rise Jeans",
    "price": 2299,
    "mrp": 3999,
    "rating": 4.5,
    "reviews": 980,
    "url": "https://www.ajio.com/levis-men-511-slim-fit-mid-rise-jeans/p/..."
  },
  {
    "source": "nykaa",
    "brand": "Levi's",
    "title": "Levi's 511 Slim Fit Jeans for Men",
    "price": 2799,
    "mrp": 3999,
    "rating": 4.3,
    "reviews": 312,
    "url": "https://www.nykaafashion.com/.../p/..."
  }
]

The brand + title pair is the matching key. mrp is identical across all three because Levi's sets a single India MRP; the gap shows up in price. Per-marketplace rating and reviews are useful as a confidence signal for matching: if reviews diverge by 10x, you're likely on a colour or fit variant rather than the same SKU.

Common pitfalls

Three things go wrong in production cross-marketplace pipelines. SKU-matching false positives — fuzzy matching at 85+ score still pairs "Levi's 511" with "Levi's 512" occasionally; require brand exact-match and use reviews order-of-magnitude as a sanity check. Coupon and tier discounts — Myntra Insider, AJIO Wardrobe and Nykaa Prive give tier-based discounts that aren't reflected in the public price; cross-marketplace gaps under 10% are usually tier-coupon noise rather than real arbitrage. Sale-window blending — Myntra EORS, AJIO BIG Bold Sale and Nykaa Hot Pink Sale rarely overlap; comparing one platform in-sale against the others out-of-sale produces misleading deltas. Tag each snapshot with the in-sale flag per marketplace.

Thirdwatch's three actors share a consistent contract — same SDK call, same dataset-item shape, same per-result billing — so you spend time on analytics rather than three independent scraping integrations. Each uses production-grade anti-bot tooling tuned for the specific marketplace. Pair with Flipkart and Amazon India for horizontal-marketplace coverage. A fourth subtle pitfall worth flagging: Nykaa Fashion is a separate domain from Nykaa Beauty; for cross-fashion analysis make sure your watchlist tags products to the correct sub-marketplace.

Related use cases

Frequently asked questions

Why compare Myntra, AJIO and Nykaa prices?

Myntra dominates apparel, AJIO is Reliance Retail's fashion play with strong private-label depth, and Nykaa owns beauty (and increasingly fashion via Nykaa Fashion). For brand teams and ops, the same SKU often prices 5-15% apart across these three marketplaces. Cross-marketplace visibility is essential for India-fashion pricing, brand protection and arbitrage.

How do I match the same SKU across Myntra, AJIO and Nykaa?

There's no shared identifier, so matching uses brand + product_name fuzzy similarity. Three common approaches: exact-substring match on brand plus distinctive model words (Nike Air Force 1 White), token-set fuzzy matching with rapidfuzz, and image-hash comparison if you fetch images from all three. Start with substring matching for known SKUs and fall back to fuzzy for long-tail.

What's the right cadence for cross-marketplace monitoring?

Daily during steady-state, hourly during sale events like End-of-Reason-Sale, AJIO's BIG Bold Sale, and Nykaa's Hot Pink Sale. All three shift prices intraday during sale windows. A 100-SKU watchlist tracked hourly across three marketplaces stays affordable enough for sustained sale-period operation.

How do I detect a real price gap rather than noise?

Compute the price delta per matched SKU triplet and require both legs to be in stock. A 10%+ gap with the cheaper listing having at least three available sizes and a rating above 4.0 is a viable signal. Below 10%, the gap is usually noise from cashback differences, coupon stacking, or Insider/Privilege tier discounts that don't flow into the public price field.

Does this work for ethnic wear and beauty too?

Yes — pass category slugs like 'women-kurtas-kurtis' to Myntra, the equivalent AJIO slug, and 'beauty-personal-care' to either Myntra or Nykaa. The schemas are aligned enough that you can union them on (brand, product_name, price) for cross-marketplace analytics. Nykaa is the strongest source for beauty SKUs; Myntra and AJIO are the strongest for apparel.

How does this compare to Indian price-comparison apps?

Consumer apps like MySmartPrice and BuyHatke focus on electronics and bundle affiliate-revenue logic. Few cover fashion cross-marketplace tracking at the SKU level. Building your own with the three Thirdwatch scrapers is meaningfully cheaper for systematic operational use and gives you the underlying records to power your own analytics or consumer app.

Related

Try it yourself

100 free credits, no credit card.

About 30 real searches. Add the MCP to Claude or Cursor in two minutes.