# TradeIndia Suppliers Scraper (`scrapyx/tradeindia-suppliers-scraper`) Actor

Search TradeIndia's B2B supplier directory by product/service category and get every listed manufacturer — company name, location, business type, product details, and optionally full profile enrichment (address, GST number, owner, seller tier).

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

## Pricing

from $0.84 / 1,000 results

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

## TradeIndia Suppliers Scraper — B2B Directory

Search TradeIndia's B2B supplier directory by product/service category and
get every manufacturer listed — company name, location, business type,
product detail, and (optionally) full profile enrichment: address, GST
number, owner name, seller tier. No login, no cookies, no browser.

### Why this actor's shape differs from a normal search scraper

TradeIndia's `robots.txt` closes every pagination mechanism this actor
could otherwise use — query-string paging (`?page=`) is disallowed
site-wide, and the internal REST/catalog APIs a prior recon session found
are separately blocked (`/restapi/`, `/catalog_apis/`, `/ai-search/`). This
actor does not try to route around that. Each category keyword returns
**one page's worth of suppliers** (typically ~28) — an honest ceiling
reported on `CATEGORY_SUMMARY`, not implied to be a partial slice of a
larger reachable set.

**A plain slugified guess only matches TradeIndia's own category taxonomy
about 13% of the time** — "solar panels" isn't `solar-panels`, it's
`rec-solar-panels`; "cotton fabric" isn't `cotton-fabric`, it's
`raw-cotton-fabric`. So a category term that doesn't match directly falls
back to the site's own published sitemap (`sitemap_manufacturers_index.xml`
— robots.txt-endorsed, ~110,000 real category slugs) and resolves to the
best token-overlap match. This fallback loads once per run, lazily, only
if at least one term needs it.

### Why one actor, not "search" + "profile lookup" as separate actors

A category search naturally produces profile URLs, and a user who wants
company details (address, GST, owner) inlined shouldn't have to glue two
actor runs together. `enrichProfiles` is a checklist toggle on one
pipeline; `profileUrls` (direct profile input, skipping search) reuses the
same enrichment code path.

### What you get

#### `SUPPLIER`

| Field | Notes |
| --- | --- |
| `companyName`, `city`, `state`, `country`, `businessType` | |
| `establishedYear`, `memberSinceYears` | **Not the same thing** — `memberSinceYears` is a duration ("11 years on TradeIndia"), not a year or date |
| `categoryName`, `productName`, `productDescription`, `priceRange` | |
| `profileUrl`, `productUrl` | |
| `numberMasked` | Always `true` for unauthenticated visitors — TradeIndia's own privacy gate, not something this actor bypasses. Present so you know not to expect a working phone field, rather than reading a silent `None` as a scrape failure. |

With `enrichProfiles: true` (or via `profileUrls`), also: `address`,
`gstNumber`, `ownerName`, `designation`, `catalogDomain`, `intro`,
`sellerTier`.

#### `CATEGORY_SUMMARY` — one per category term

`rowsOnPage` (the honest per-category ceiling), `profilesEnriched`,
`finalUrl`, and `notes` — including whether the sitemap fallback had to
resolve your term to a different real slug.

#### `ERROR` — one per input that failed

### Known limits

- **~28 suppliers per category term.** This is TradeIndia's own per-page
  batch with no policy-compliant way to reach a second page (see above).
  Search several related keywords to broaden coverage instead of expecting
  deep pagination on one.
- **Phone numbers are always masked** for unauthenticated access — a
  TradeIndia privacy feature, not an extraction gap.
- **This host rate-limits hard by IP.** Recon burned through a local dev
  IP's budget after ~40-50 requests in a few minutes; TLS-profile rotation
  alone did not clear the block, a different exit IP did. Residential proxy
  is the default for exactly this reason — not a generic caution, load-
  bearing for this specific host.

### Proxy

Residential is the default and matters more here than on most targets in
this portfolio — see "Known limits" above.

# Actor input Schema

## `categories` (type: `array`):

Product or service keywords to search, e.g. "led lights", "solar panels", "cotton fabric". Each one becomes a TradeIndia category page and returns every supplier listed on it (typically ~28). This actor deliberately does not paginate past that first page — TradeIndia's own robots.txt disallows query-string pagination (?page=) site-wide, so this is the honest ceiling per category, not a bug. Search several related keywords to broaden coverage instead.

## `profileUrls` (type: `array`):

Fetch specific supplier profiles directly (skips category search). Paste full profile URLs, e.g. https://www.tradeindia.com/zaral-electricals-6707422/ — found in the profileUrl field of a category search result.

## `enrichProfiles` (type: `boolean`):

For each supplier found via 'categories', also fetch their profile page for address, GST number, owner name and seller tier — one extra request per supplier. Phone numbers stay masked either way (TradeIndia's own privacy gate for unauthenticated visitors, not something this actor bypasses).

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

How many category/profile pages fetch in parallel.

## `minRequestInterval` (type: `integer`):

Politeness pacing applied to request STARTS across all workers. 0 disables pacing.

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

Residential proxy is the default, though no WAF was observed during recon (6-profile TLS ladder, all clean).

## Actor input object example

```json
{
  "categories": [
    "led lights"
  ],
  "enrichProfiles": false,
  "maxConcurrency": 5,
  "minRequestInterval": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One row per scraped record. See the dataset's default view for field definitions.

# 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 = {
    "categories": [
        "led lights"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapyx/tradeindia-suppliers-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 = { "categories": ["led lights"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapyx/tradeindia-suppliers-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 '{
  "categories": [
    "led lights"
  ]
}' |
apify call scrapyx/tradeindia-suppliers-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapyx/tradeindia-suppliers-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/rkaAVnXGPGeWR6NHm/builds/86wZ4q0v2nkCc0SE6/openapi.json
