# India Government Tenders — CPPP, GeM & State Portals (`foxlabs/india-government-tenders`) Actor

Live Indian government tenders from CPPP, GePNIC state portals and GeM: tender ID, title, organisation, category, EMD, tender value, location, deadlines, documents and a link that opens the tender. Plus GeM bid results with every seller's rank (L1, L2 …) and price.

- **URL**: https://apify.com/foxlabs/india-government-tenders.md
- **Developed by:** [Berkan Kaplan](https://apify.com/foxlabs) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 tender records

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

## India Government Tenders — CPPP, GeM & State Portals 🏛️

**foXLabs procurement series:** [EU TED Tenders](https://apify.com/foxlabs/ted-tenders) · [World Bank Tenders](https://apify.com/foxlabs/worldbank-tenders) · [Ukraine ProZorro Tenders](https://apify.com/foxlabs/ukraine-prozorro-tenders) · [IDB Tenders](https://apify.com/foxlabs/iadb-tenders) · [Indian Company Data](https://apify.com/foxlabs/indian-company-data)
**foXLabs India series:** [Company registry](https://apify.com/foxlabs/indian-company-data) · [NSE filings](https://apify.com/foxlabs/india-listed-company-filings) · [Tech hiring signals](https://apify.com/foxlabs/india-tech-hiring-signals) · [IndiaMART suppliers](https://apify.com/foxlabs/indiamart-supplier-data)

🎉 Turn India's public procurement portals into clean, structured tender data — no login, no API key, one row per tender with the tender ID, title, buyer organisation, category, EMD, tender value, location and PIN code, deadlines, document names and a link that opens the tender. Plus GeM bid results: every seller's rank (L1, L2 …) and price.
Built for suppliers and MSMEs selling to Indian government buyers, tender-alert and bid-management services, and procurement analysts.

### 🔍 What is India Government Tenders — and when should you use it?

Pick the portals, add optional filters — keyword, buyer organisations, category, publish window, closing deadline — and the actor reads the portals' public, captcha-free pages live, opens each matching tender for its full record and returns clean, deduplicated rows you can filter, export or feed to an AI agent.

What it reads (sizes seen on 10 September 2026):

- **CPPP** — the Central Public Procurement Portal's merged feed of every central portal: 27,839 active tenders (list fields).
- **eprocure.gov.in** — 2,469 active tenders from 238 organisations, with the full tender record.
- **etenders.gov.in** — 1,866 active tenders from 84 organisations, full record.
- **tntenders.gov.in** (Tamil Nadu) — 6,085 active tenders from 76 organisations, full record.
- **GeM** (Government e-Marketplace) — 35,490 open bids through the CPPP mirror; with an Indian residential proxy also GeM's own bid search and its bid results.

**Use it when you need:** a daily feed of new central-government tenders with EMD and deadlines; every active tender of a list of buyer organisations; tenders in a category that close in the next two weeks; or GeM bid results — who bid, who came L1, at what price.

**Use something else when:** you need award notices from CPPP or the GePNIC portals (captcha-protected — not covered), Maharashtra's portal (its robots.txt forbids crawling — not covered), or firmographics of the winning sellers — pair the award rows with [Indian Company Data](https://apify.com/foxlabs/indian-company-data).

### 🤖 Use with AI agents

**Already on the Apify MCP server?** Ask for this Actor by name: `foxlabs/india-government-tenders`.

**Your agent can pay for its own runs.** This Actor is pay-per-event with agentic payments, so an agent can discover it, run it and settle the bill over **x402 (USDC on Base)** or **Skyfire** — no Apify account or API token of its own. Billing is the same either way: per delivered tender or award row; the summary row is never charged.

Otherwise paste this into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```
I want to pull Indian government tenders using the Apify Actor `foxlabs/india-government-tenders`.
Input: `sources` picks the portals (cppp_all, eprocure, etenders_gov, tntenders, gem_mirror, gem_live); `mode` is list_detail, list or awards; optional `keyword`, `organisation` (one name per line), `category`, `datePreset`, `closingWithinDays`; `maxResults` caps the rows.
Start with: {"sources":["cppp_all","eprocure"],"mode":"list_detail","datePreset":"last_7_days","maxResults":10}
Ask me what to look up, run the Actor, then summarise the rows as a table.
```

Things you can ask your agent for:

- "List this week's new central-government tenders with EMD and closing date."
- "Find IT tenders on eprocure and etenders that close in the next 14 days."
- "Show every active tender of AIIMS Jodhpur, Tezpur University and GAIL Gas."
- "Who won the latest GeM bids, and at what price?" (needs the Indian residential proxy)

The machine-readable API, MCP config and OpenAPI definition live at `apify.com/foxlabs/india-government-tenders.md`.

### 📋 Overview

Everything you need to turn CPPP, the GePNIC state and central portals and GeM into clean, structured data — in one actor, with no login, cookies or API key.

**Why teams pick this actor:**

- ✅ **The full tender record** — EMD, category, location and PIN code, critical dates, inviting authority and document names on every detail row of the default run; tender value where the portal publishes one (52% of detail rows in our test run; otherwise `null`).
- 🔗 **Links that open** — every GePNIC and GeM live row carries a `tenderUrl` that opens that tender in a fresh session with no cookies (13 of 13 checked), not the portal's session-bound link.
- 🏆 **GeM bid results** — every seller with rank (L1 to L8 seen) and total price: competitor and price intelligence.
- 🧹 **One row per tender** — a tender listed by two portals is delivered once, and repeats from overlapping CPPP pages are dropped; 100% unique rows in every test run.
- 🧾 **Says why when it finds little** — an empty or short run ends with a summary row and a per-source report, never silently.
- 💰 **Pay only for results** — per delivered tender or award row; the summary row is never charged.
- 🤖 **Agent-ready** — MCP + x402 agentic payments.

### ✨ Features

- 🗂️ **Six sources, one schema** — CPPP, three GePNIC portals, the GeM mirror and GeM live all fill the same row shape.
- 🔍 **Filters** — keyword, buyer organisations (one per line), category, publish window (24 h / 7 d / 30 d / custom / any), closing within N days.
- 🧭 **Category search that knows the portals' words** — the actor reads each portal's own category list; `IT` covers Information Technology, Info. Tech. Services and Computer H/W, S/W and Data Processing, and never matches "Items". Tenders whose titles look like the category are opened first, and the GePNIC portals are read at the same time.
- 💱 **Indian money, four ways** — every amount as raw text, currency, compact (₹34.71 L) and exact (₹34,71,143).
- 🕒 **Clean dates** — ISO 8601 in Indian time (+05:30) everywhere.
- 📊 **Run report** — `SOURCE_REPORT` in the key-value store: rows, requests, bytes, pages scanned and duplicates per source.

### 🎬 Quick Start

```bash
curl -X POST "https://api.apify.com/v2/acts/foxlabs~india-government-tenders/runs?token=YOUR_TOKEN" -H "Content-Type: application/json" -d '{"sources":["cppp_all","eprocure"],"mode":"list_detail","datePreset":"last_7_days","maxResults":10}'
```

This is the default input: in our test it returned 100 rows — 50 full records from eprocure.gov.in and 50 CPPP feed rows — in 4 min 37 s, with the first rows after about 20 seconds.

### 🚀 Getting Started (3 steps)

1. **Choose the portals** — keep the default (CPPP + eprocure) or add etenders, tntenders and GeM.
2. **Filter** — a keyword, your target organisations, a category or a closing deadline; set `maxResults`.
3. **Run and export** — a clean dataset as JSON, CSV or Excel, plus the run report.

### 📥 Input

```json
{"sources":["cppp_all","eprocure"],"mode":"list_detail","keyword":"","organisation":"","category":"","datePreset":"last_7_days","maxResults":10}
```

| Field | Type | Description |
|---|---|---|
| `sources` | array | Portals to read: `cppp_all`, `eprocure`, `etenders_gov`, `tntenders`, `gem_mirror`, `gem_live`. Default CPPP + eprocure. |
| `mode` | string | `list_detail` (default, full record), `list` (list fields only, far fewer requests) or `awards` (GeM bid results). |
| `keyword` | string | Title, reference number or tender ID contains this text. On GeM live it is GeM's own full-text search. |
| `organisation` | string | Buyer organisations, one per line (a name contains the text). On GePNIC only those organisations are visited. |
| `category` | string | Portal category words, e.g. `Civil Works - Roads`, `Medicines`, `IT`. Several: separate with `\|`. |
| `datePreset` | string | Published within `last_24_hours`, `last_7_days` (default), `last_30_days`, `custom` or `any`. In `awards` mode: the bid end date. |
| `dateFrom` / `dateTo` | string | Custom window, `YYYY-MM-DD`, Indian time. |
| `closingWithinDays` | integer | Only tenders still open and closing within N days. |
| `maxResults` | integer | Total row cap, shared across sources (default 500; `0` = unlimited). The GePNIC portals are read at the same time; one that finds fewer leaves its share to the others. |
| `maxScanPages` | integer | Scan limit per source: list pages, organisation lists and — with a category — tender pages that did not match (default 50). |
| `requestDelayMs` | integer | Politeness delay (default 800 ms; GeM always gets at least 1,000 ms). |
| `maxConcurrency` | integer | Pages fetched at once on each GePNIC portal — organisation lists and tender pages (default 2, max 3). A portal never gets more than one new request per second; GeM is read one request at a time. |
| `proxyConfiguration` | object | Default: Apify proxy, automatic. For `gem_live` and `awards`: Residential, country India (IN). |

#### Example inputs (measured in our test runs)

| Goal | Input | Result |
|---|---|---|
| This week's tenders (default) | `{"sources":["cppp_all","eprocure"],"mode":"list_detail","datePreset":"last_7_days","maxResults":10}` | 10 rows (5 with the full GePNIC detail), 8 requests, 36 s on the Apify platform (run haUUFI2nD1HTbYrpX) |
| IT tenders closing within 14 days | `{"sources":["eprocure","etenders_gov"],"mode":"list_detail","category":"IT","datePreset":"any","closingWithinDays":14,"maxResults":10,"maxScanPages":20}` | 10 rows, 53 requests, 1 min 42 s — both portals read at the same time |
| GeM bids for a keyword | `{"sources":["gem_live"],"mode":"list","keyword":"CCTV","datePreset":"any","maxResults":10,"proxyConfiguration":{"useApifyProxy":true,"apifyProxyGroups":["RESIDENTIAL"],"apifyProxyCountry":"IN"}}` | 10 rows, 2 requests, 11 s, 29.6 KB of residential traffic |
| GeM bid results | `{"sources":["gem_live"],"mode":"awards","datePreset":"last_7_days","maxResults":22,"proxyConfiguration":{"useApifyProxy":true,"apifyProxyGroups":["RESIDENTIAL"],"apifyProxyCountry":"IN"}}` | 22 seller rows from 6 bids, 8 requests, 34 s, 182 KB of residential traffic |

Every active tender of twenty buyer organisations (list mode) — 58 rows, 22 requests, 2 min 10 s:

```json
{"sources":["eprocure","etenders_gov"],"mode":"list","organisation":"All India Institute of Medical Sciences-Jodhpur\nAssam University Silchar\nCentral University of Tamil Nadu\nCentre for Development of Telematics\nHindustan Organic Chemicals Limited\nIndian Institute of Management Lucknow\nInstitute for Plasma Research\nNavodaya Vidyalaya Samiti\nOffice of the CAG of India\nTezpur University\nSemi-Conductor Laboratory (SCL)\nNational Institute of Technology Kurukshetra\nAnushakti Vidhyut Nigam Limited (ASHVINI)\nEngineering Projects (India) Ltd.\nGAIL Gas Limited\nMumbai Metro Rail Corporation Limited\nNational Fertilizers Limited\nNational Informatics Centre Services Incorporated\nVadhvan Port Project Limited\nYantra India Limited","datePreset":"any","maxResults":0}
```

### 📤 Output

One row per tender (`recordType: "tender"`) or, in `awards` mode, one row per participating seller (`recordType: "award"`). Missing values are `null`, never an empty string.

**Tender rows**

| Field | Filled by | Description |
|---|---|---|
| `tenderId` | all sources | The portal's tender ID (GeM: bid number) |
| `referenceNo` | GePNIC, CPPP | The buyer's reference number |
| `title` | all sources | Tender title (GeM: item or BOQ title; CPWD tenders on CPPP show their reference number here) |
| `description` | GePNIC detail | Work description, only when it says more than the title |
| `organisation` / `department` | all / GePNIC, GeM mirror | Buyer organisation and its sub-units |
| `ministry` | GeM live | Buyer ministry |
| `category` | GePNIC detail, GeM | Product category as the buyer filed it |
| `tenderCategory` / `tenderType` / `formOfContract` | GePNIC detail | Goods / Services / Works; open, limited or global tender; contract form |
| `quantity` | GeM | Total quantity |
| `location` / `pincode` / `state` | GePNIC detail | Work location, PIN code, and the state derived from the PIN code |
| `emdRaw` / `emdCurrency` / `emdCompact` / `emdExact` | GePNIC detail | Earnest money deposit (₹0 = no EMD asked) |
| `tenderValueRaw` / `…Currency` / `…Compact` / `…Exact` | GePNIC detail | Estimated tender value, when published |
| `publishedAt` / `bidSubmissionEndAt` / `openingAt` | all (opening: GePNIC, CPPP) | Critical dates, ISO 8601 +05:30. On GeM `publishedAt` is the bid start — a reverse auction can start after today |
| `preBidMeetingAt` / `bidValidityDays` / `periodOfWorkDays` | GePNIC detail | When the tender states them |
| `inviterName` / `inviterAddress` | GePNIC detail | Tender inviting authority (designation and office) |
| `documentNames` | GePNIC detail | Names of the tender documents (NIT, BOQ …) |
| `tenderUrl` | GePNIC, GeM live | A link that opens this tender (GeM: the bid document). `null` for CPPP and GeM-mirror rows |
| `portalUrl` | all sources | The portal page where the tender can be looked up by its ID |
| `portal` / `sourceName` / `scrapedAt` | all sources | Provenance and fetch time |

**Award rows** (`awards` mode): `bidNumber`, `bidId`, `bidType`, `category`, `organisation`, `department` (`null` when GeM gives none), `ministry`, `quantity`, `startDate`, `endDate`, `buyerStatus`, `sellerName`, `rank` (L1 = lowest price; rows are sorted by rank within each bid), `sellersInBid` (how many sellers the bid's result page lists), `totalPriceRaw` / `totalPriceCurrency` / `totalPriceCompact` / `totalPriceExact`, `qualified`, `mseStatus` (`MSE`, or `null`), `participatedOn`, `offeredItem`, `resultUrl` (the bid's result page), `tenderUrl` (the bid document), `portal`, `sourceName`, `scrapedAt`.

**Summary row** (`recordType: "summary"`): written only when a run is empty, a source failed, or the run stopped short of `maxResults` — `title`, `message`, `hint` and the per-source `sourceReport`. Never charged.

A real row from the default run:

```json
{"recordType":"tender","tenderId":"2026_AIIMB_925199_1","referenceNo":"AIIMS Bathinda/Engg./26-27/5781","title":"Tender for construction of Patient Attendant Waiting area and Medical record room on the terrace of LT Panel room, IPD, AIIMS Bathinda","description":null,"organisation":"All India Institute of Medical Sciences Bathinda","department":"Administration - AIIMS Bathinda","ministry":null,"portal":"eprocure.gov.in","sourceName":"GePNIC — eprocure.gov.in (Central Government e-Procurement)","category":"Civil Works","tenderCategory":"Works","tenderType":"Open Tender","formOfContract":"Works","quantity":null,"location":"AIIMS Bathinda","state":"Punjab","pincode":"151001","emdRaw":"70,000","emdCurrency":"INR","emdCompact":"₹70,000","emdExact":"₹70,000","tenderValueRaw":"34,71,143","tenderValueCurrency":"INR","tenderValueCompact":"₹34.71 L","tenderValueExact":"₹34,71,143","publishedAt":"2026-09-08T09:00:00+05:30","bidSubmissionEndAt":"2026-10-03T17:00:00+05:30","openingAt":"2026-10-05T09:00:00+05:30","preBidMeetingAt":"2026-09-15T11:00:00+05:30","bidValidityDays":270,"periodOfWorkDays":null,"inviterName":"Executive Director AIIMS Bathinda","inviterAddress":"AIIMS Bathinda, Mandi Dabwali road, Bathinda, Punjab 148101","documentNames":["Tendernotice_1.pdf","BOQ_972241.xls"],"tenderUrl":"https://eprocure.gov.in/eprocure/app?component=%24DirectLink&page=FrontEndViewTender&service=direct&sp=SzJs2BAp8RdaeETCaiif2Xg%3D%3D","portalUrl":"https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page","scrapedAt":"2026-09-10T14:10:57.969Z"}
```

A real award row:

```json
{"recordType":"award","bidNumber":"GEM/2026/B/7979113","bidId":9827185,"bidType":"Bid","category":"Booster,Battery pack for Tx and Rx each,12 V Battery with charger,Starter,Battery charger for Tx an","organisation":"Director General Of National Cadet Corps (dgncc)","department":"Department of Defence","ministry":"Ministry of Defence","quantity":160,"startDate":"2026-08-31T23:03:35+05:30","endDate":"2026-09-10T23:30:00+05:30","buyerStatus":"Bid Award","sellerName":"HANGAR-S","rank":"L1","sellersInBid":3,"totalPriceRaw":"₹ 297848.00","totalPriceCurrency":"INR","totalPriceCompact":"₹2.98 L","totalPriceExact":"₹2,97,848","qualified":true,"mseStatus":"MSE","participatedOn":null,"offeredItem":"Booster,Battery pack for Tx and Rx each,12 V Battery with charger,Starter,Battery charger for Tx an","portal":"gem","sourceName":"GeM — bidplus.gem.gov.in (bid results)","resultUrl":"https://bidplus.gem.gov.in/bidding/bid/getSinglePacketResultView/9827185","tenderUrl":"https://bidplus.gem.gov.in/showbidDocument/9827185","scrapedAt":"2026-09-10T15:04:47.055Z"}
```

### ⛔ Not covered

- **Award notices (AOC) on CPPP and the GePNIC portals** — they sit behind an image captcha; this actor never solves captchas.
- **mahatenders.gov.in (Maharashtra)** — its robots.txt says `Disallow: /`, so it is not read. Other state portals are not included yet.
- **GeM without an Indian IP** — GeM refuses non-Indian IPs; without a Residential proxy set to India, GeM sources stop after one attempt with a summary row that says so.
- **CPPP and GeM-mirror rows are list rows** — no EMD, category or value, and no per-tender link (the portal's own links expire within minutes and ask for a captcha); use `portalUrl` and the tender ID.
- **The documents themselves** — only their names are delivered.

### 💼 Use cases

**1. Daily tender alerts** — a supplier or MSME tracking new work from central buyers.
*Input:* `datePreset: last_24_hours` on a daily schedule. *Output:* new tenders with EMD, deadline and document names. *Use:* a morning bid-pipeline sheet.

**2. Account-based bidding** — every open tender of the buyers you already sell to.
*Input:* `organisation` with one buyer per line. *Output:* all their active tenders. *Use:* never miss a repeat buyer's tender.

**3. GeM price and competitor intelligence** — who wins your product category on GeM, and at what price.
*Input:* `mode: awards`, optionally a keyword or category, with the Indian residential proxy. *Output:* every seller's rank and price per bid. *Use:* price your next bid; join seller names with [Indian Company Data](https://apify.com/foxlabs/indian-company-data).

### 🔗 Integration

**JavaScript / Node.js**

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('foxlabs/india-government-tenders').call({"sources":["cppp_all","eprocure"],"mode":"list_detail","datePreset":"last_7_days","maxResults":10});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

**Python**

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('foxlabs/india-government-tenders').call(run_input={"sources":["cppp_all","eprocure"],"mode":"list_detail","datePreset":"last_7_days","maxResults":10})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

**Automation (n8n / Zapier / Make):** a daily schedule → HTTP request to the actor API with your filters → filter the JSON on `recordType: "tender"` → push new tender IDs to a sheet, CRM or Slack channel.

### 📊 Pricing

Pay-per-event, charged only for delivered rows: one `tender-record` event per list-level tender row (CPPP, GeM mirror, GeM live, and `list` mode), one `tender-detail-record` event per tender row read from the full GePNIC detail page (`list_detail` mode), and one `award-record` event per GeM seller row. Rows need a tender ID and a title, or a bid ID and a seller name, to be charged. The summary row is never charged. [View current pricing.](https://apify.com/foxlabs/india-government-tenders)

Platform usage — compute and proxy traffic — is included in the per-row price. The default proxy (automatic) is enough for CPPP, the GeM mirror and the GePNIC portals. `gem_live` and `awards` need Residential proxy traffic from India: in our test runs a 10-row GeM search moved 29.6 KB and 22 award rows moved 182 KB (response bytes; TLS overhead comes on top).

### ❓ FAQ

**Do I need an account, login or API key on the portals?** No. The actor reads public pages that the portals show to every bidder.

**Why is `tenderUrl` empty on CPPP rows?** CPPP's own tender links expire within minutes and then ask for a captcha, so there is no stable link to give. `portalUrl` points to the page where the tender can be looked up by its ID.

**Will the GePNIC links still work tomorrow?** In our checks 13 of 13 links opened the right tender in a fresh session with no cookies, and 2 of 2 links issued two hours earlier still did. How many days they stay valid has not been measured.

**How does a category search work?** A GePNIC portal shows a tender's category only on the tender page, and its search, classification, location and closing-date lists sit behind an image captcha (so does CPPP's search by product) — this actor never solves captchas. So it reads the organisations' tender lists, largest first, scores each title against the category and opens the tenders that look like it, to check the category the buyer picked. For `IT`, titles where a computer word stands in electrical work, supplies or lab equipment ("computer wiring", "printer cartridges", "3D printer") are opened only after the rest. Organisation lists and tender pages share the connections set by `maxConcurrency`, the portals are read at the same time, and `maxScanPages` caps the organisation lists plus tender pages without a match on each portal. Buyers also file many purchases under broad categories: in our IT test, computers and printers were filed under "Miscellaneous Goods" and a GPU purchase under "Electrical Goods/Equipment". The run log lists every tender skipped for its category; for wider coverage add a keyword search such as `computer`, `server` or `software`.

**Does CPPP repeat tenders?** Its pages overlap when many tenders share the same publish minute; the actor drops the repeats (18 of 70 CPPP rows in the default run) and keeps paging.

**What does L1 mean on a GeM result?** The lowest-priced seller among those who qualified. It is not proof that a contract was signed, and GeM masks the buyer's name on result pages. Seller rows are sorted by rank, L1 first. If `maxResults` stops a run in the middle of a bid, you keep its top-ranked sellers, and `sellersInBid` shows how many the bid had.

**How current is the data?** Every run reads the portals live. GeM notes that new bids can take up to 15 minutes to appear.

**Can I export to CSV / Excel / JSON?** Yes — directly from the Apify dataset.

### 🐛 Troubleshooting

- **A summary row instead of tenders** — read its `message` and `hint`: it says, per source, whether nothing matched, the scan limit was reached or the portal failed.
- **"GeM is only reachable from India — set proxy to Residential, country IN"** — set Proxy configuration to Residential with country India (IN).
- **"scan limit reached"** — raise `maxScanPages`, or narrow the search with organisations.
- **The organisation filter finds nothing** — use part of the name as the portal writes it (e.g. `Tezpur University`); the run log lists the matched organisations.

### ⚠️ Trademark

Independent tool. Not affiliated with, endorsed by or connected to the Government of India, the National Informatics Centre (NIC), the Central Public Procurement Portal, GePNIC, GeM (Government e-Marketplace) or any buyer listed. Names and marks are used for identification only.

### ⚖️ Is it legal to scrape this data?

This actor reads public procurement pages without logging in, skips every captcha-protected page and does not read sites whose robots.txt disallows crawling. The CPPP copyright policy allows reproduction with permission of the respective organisation and asks that the source be prominently acknowledged — every row carries `portal` and `sourceName` for that. GeM's website policy asks for written permission before its content is reproduced, so check that your use is covered. Rows can contain personal data such as an officer's designation or a sole proprietor's trade name; handle it under India's DPDP Act, the GDPR or similar law with a legitimate basis. See Apify's blog post on the legality of web scraping.

### 🤝 Support & contact

- 🌐 **Website:** [data.foxlabs.com.tr](https://data.foxlabs.com.tr)
- 📧 **Email:** info@foxlabs.com.tr
- 🐛 **Issues:** open a ticket in the Actor's **Issues** tab
- 🧰 **More clean B2B data actors:** [Fox Labs on Apify](https://apify.com/foxlabs)

### Changelog

#### 0.1.3 — 2026-09-10 — category search: faster and cheaper

- The GePNIC portals (eprocure, etenders, tntenders) are read at the same time instead of one after the other. The row budget is still shared: each portal starts with an equal share, and one that finds fewer leaves the rest to the others.
- On each portal, organisation lists and tender pages share the `maxConcurrency` connections (default 2); before, organisation lists were read one at a time. Requests to one portal still start at least 1 s apart.
- A category search opens fewer tender pages that cannot match: only titles that look like the category are opened while organisation lists are left to read; for `IT`, titles where a computer word stands in electrical work, supplies or lab equipment ("computer wiring", "printer cartridges", "3D printer"), or that come from an electrical, civil or estate department, are opened only after the rest; "data processing" and "workstation" now count as strong IT signs.
- Measured on the IT example (eprocure + etenders, closing within 14 days, 10 rows, scan limit 20) through the Apify proxy: 10 rows in 102 s (10.2 s per row), where the previous version needed 184–195 s for 6 rows (30.7–32.5 s per row); the 6 tenders it found are among the 10.
- No change to the input fields, the output fields or billing.

#### 0.1 — 2026-09-10 — initial release

- Award rows are sorted by rank (L1 first) and carry `sellersInBid`, so a run that stops at `maxResults` in the middle of a bid keeps its top-ranked sellers and shows how many there were.
- GeM placeholders (`NA`, `N/A`, `-`) in `ministry`, `department` and `mseStatus` are returned as `null`.
- Two tender events: `tender-record` for list-level rows and `tender-detail-record` for rows with the full GePNIC detail page; `award-record` for GeM results. Summary rows are never charged.
- The prefilled input asks for 10 rows: Indian portals answer Apify's servers several times slower than a local connection, and a 30-row default took 325 s on the platform.
- A run now stops scanning 90 s before its timeout and still saves the rows found and an explanatory summary row, instead of ending empty when the timeout hits.
- **Sources:** the CPPP "latest active tenders" feed (every central portal, list fields); the GePNIC portals eprocure.gov.in, etenders.gov.in and tntenders.gov.in through their captcha-free "Tenders by Organisation" pages, with the full tender page (EMD, tender value, category, location, PIN code, critical dates, inviting authority, document names); GeM open bids via the CPPP mirror; GeM live bids from bidplus.gem.gov.in (needs an Indian residential proxy).
- **Modes:** `list_detail` (default), `list`, and `awards` — GeM bid results with one row per seller: rank (L1, L2 …), total price as a 4-field money set, qualified flag, MSE status.
- **Filters:** keyword, organisations (one per line), category (the portals' own product categories; `IT` also covers their Information Technology, Info. Tech. Services and Computer categories), publish-date presets or a custom range, closing within N days, a row budget shared across sources and a scan limit per source.
- **Links that work:** `tenderUrl` opens the tender in a fresh session, no cookies needed. GePNIC links are delivered without the `session=T` flag that ties the portal's own links to one browser session; GeM rows link the bid document. CPPP and GeM-mirror rows get no per-tender link (the portal's own links expire within minutes and ask for a captcha) — they carry `portalUrl`, the page to look the tender up by its ID.
- **One row per tender:** a tender listed by two sources is delivered once (GePNIC tender IDs and GeM bid numbers are unique across portals); repeated rows from overlapping CPPP pages are dropped.
- **Run report:** every run stores `SOURCE_REPORT` (per source: status, rows, requests, wire bytes, pages scanned, duplicates, notes). An empty, failed or short run also gets a summary row that explains why, source by source; summary rows are never charged. Without an Indian proxy, GeM sources stop after one attempt with that explanation.
- **Pay-per-event:** `tender-record` for each tender row with a tender ID and a title; `award-record` for each award row with a bid ID and a seller name.
- **Not included:** award notices on CPPP and the GePNIC portals (captcha-protected) and mahatenders.gov.in (its robots.txt disallows crawling).

# Changelog

This Actor's version history is a separate document: https://apify.com/foxlabs/india-government-tenders/changelog.md

# Actor input Schema

## `sources` (type: `array`):

Which procurement portals to read. The GePNIC portals (`eprocure`, `etenders_gov`, `tntenders`) give the full tender record — EMD, tender value, category, location, PIN code, documents, inviting authority — plus a link that opens the tender. `cppp_all` is the Central Public Procurement Portal's merged feed of every central portal (list fields: ID, title, organisation, dates). `gem_mirror` is GeM's open-bid list as mirrored by CPPP (works from anywhere). `gem_live` reads GeM itself and **needs an Apify Residential proxy with country India** — GeM does not answer non-Indian IPs (measured residential traffic about 3 KB per bid row — roughly $0.02 per 1,000 rows at $8/GB). Sources with full records run first; a tender listed by two sources is delivered once.

## `mode` (type: `string`):

`list_detail` (default) opens each matching GePNIC tender for the full record — EMD, tender value, category, location, PIN code, documents, inviting authority. `list` stops at the list pages (far fewer requests, list fields only; a category filter still opens GePNIC tender pages, because the category is only shown there). `awards` switches to GeM **bid results**: one row per participating seller with rank (L1 = lowest price) and total price — needs the India residential proxy (measured about 8 KB of residential traffic per award row — roughly $0.07 per 1,000 rows at $8/GB).

## `keyword` (type: `string`):

Keep tenders whose title, reference number or tender ID contains this text (case-insensitive). On the GeM mirror it is matched against the product category and bid number (the mirror has no title); on GeM live it is sent to GeM's own full-text search (items, BOQ title, category, department, ministry, city). Examples: `CCTV`, `road`, `laptop`.

## `organisation` (type: `string`):

Keep tenders whose organisation, department or ministry contains one of these names (case-insensitive) — one name per line, e.g. `AIIMS`, `Railway`, `NHAI`. On the GePNIC portals only the matching organisations are visited, which makes the run much faster.

## `category` (type: `string`):

Keep tenders whose category contains these words — the portal's own product category on GePNIC (e.g. `Civil Works - Roads`, `Computer- H/W`, `Medicines`) and the product category on GeM. Words of 3 letters or fewer (like `IT`) match whole words only, so `IT` never matches `Items`; `IT` also covers the portals' `Information Technology`, `Info. Tech. Services` and `Computer- H/W`, `Computer- S/W`, `Computer- Data Processing` categories. Several categories: separate them with `|`. The category is only shown on the tender page, so GePNIC tenders are opened to check it, those whose titles look like the category first; CPPP list rows carry no category and are skipped when this is set.

## `datePreset` (type: `string`):

Time window on the tender's published date (bid start date on GeM). In `awards` mode it applies to the bid END date instead and is filtered by GeM itself.

## `dateFrom` (type: `string`):

Only used when "Published within" is `custom`. Inclusive, Indian time.

## `dateTo` (type: `string`):

Only used when "Published within" is `custom`. Inclusive, Indian time. Leave empty for today.

## `closingWithinDays` (type: `integer`):

Keep only tenders that are still open and whose bid submission deadline falls within the next N days (e.g. `14` for two weeks). Leave empty for no deadline filter.

## `maxResults` (type: `integer`):

Stop after this many rows in total. The budget is shared across the selected sources; a source that finds fewer leaves its share to the others (the GePNIC portals are read at the same time). `0` = unlimited (bounded only by the scan limit below).

## `maxScanPages` (type: `integer`):

Advanced. How many pages each source may read looking for matches: list pages on CPPP and GeM (10 tenders each), organisation lists on the GePNIC portals, and — with a category filter — GePNIC tender pages whose category did not match. Raise it for rare keywords or categories; lower it for quick runs. The run report says when this limit stopped a source.

## `requestDelayMs` (type: `integer`):

Politeness delay against the public portals (per connection). GeM is always given at least 1,000 ms and one request at a time.

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

How many GePNIC pages — organisation lists and tender pages — to fetch at once on each portal. 2 is polite; 1 is safest. Either way a portal gets at most one new request per second.

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

CPPP, the GeM mirror and the GePNIC portals work with the default Apify proxy (automatic). For `gem_live` or `awards` mode choose **Residential** with country **India (IN)** — GeM only answers Indian IPs. Measured residential traffic: about 3 KB per live bid row and 8 KB per award row (roughly $0.02 and $0.07 per 1,000 rows at $8/GB; TLS overhead not included). Without an Indian proxy the run stops within seconds with a summary row that says so.

## Actor input object example

```json
{
  "sources": [
    "cppp_all",
    "eprocure"
  ],
  "mode": "list_detail",
  "datePreset": "last_7_days",
  "maxResults": 10,
  "maxScanPages": 50,
  "requestDelayMs": 800,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "sources": [
        "cppp_all",
        "eprocure"
    ],
    "mode": "list_detail",
    "keyword": "",
    "organisation": "",
    "category": "",
    "datePreset": "last_7_days",
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": []
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("foxlabs/india-government-tenders").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 = {
    "sources": [
        "cppp_all",
        "eprocure",
    ],
    "mode": "list_detail",
    "keyword": "",
    "organisation": "",
    "category": "",
    "datePreset": "last_7_days",
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": [],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("foxlabs/india-government-tenders").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 '{
  "sources": [
    "cppp_all",
    "eprocure"
  ],
  "mode": "list_detail",
  "keyword": "",
  "organisation": "",
  "category": "",
  "datePreset": "last_7_days",
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}' |
apify call foxlabs/india-government-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,foxlabs/india-government-tenders"
        }
    }
}
```

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/BqbG5vdSaA1RPzPfn/builds/AizZtmzVsgdoJQQQH/openapi.json
