# AJIO Product & Markdown Price Scraper (India) (`superslowsloth/ajio-products`) Actor

AJIO scraper: search terms to one row per product with INR selling price, MRP, discount percent, price after the best coupon, brand, department, seller and image. For daily Indian fashion price and markdown watching.

- **URL**: https://apify.com/superslowsloth/ajio-products.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.04 / 1,000 product scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## AJIO Product & Markdown Price Scraper (India)

Search [AJIO](https://www.ajio.com) (Reliance Retail's Indian fashion store) by
keyword and get one flat row per product: the **selling price and the MRP in
INR**, the markdown percent, the **price after the best coupon**, brand,
department, seller, the product link and the photo. Run it on a schedule and diff
the dataset to get a **daily Indian fashion price and markdown watch**: which
brands cut prices, which products were marked down and by how much, and where a
coupon makes the real price lower still.

No account, no API key, no login, no browser. One request returns up to 100
products.

### Input

| Field | Notes |
|---|---|
| `searchTerms` | One or more search terms, one per line (`shirt`, `nike sneakers`, `cotton kurta`). Each term is read separately, page by page. A product found by two terms is returned once, under the first. |
| `maxItems` | Products to read per term (default 100, up to 10,000). 100 per page. |
| `onlyOnSale` | Return only products whose selling price is below the MRP. Products that are not reduced are read, not returned and not charged. |
| `sort` | `relevance` (default), `discount`, `price-asc`, `price-desc`, `newest`: the choices of AJIO's own sort menu. |
| `proxyConfiguration` | Apify datacenter proxy by default. |

Example input:

```json
{
  "searchTerms": ["shirt", "nike sneakers"],
  "maxItems": 250,
  "onlyOnSale": true,
  "sort": "discount"
}
```

There is no start-URL input. A search page URL (`ajio.com/search/?text=shirt`) is
the same search as the term `shirt`, so use the term. AJIO's category pages
(`/men-shirts/c/830216013`) are filters on a listing, not a search, and no
parameter of the search API was found that reproduces them reliably, so they are
not offered.

### Output

Prices are numbers in rupees; `currency` is `INR` on every record measured.

| Field | Notes |
|---|---|
| `query` | The search term that first found the product. |
| `product_id`, `url` | AJIO's 12-digit product code (`463292672001`) and the product page link. |
| `name`, `brand` | As AJIO shows them. `brand` is null if AJIO sends none. |
| `price` | The **selling price**, the headline price on the product page. |
| `original_price` | The **MRP**, the struck-through figure. Equal to `price` when the product is not reduced. |
| `on_sale`, `discount_percent` | `on_sale` is true when `price` is below `original_price`. `discount_percent` is AJIO's own badge ("69% off" gives `69`). It is **null when the product is not reduced**, never 0. |
| `price_after_coupon` | The price after the best coupon AJIO applies to the listing. Equal to `price` when the coupon saves nothing. See below. |
| `coupon_status` | AJIO's `couponStatus` as sent (`Coupon Applicable`). |
| `gender`, `category`, `product_type` | How AJIO files the product: `Men` / `Western Wear` / `Shirts`. |
| `seller_id` | AJIO's seller id. Null on products AJIO sells itself. |
| `image_url` | The listing photo. |

Example row (real values, 2026-10-16):

```json
{
  "query": "shirt",
  "product_id": "463292672001",
  "name": "Men Textured Slim Fit Shirt with Patch Pocket",
  "brand": "THE BEAR HOUSE",
  "url": "https://www.ajio.com/the-bear-house-men-textured-slim-fit-shirt-with-patch-pocket/p/463292672_purple",
  "image_url": "https://assets.ajio.com/medias/sys_master/root/20230620/f0G5/649219dd42f9e729d758a303/the_bear_house_purple_men_textured_slim_fit_shirt_with_patch_pocket.jpg",
  "currency": "INR",
  "price": 773.0,
  "original_price": 2495.0,
  "on_sale": true,
  "discount_percent": 69.0,
  "price_after_coupon": 541.0,
  "coupon_status": "Coupon Applicable",
  "gender": "Men",
  "category": "Western Wear",
  "product_type": "Shirts",
  "seller_id": null
}
```

#### What the three prices mean

AJIO's search records carry three prices with unhelpful names. Which is which was
checked against 470 records of one search and against a product page:

- **`price`** (AJIO's `price`) is the figure the product page prints as its
  headline price: Rs. 1,099 for one CAHOOT shirt, 17 times in the page.
- **`original_price`** (`wasPriceData`) is the MRP the page strikes through,
  Rs. 1,999 there. It is on every record, and equal to `price` on the ones that
  are not reduced (80 of the 470), so `on_sale` is false for those.
- **`discount_percent`** (`discountPercent`) is the MRP markdown rounded to a
  whole percent, and absent exactly where `price` equals `original_price`.
  1,099 against 1,999 reads 45%; 150 against 1,999 is 92.5% and reads 93%.
- **`price_after_coupon`** (`offerPrice`) is the price after the best coupon.
  The same product's page lists the code `NEW30`, "Get Flat 30% off upto 500",
  and 1,099 less 30% is the 769 in the record. It is below `price` on 333 of the
  470 records and equal on the other 137; never above. A coupon can be limited to
  new customers or need a minimum basket, so treat it as the best case, not what
  every buyer pays. It is not a reduction: `on_sale` ignores it.

#### Honest nulls

A field AJIO did not send is `null`, never `0` or `""`. `discount_percent` is
null for every product that is not reduced. `seller_id` is null on products AJIO
sells itself (266 of 470 records).

- **No rating, review count, size or stock.** The search records carry none of
  them, so the rows do not either.

### Pricing

Pay per event:

- **$0.002** per run (`actor-start`), charged only after your input is
  validated, so a run that fails on bad input costs nothing.
- **$0.00104** per product row written (`product-scraped`), i.e. $1.04 per
  1,000 products. A row that is not written is not charged: rows filtered by
  `onlyOnSale`, and repeats of a product another term already returned, are free.

### How it fetches

It calls the JSON API behind ajio.com's own search page. Measured 2026-10-16:
HTTP 200 JSON from a plain home connection and, earlier the same day, from an
Apify datacenter address, with no key or cookie. A refusal (403, 429, 5xx), a 200
that is not a search answer, or a dropped connection is treated as the address
being blocked, and the actor rotates to a fresh one and retries.

Things worth knowing, all measured:

- **100 products per page.** A page size of 101 or more is answered with an
  empty `{}` body and HTTP 200, so the actor asks for 100.
- **Sorts are checked.** AJIO accepts a sort code it does not know and silently
  returns relevance order. The actor compares the order AJIO says it applied with
  the one you chose and fails (at no charge) rather than bill rows in the wrong
  order. The price and discount sorts follow AJIO's own index: over 134 rows
  sorted by price low to high, one record sat out of order.
- **The result set moves.** The number of matches for "shirt" read 54,920,
  54,918 and 54,915 within minutes, and two consecutive pages fetched separately
  shared 11 products. A run never returns a product twice, but a very long walk
  can miss one that shifted between pages. Run again for a fresh read.
- **The search does not end where it says it does.** Past the last page AJIO
  keeps answering products (mostly the last page again) instead of an empty
  list. The actor stops at the page count AJIO reports and when a page brings
  nothing new.
- **Depth.** At most 10,000 products per term. A page that AJIO answers with
  `{}` is retried from a fresh address and, if it keeps failing, is recorded as a
  failure while the rows already read are kept.
- **Not offered.** AJIO's facet filters (brand, size, price range, colour) and
  its category pages are not wired into this actor. Narrow the search with the
  term instead (`nike sneakers`, `women cotton kurta`).

# Actor input Schema

## `searchTerms` (type: `array`):

What you would type into the AJIO search box, one term per line (for example shirt, nike sneakers or cotton kurta). Each term is read separately and in full, page by page. A product that two terms both find is returned once, under the first.

## `maxItems` (type: `integer`):

Read at most this many products for each search term. AJIO lists 100 per page in this actor, so 250 reads three pages. Up to 10,000 are accepted.

## `onlyOnSale` (type: `boolean`):

Return only products whose selling price is below the MRP (the on_sale field). Products that are not reduced are read but not returned and not charged, and do not count toward Max products. A coupon price is not a reduced price; read price_after_coupon for that.

## `sort` (type: `string`):

The order AJIO lists the products in, the same choices as its own sort menu. 'Relevance' is its default. The price and discount sorts follow AJIO's own index, which can place a product slightly out of strict order.

## `proxyConfiguration` (type: `object`):

Use Apify's automatic datacenter proxy (the default). ajio.com answered an Apify datacenter address with its search JSON when this actor was built; the residential group was not needed. A refused request is retried from a fresh address.

## Actor input object example

```json
{
  "searchTerms": [
    "shirt"
  ],
  "maxItems": 100,
  "onlyOnSale": false,
  "sort": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# 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 = {
    "searchTerms": [
        "shirt"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/ajio-products").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 = {
    "searchTerms": ["shirt"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/ajio-products").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 '{
  "searchTerms": [
    "shirt"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/ajio-products --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superslowsloth/ajio-products"
        }
    }
}
```

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/SScdiftVxxKbky0mw/builds/46YPHOaLp01A0sxXN/openapi.json
