# IndiaMART Scraper — Suppliers, Products, Prices & GST (`tortuga/indiamart-scraper`) Actor

Scrape IndiaMART products and suppliers from any keyword, category or product URL: price and unit, MOQ, specifications, supplier company, city, TrustSEAL/GST badges, ratings and images.

- **URL**: https://apify.com/tortuga/indiamart-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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

## IndiaMART Scraper

Scrape IndiaMART, India's largest B2B marketplace, from any keyword, category or product URL: product title, price and unit (INR), minimum order quantity (MOQ), specifications, images, product video and brochure, plus the supplier's company name, city and state, TrustSEAL and GST-verified badges, business type, years on IndiaMART, rating, rating count, response rate and public IndiaMART business phone number. Filter by Indian city. Turn on **Include product details** to also get all specifications, the full description, packaging, delivery time, production capacity and the supplier profile (year established, employees, annual turnover, legal status, GST registration and the GST number printed on the product page).

Built for reliability: plain HTTP with browser TLS fingerprinting, no headless browser, no login. IndiaMART loads its listings as JSON, so the scraper reads structured data instead of fragile CSS selectors. You pay only for the products you get.

See also: [Alibaba Scraper](https://apify.com/tortuga/alibaba-scraper) and [Made-in-China Scraper](https://apify.com/tortuga/made-in-china-scraper), with the same input and output format for side-by-side supplier sourcing.

### What data does IndiaMART Scraper extract?

Every product from a search or category page:

| Field | Description |
|---|---|
| `productId` | IndiaMART product display ID (the number at the end of the product URL) |
| `title` | Product title |
| `url` | Clean product URL (`https://www.indiamart.com/proddetail/...-<id>.html`, tracking parameters removed) |
| `price` | Unit price as a number (`null` when the supplier shows "Ask Price") |
| `priceMin`, `priceMax` | Lowest and highest price when a range is shown (equal to `price` otherwise) |
| `priceText`, `currency`, `priceUnit` | Price as displayed (`₹ 190/Piece`), `INR`, and the unit (Piece, Kg, Meter, ...) |
| `moq`, `moqUnit` | Minimum order quantity and its unit (search results; with details also from product pages that show it) |
| `attributes` | Key specifications from the listing as `{name: value}` (brand, wattage, material, size, ...) |
| `description` | Short product description |
| `imageUrl`, `images` | Main image (1000x1000 when available); all images with details |
| `videoUrl`, `brochureUrl` | Product video (YouTube) and PDF catalogue when the supplier uploaded one |
| `category`, `categoryId` | IndiaMART category (e.g. Bluetooth Speaker) |
| `isMoreFromSupplier` | `true` for the extra products IndiaMART groups under a supplier ("more from this seller") |
| `supplier.name`, `supplier.id`, `supplier.url`, `supplier.website` | Company name, IndiaMART supplier ID, IndiaMART catalogue page and own website |
| `supplier.city`, `supplier.state`, `supplier.address`, `supplier.country` | Business location as listed |
| `supplier.isTrustSeal` | TrustSEAL verified (paid, document-verified supplier) |
| `supplier.isGstVerified` | GST registration verified by IndiaMART |
| `supplier.isVerifiedExporter`, `supplier.isIecVerified` | Verified exporter / Import-Export Code badges when shown |
| `supplier.membershipTier` | Listing tier on category pages (STAR, LEADER, TSCATALOG, CATALOG) |
| `supplier.businessType` | Manufacturer, Wholesaler, Exporter, Retailer, ... |
| `supplier.memberSince`, `supplier.yearsOnPlatform` | Date joined (search results) and years on IndiaMART |
| `supplier.rating`, `supplier.ratingCount` | Supplier rating (0-5) and number of buyer ratings |
| `supplier.responseRate` | Share of buyer calls the supplier answers, in percent |
| `supplier.phone` | The supplier's public IndiaMART business number (the call-forwarding number printed on the listing) |
| `listingType`, `position`, `page` | Where the item came from (`search`, `category` or `product`), its position and page |
| `searchTerm`, `city`, `sourceUrl`, `continuedInCategory`, `scrapedAt` | Which input produced the item and the run timestamp |
| `changeType`, `previousValues` | Only with **Only new or changed items** on: `new` or `changed`, and for changed products the old values of the fields that changed |

With **Include product details** on, each item also gets:

| Field | Description |
|---|---|
| `attributes` | All specifications from the product page |
| `images` | All product images in 1000x1000 |
| `categoryPath` | Category breadcrumb (group > parent category > category) |
| `packagingDetails`, `deliveryTime`, `productionCapacity` | Packaging, delivery and capacity as the supplier filled them in |
| `paymentTerms`, `portOfDispatch` | Payment terms and dispatch port when given |
| `supplier.businessType`, `supplier.additionalBusiness` | Nature of business and additional business types |
| `supplier.yearEstablished`, `supplier.employees`, `supplier.annualTurnover`, `supplier.legalStatus` | Company profile: founding year, employee range, turnover band (e.g. `Rs. 25 - 50 Crore`), legal form |
| `supplier.gstRegistrationYear`, `supplier.gstBusinessType`, `supplier.gstAnnualTurnover`, `supplier.gstLegalStatus` | GST registration facts shown on the page |
| `supplier.gstNumber` | The supplier's GSTIN exactly as the product page prints it ("Verified GST Number", e.g. `09AACCE7191F1ZI`); `null` when the page does not show one. Search and category pages show only the GST badge, so listing-only items have `null` |
| `supplier.exportCountries`, `supplier.logo` | Top export countries and company logo |
| `isAvailable`, `detailError` | `false` + `"product not available"` when the product page has been removed (listing data is kept, no detail charge) |

### How to use IndiaMART Scraper

1. Enter one or more **Search terms** (e.g. `bluetooth speaker`, `cotton fabric`, `led bulb`), or paste **Start URLs**: category pages (`https://dir.indiamart.com/impcat/bluetooth-speaker.html`), city category pages (`https://dir.indiamart.com/mumbai/bluetooth-speaker.html`), search pages or single product pages.
2. Optionally set a **City** (e.g. `Mumbai`, `New Delhi`) to get only suppliers located there.
3. Set **Max items** and **Max pages per search** to cap the run (and the cost).
4. Optionally switch on **Include product details**.
5. Click **Start**. Results appear in the **Dataset** tab; export as JSON, CSV or Excel, or read them through the API.

### Input example

```json
{
  "searchTerms": ["bluetooth speaker", "led bulb"],
  "startUrls": [{ "url": "https://dir.indiamart.com/impcat/cotton-fabric.html" }],
  "city": "Mumbai",
  "maxItems": 300,
  "maxPagesPerSearch": 5,
  "includeDetails": false,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "IN" }
}
```

### Output example

```json
{
  "productId": "2858662389273",
  "title": "Kt 125 Bluetooth Speaker",
  "url": "https://www.indiamart.com/proddetail/kt-125-bluetooth-speaker-2858662389273.html",
  "price": 190,
  "priceText": "₹ 190/Piece",
  "currency": "INR",
  "priceUnit": "Piece",
  "moq": 50,
  "moqUnit": "Piece",
  "attributes": { "Output Power": "5 W", "Battery Backup": "Up to 4 hrs", "Bluetooth Version": "v3.0", "Color": "Black" },
  "imageUrl": "https://5.imimg.com/data5/SELLER/Default/2026/2/582004540/PM/JW/CK/107414898/kt-125-bluetooth-speaker-1000x1000.jpg",
  "videoUrl": "https://youtu.be/gVLGjEbgQI4?si=gLzSeYkMuPjg5-C0",
  "category": "Bluetooth Portable Speaker",
  "isMoreFromSupplier": false,
  "supplier": {
    "id": "114957172",
    "name": "Revox24",
    "url": "https://www.indiamart.com/revox/",
    "website": "https://www.revox24.in/",
    "city": "New Delhi",
    "state": "Delhi",
    "country": "IN",
    "isTrustSeal": true,
    "isGstVerified": true,
    "businessType": "Wholesaler",
    "memberSince": "2020-06-14",
    "yearsOnPlatform": 6,
    "rating": 4.2,
    "ratingCount": 1087,
    "responseRate": 90,
    "phone": "+91-8047649336",
    "gstNumber": null
  },
  "listingType": "search",
  "position": 1,
  "page": 1,
  "searchTerm": "bluetooth speaker"
}
```

### How much does it cost?

Pay per result: a small price per product from a search or category page, plus a small extra per product when **Include product details** is on (one extra page fetch each). No subscription; Apify's free plan is enough to try it. Proxy traffic is billed separately by Apify (see the proxy note below); a typical 1,000-product run without details uses well under 100 MB.

### How many results can I get from an IndiaMART search?

IndiaMART shows anonymous visitors only the first page of a keyword search (10 suppliers, about 35 products including each supplier's other matching products); further search pages need a login. When you ask for more, the scraper automatically continues in the IndiaMART category that best matches your keyword (e.g. "bluetooth speaker" -> the Bluetooth Speaker category with 17,000+ products), where pages load without login. IndiaMART stops each category listing after about 500 suppliers (18 pages, roughly 1,000-1,500 products counting the grouped "more from this supplier" products). To go further, run the category for several cities (`city` input or `https://dir.indiamart.com/<city>/<category>.html` URLs) - each city has its own listing. Items say where they came from in `listingType`; switch off **Continue in matching category** to keep keyword-search results only.

### How do I scrape IndiaMART suppliers in one city?

Set **City** to the city name (`Pune`, `Ahmedabad`, `New Delhi`, ...). Search terms are then filtered to suppliers located in that city, and category URLs are opened in their city version (`https://dir.indiamart.com/pune/led-bulb.html`). You can also paste city category URLs directly.

### Does it work without login? Why the Indian proxy?

Yes, everything comes from public pages IndiaMART serves to anonymous visitors; no account or cookies are used. IndiaMART serves its domestic category listings only to visitors in India (other countries get an error or the smaller export site), and rate-limits busy IP addresses on product pages. The default proxy is therefore Apify **residential proxy with country India**. Apify bills residential traffic per GB: a search page is about 0.8 MB, a category page 0.1-0.3 MB and a product page 50-90 KB. Keyword search page 1 also works with datacenter proxies if you only need the first ~35 products per keyword and set **Max pages per search** to 1.

### Can I get supplier phone numbers and emails from IndiaMART?

The scraper returns company-level business data: company name, city, address as listed, website, IndiaMART catalogue URL and the public IndiaMART business number shown on the listing (a call-forwarding number IndiaMART assigns to the business). With **Include product details** it also returns the supplier's GST number as printed on the product page (`supplier.gstNumber`). It does not return mobile numbers that IndiaMART hides behind "View Mobile Number" / login, email addresses (IndiaMART does not show them) or contact-person / proprietor names: IndiaMART's current product, search and category pages do not display a contact person's name, so there is nothing to export (the name exists only in the page's hidden data, which the scraper does not use).

### Monitor changes on a schedule

Turn on **Only new or changed items** and the scraper remembers what earlier runs of the same input returned: each run outputs only products that are new or whose price or minimum order quantity changed. Unchanged products are dropped before anything is saved or any product page is opened, so they are not charged. Save the input as a task (for example one keyword, optionally with a city, and **Max items** 35: the products of the search page are checked every run), then add a Schedule to it in Apify Console (Schedules → Create new, e.g. daily or weekly). Every output product carries `changeType` (`new` or `changed`), and changed ones carry `previousValues`, e.g. `{"price": 190, "moq": 50}`. Keep the window within the search page: the category listing a search continues into is shuffled by IndiaMART on every visit, so deeper windows report reshuffled products as new. **Monitoring key** keeps several schedules on the same search separate.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets. Schedule it to monitor prices, MOQs or new suppliers for your keywords.

### Is it legal to scrape IndiaMART?

This Actor collects only data IndiaMART shows publicly to signed-out visitors: product listings, prices, MOQs, ratings and company information, including the GST number printed on product pages. It does not collect anything behind a login, "View Mobile Number" (click-to-reveal) numbers, email addresses, contact-person names or photos, or values that exist only in hidden page data. Note that for sole proprietorships the GSTIN contains the proprietor's PAN, so treat it as personal data where applicable. You are responsible for how you use the data and for complying with IndiaMART's terms and applicable law (including India's DPDP Act).

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

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

Keywords to search on IndiaMART, one per line (e.g. "bluetooth speaker", "cotton fabric"). The first page of the keyword search returns about 35 products (10 suppliers plus their other matching products). IndiaMART only shows further search pages to logged-in users, so if you want more, the scraper continues in the keyword's best-matching IndiaMART category (see 'Continue in matching category').

## `startUrls` (type: `array`):

IndiaMART URLs to scrape instead of (or in addition to) search terms: category pages (https://dir.indiamart.com/impcat/bluetooth-speaker.html), city category pages (https://dir.indiamart.com/mumbai/bluetooth-speaker.html), search pages (https://dir.indiamart.com/search.mp?ss=led+bulb\&cq=pune) or single product pages (https://www.indiamart.com/proddetail/...-2859389548233.html, returned with full details).

## `city` (type: `string`):

Optional Indian city to restrict results to suppliers located there (e.g. "Mumbai", "New Delhi", "Ahmedabad"). Applies to search terms and to /impcat/ category URLs. Leave empty for all of India.

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

Stop after this many products in total (across all search terms and URLs). Keeps cost predictable.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to open per search term or category URL. A category page holds 28 products plus 'more from this supplier' cards (about 60-100 products per page); IndiaMART stops category listings after about 500 suppliers (18 pages). For search terms, page 1 is the keyword search and pages 2+ come from the matching category.

## `continueInCategory` (type: `boolean`):

IndiaMART requires a login for keyword-search page 2+. When this is on and you want more products than the first search page has, the scraper continues in the IndiaMART category that best matches your keyword (e.g. 'bluetooth speaker' -> Bluetooth Speaker category, 17,000+ products). Items say where they came from in `listingType` (search / category). Turn off to get keyword-search results only.

## `includeDetails` (type: `boolean`):

Also open every product page to get all specifications, the full description, all images, packaging details, delivery time, production capacity, payment terms, port of dispatch and the supplier profile (nature of business, year established, employees, annual turnover, legal status, GST registration year and turnover band, export countries). Slower and charged extra per product (see pricing).

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this search returned and output only new items or items whose price/status changed. Use with a Schedule; unchanged items are not charged. With this on, Max items is the number of products checked each run (the watched window, e.g. the first 35 search results), so a run never digs deeper than the first one. The price and the minimum order quantity are compared; product pages are only opened for new or changed products. Keep the window within the search page (about 35 products): the category listing it continues into is ordered differently on every visit.

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input.

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

IndiaMART serves its category listings only to Indian IP addresses (other IPs get HTTP 429), so the default is Apify residential proxy in India. Keyword search page 1 and product pages also work through datacenter proxies. Residential traffic is billed by Apify per GB; a search page is about 0.8 MB, a category page about 0.1-0.3 MB, a product page about 50-90 KB.

## Actor input object example

```json
{
  "searchTerms": [
    "bluetooth speaker"
  ],
  "startUrls": [],
  "maxItems": 100,
  "maxPagesPerSearch": 10,
  "continueInCategory": true,
  "includeDetails": false,
  "onlyNewOrChanged": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IN"
  }
}
```

# Actor output Schema

## `results` (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": [
        "bluetooth speaker"
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "IN"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/indiamart-scraper").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": ["bluetooth speaker"],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "IN",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/indiamart-scraper").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": [
    "bluetooth speaker"
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IN"
  }
}' |
apify call tortuga/indiamart-scraper --silent --output-dataset

```

## MCP server setup

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

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/i6hbKYmCRga0qHBs2/builds/pOw5LAVYd2Nyji52Z/openapi.json
