# Flipkart Scraper & Price Tracker - Price, MRP, Stock, Seller (`neverempty/flipkart-product-price-monitor`) Actor

Paste Flipkart product URLs and get the selling price, MRP, discount, bank-offer price, stock status, rating breakdown and seller for the exact pid you asked for. Monitor mode returns only products whose price or stock changed since the last run. No proxy needed; unreadable pages are free.

- **URL**: https://apify.com/neverempty/flipkart-product-price-monitor.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 product returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Flipkart Scraper & Price Tracker - Price, MRP, Stock, Seller

Paste **Flipkart product URLs** and get one row per product: selling price, **MRP**, discount %, the **"Buy at" price with bank offers**, stock status, rating with its **1 to 5 star breakdown**, and the **seller** (name, seller rating, seller ID). Turn on monitor mode and later runs return **only the products whose price or stock changed**, with the previous values next to the new ones.

Built for price tracking: you give it the products you care about, it tells you what moved.

### Why this one

- **Only what changed.** A daily watch over 300 products usually has a handful of price moves. Monitor mode returns those rows only; an unchanged product costs one small `product-checked` event instead of a full product row. Review counts change every day on Flipkart, so they are **not** treated as a change.
- **No proxy to pay for.** It reads the product page itself from Apify's normal network. You do not need a residential proxy.
- **The price of the product you asked for, not a "similar product".** A Flipkart product page also carries the prices of recommended products. This Actor checks the product ID (`pid`) of the page against the one in your URL in two places, and returns nothing (free) if they do not match.
- **No wrong price is better than a wrong price.** The selling price is read from three places in the page (the structured data, the page state and the visible price). If they disagree, `price` is `null`, the row is free, and `warnings` says why.
- **Pages that cannot be read are free.** A product ID that does not exist, an old product Flipkart no longer serves, a refused request: each comes back as a free row that says why.

### Input

```json
{
  "productUrls": [
    "https://www.flipkart.com/apple-iphone-17-lavender-256-gb/p/itm5c650337c09ee?pid=MOBHQV9YDG7CGRAM"
  ],
  "onlyChanges": false
}
```

| Field | What it does |
|---|---|
| `productUrls` | Flipkart product pages, up to 1,000 per run (`https://www.flipkart.com/<name>/p/itm<ID>?pid=<PID>`). Share links from the app (`dl.flipkart.com/dl/...`) and URLs with tracking parameters work too. **Keep the `pid`**: it selects the exact colour / size. Without it Flipkart picks the variant and the row says so. |
| `onlyChanges` | Monitor mode. First run: records the starting point, free, no product rows. Later runs: only products whose price or stock changed. |
| `watchName` | Optional. A separate memory per name (for example one per schedule). |
| `resetMonitoringState` | Forget what this watch remembers and start again. |
| `maxConcurrency` | Pages read at the same time, 1 to 4 (default 2). |
| `requestTimeoutSecs` | Seconds to wait for one page, 5 to 60 (default 30). |

Search pages, category pages, review pages and seller lists are **not** read: Flipkart's robots.txt disallows search (`/search?`), paging (`page=`), sorting and review pages, and this Actor follows it. Use it with product URLs you already have.

### Output

One row per product:

```json
{
  "status": "ok",
  "productId": "MOBHQV9YDG7CGRAM",
  "itemId": "itm5c650337c09ee",
  "title": "Apple iPhone 17 (Lavender, 256 GB)",
  "brand": "APPLE",
  "category": "mobile",
  "variantAttributes": { "color": "Lavender", "storage+ram": "256 GB" },
  "price": 86999,
  "mrp": 99900,
  "currency": "INR",
  "discountPercent": 13,
  "discountAmount": 12901,
  "bestOfferPrice": 81999,
  "inStock": true,
  "availabilityStatus": "IN_STOCK",
  "rating": 4.6,
  "ratingCount": 28706,
  "reviewCount": 2057,
  "ratingHistogram": { "1": 1102, "2": 258, "3": 707, "4": 3684, "5": 22955 },
  "sellerName": "TrueComRetail",
  "sellerRating": 4.6,
  "sellerId": "f6d15b4a4f304426",
  "flipkartAssured": true,
  "cashOnDelivery": true,
  "sources": { "price": "json-ld+page-state+page-text", "mrp": "page-state+page-text" }
}
```

| Column | Meaning |
|---|---|
| `price` | Selling price shown on the page, in rupees (number). `currency` is `INR`. |
| `mrp` | The MRP (crossed-out list price). |
| `discountPercent` | The discount % exactly as Flipkart shows it (not recalculated). `discountAmount` = `mrp` − `price`. |
| `bestOfferPrice` | The "Buy at ₹… with Bank offer + more" price. It depends on card and payment offers, so it is not the price everyone pays. |
| `inStock` / `availabilityStatus` | `true` / `false`, and Flipkart's own status word (for example `IN_STOCK`). |
| `rating`, `ratingCount`, `reviewCount`, `ratingHistogram` | Average stars, number of ratings, number of written reviews, and the count for each star. A product with no ratings has `rating: null` and `ratingCount: 0` (not a rating of 0). |
| `sellerName`, `sellerRating`, `sellerId` | The seller that currently has the buy button. |
| `sources` | Where the price and MRP were read and confirmed. |
| `changeType`, `changeTypes`, `previousPrice`, `previousMrp`, `previousInStock`, `previousAvailabilityStatus`, `previousCheckedAt` | Monitor mode only: what changed (`price-drop`, `price-increase`, `out-of-stock`, `back-in-stock`, `availability-changed`) and the values at the last check. |

Free rows have `status` other than `ok` and a `note` that explains:

| `status` | When |
|---|---|
| `not-found` | Flipkart has no product with this ID (it answers with an empty product page). |
| `different-product` | The page shows a different product than the `pid` in the URL. |
| `no-price` | The product was read but no selling price could be confirmed. |
| `unreadable` | Flipkart did not answer with a usable page after 3 tries (old products it no longer sells answer HTTP 500). |
| `blocked` | Flipkart refused the request (403 / 429) or showed a check page. This Actor does not solve check pages or switch to proxies; try again later. |
| `bad-input` | Not a Flipkart product URL (for example a search URL), so nothing was requested. |
| `baseline-recorded`, `no-change`, `budget-reached` | Summary rows in monitor mode and when your spending limit is reached. |

### Measured before release

From Apify's network on 2026-10-09: **45 different products** across 23 Flipkart categories (phones, TVs, speakers, smartwatches, books, sunglasses, watches, clothing, furniture, musical instruments) were all read (HTTP 200, no check page). On all 45, the price from the structured data, the page state and the visible price agreed, the product ID matched the URL, and the price, MRP, discount %, seller name, title and rating count were all found in the visible page text. A made-up product ID came back as an empty product page (now a free `not-found` row), and an old product (Moto E, 2014) answered HTTP 500 twice.

Not measured yet: an out-of-stock product page (none of the 45 was out of stock). The stock status is read from Flipkart's own status word and the structured data, and if the two disagree `inStock` is `null`.

### Pricing

You pay per product row returned (`product-returned`). In monitor mode an unchanged product costs one `product-checked` event, and the first run of a watch is free. There is no start fee. Free rows (not found, blocked, robots, bad input, no price) are never charged. If you set a maximum charge for a run, the run stops there and says so; the products it did not return are not remembered, so the next run returns them.

### Use cases

- Daily price-drop alerts for a list of products you sell against or want to buy.
- MRP and discount tracking during sales such as Big Billion Days.
- Stock alerts: get a row when a product goes out of stock or comes back.
- Seller monitoring: see which seller currently holds the buy button and its rating.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

## `productUrls` (type: `array`):

Flipkart product pages, one per line (up to 1,000 per run), like https://www.flipkart.com/<name>/p/itm<ID>?pid=<PID>. Keep the pid to get that exact colour or size; without it Flipkart picks the variant. Search, category and review pages are not read. If you leave this empty, one example product is read.

## `onlyChanges` (type: `boolean`):

Remembers the selling price and stock status of every product. The first run records the starting point (free, no product rows). Later runs with the same URLs return only the products whose price or stock changed, with the previous values. Unchanged products cost one small product-checked event each.

## `watchName` (type: `string`):

Keeps a separate memory per name, so two schedules with different product lists do not mix. Letters, digits, dot, dash and underscore, up to 40 characters. Empty means the watch called default.

## `resetMonitoringState` (type: `boolean`):

Monitor mode only: forget the remembered prices of this watch name first, so this run records a new starting point.

## `maxConcurrency` (type: `integer`):

How many product pages are read in parallel (1 to 4). Kept low on purpose so Flipkart is not hit hard.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one product page before asking again (5 to 60).

## Actor input object example

```json
{
  "productUrls": [
    "https://www.flipkart.com/apple-iphone-17-lavender-256-gb/p/itm5c650337c09ee?pid=MOBHQV9YDG7CGRAM",
    "https://www.flipkart.com/boat-partypal-500-200w-party-speaker-karaoke-auto-tuner-uhf-mic-rgb-leds-app-support-200-w-bluetooth-tower-speaker/p/itm871677eaf793c?pid=ACCHZGT7WRZWFWB7"
  ],
  "onlyChanges": false,
  "resetMonitoringState": false,
  "maxConcurrency": 2,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Flipkart product: pid, title, brand, selling price, MRP, discount, bank-offer price, stock status, rating with its 1-5 star breakdown, seller name and rating. In monitor mode only the products whose price or stock changed, with the previous values. A page that cannot be read comes back as a free row that says why.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "productUrls": [
        "https://www.flipkart.com/apple-iphone-17-lavender-256-gb/p/itm5c650337c09ee?pid=MOBHQV9YDG7CGRAM",
        "https://www.flipkart.com/boat-partypal-500-200w-party-speaker-karaoke-auto-tuner-uhf-mic-rgb-leds-app-support-200-w-bluetooth-tower-speaker/p/itm871677eaf793c?pid=ACCHZGT7WRZWFWB7"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/flipkart-product-price-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "productUrls": [
        "https://www.flipkart.com/apple-iphone-17-lavender-256-gb/p/itm5c650337c09ee?pid=MOBHQV9YDG7CGRAM",
        "https://www.flipkart.com/boat-partypal-500-200w-party-speaker-karaoke-auto-tuner-uhf-mic-rgb-leds-app-support-200-w-bluetooth-tower-speaker/p/itm871677eaf793c?pid=ACCHZGT7WRZWFWB7",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("neverempty/flipkart-product-price-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "productUrls": [
    "https://www.flipkart.com/apple-iphone-17-lavender-256-gb/p/itm5c650337c09ee?pid=MOBHQV9YDG7CGRAM",
    "https://www.flipkart.com/boat-partypal-500-200w-party-speaker-karaoke-auto-tuner-uhf-mic-rgb-leds-app-support-200-w-bluetooth-tower-speaker/p/itm871677eaf793c?pid=ACCHZGT7WRZWFWB7"
  ]
}' |
apify call neverempty/flipkart-product-price-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neverempty/flipkart-product-price-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MYCWdmHJzpGx5Oc6O/builds/uyS0eJ6eithrV2H7T/openapi.json
