# 🇮🇳 India Government Tenders — GeM & CPPP (`nexgendata/gem-tenders-india`) Actor

India government tenders from CPPP eProcurement (incl. GeM) — title, organisation, value, dates, bid links. Watch mode for new tenders.

- **URL**: https://apify.com/nexgendata/gem-tenders-india.md
- **Developed by:** [NexGenData](https://apify.com/nexgendata) (community)
- **Categories:** Developer tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🇮🇳 India Government Tenders — GeM & CPPP eProcurement Scraper

Live **central and state government tenders from India's CPPP eProcurement portal** (`eprocure.gov.in`) — the government-run aggregator that carries the same central/state tenders as the departmental portals **and a dedicated GeM (Government e-Marketplace) bids slice**. Every row comes back as a clean **tender record** with a decoded tender id, the organisation, published / closing / opening dates, corrigendum status, and a working detail URL. Built for contractors, bid-management teams, GovTech products, and AI agents that need structured Indian public-procurement data without driving a JavaScript portal.

> Public procurement data, provided as-is for information purposes. Not affiliated with GeM, CPPP, NIC, or any government body.

### 📊 What you get

One record per tender (`source` chooses the slice):

- `tender_id` — decoded numeric tender id (base64-decoded from the detail path; a stable GeM hash on the GeM slice)
- `tender_ref_no` — the tender reference / GeM bid number
- `title` — tender title / product category
- `organisation` — issuing organisation (e.g. "Central Public Works Department (CPWD)")
- `published_date` — e-published / bid-start date
- `closing_date` — bid submission closing / bid-end date
- `opening_date` — tender opening date (central/state slice)
- `corrigendum` — corrigendum indicator
- `department` — department name (GeM slice)
- `detail_url` — absolute link to the full tender page on `eprocure.gov.in`
- `tender_value` — tender value (null in this fast listing path; on the detail page)
- `source`, `scraped_at`

#### Source slices

| `source` | Slice | Feed |
|---|---|---|
| `all` (default) | All active central + state tenders | `/cppp/latestactivetendersnew` |
| `gem` | GeM-branded bids | `/cppp/gemtender` |

### 💵 Pricing

Pay-per-result, no subscription:

| Event | Price |
|---|---|
| Actor start | $0.01 |
| **Tender record** | **$0.05 each** |
| Watch-check (per scheduled watch run) | $0.05 |

About **20 tenders per $1**.

**Worked example:** a pull of 50 active tenders = 1 start ($0.01) + 50 records ($2.50) = **$2.51**. A daily watch run that finds 4 new tenders = $0.05 watch-check + 4 × $0.05 = **$0.25**.

### 🧾 Sample output

```json
{
  "tender_id": "13956863",
  "tender_ref_no": "1000460298",
  "title": "PROCUREMENT OF PIPE FITTINGS FOR 131P137 SUCTION PIPING AT BPCL MUMBAI REFINERY",
  "organisation": "Bharat Petroleum Corporation Limited",
  "published_date": "17-Jul-2026 08:23 PM",
  "closing_date": "24-Jul-2026 02:00 PM",
  "opening_date": "24-Jul-2026 02:01 PM",
  "corrigendum": null,
  "department": null,
  "detail_url": "https://eprocure.gov.in/cppp/tendersfullview/MTM5NTY4NjM=A13h1...",
  "tender_value": null,
  "source": "all",
  "scraped_at": "2026-07-17T20:30:00Z"
}
```

### ⏰ Watch mode — new-tender alerts

Turn on **`watchMode`** and put the actor on a schedule. The first run seeds a baseline and emits nothing; every later run emits **only new tenders** since the last run (keyed on `tender_id`). Perfect for a standing "new CPWD / GeM tenders in my category" feed into Slack, a sheet, or an agent.

```json
{ "source": "all", "keyword": "road", "watchMode": true, "watchLabel": "highway-tenders" }
```

### 🤖 Use with AI agents

Returns clean JSON, so an agent can call it directly. Example task: *"Pull today's active CPWD tenders closing this month and summarize the ones over ₹1 crore."* Works with MCP tool-calling and agentic (x402) payment flows — no API key required.

#### API

```bash
curl -X POST "https://api.apify.com/v2/acts/nexgendata~gem-tenders-india/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"source":"all","keyword":"software","maxResults":25}'
```

#### CLI

```bash
apify call nexgendata/gem-tenders-india --input '{"source":"gem","maxResults":100}'
```

### 🔗 Related NexGenData actors

- **singapore-gebiz-tenders** — the same government-tender play for Singapore's GeBIZ (APAC sibling).
- **India Six** — the India public-data suite:
  - **nse-bse-announcements** — NSE/BSE corporate announcements & filings.
  - **mca-company-registry** — India company master data (CIN, directors, capital, status).
  - **india-startup-funding-tracker** — India startup funding rounds.
  - **india-trademark-search** — Indian trademark records.
  - **india-gst-verification** — GSTIN verification & taxpayer details.
  - **india-court-cases** — Indian court case records.

### ❓ FAQ

**Where does the data come from?** India's **CPPP eProcurement** portal (`eprocure.gov.in`), run by NIC — the central aggregator of government tenders, which includes a GeM-bids slice. To be clear: this is sourced from CPPP eProcurement (which carries GeM bids), **not** scraped from GeM's own portal (`gem.gov.in`) directly.

**Why CPPP instead of GeM directly?** GeM's own portal is browser/CSRF-gated and resets connections from datacenters. CPPP serves the same tenders as server-rendered HTML that is reachable reliably, so you get stable structured data.

**How fresh is it?** Real-time — tenders appear as CPPP publishes them; `published_date` is on every record.

**Does a blocked source bill me?** No. If CPPP is unreachable the run **fails loud** and charges nothing — you never pay for an empty "success". Reaching the end of the tender list is a clean empty result, not a failure.

**Can I filter?** Use the `keyword` filter (matched against title + organisation) and the `source` slice; `maxResults` caps the pull.

***

Data sourced from public CPPP eProcurement (`eprocure.gov.in`) government-tender listings, which include GeM bids. This actor is not affiliated with or endorsed by GeM, CPPP, NIC, or any government body. Public procurement data, provided as-is.

# Actor input Schema

## `source` (type: `string`):

Which CPPP eProcurement slice to pull. 'all' = every active central/state tender (latestactivetenders); 'gem' = the GeM-branded bids slice (gemtender).

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

Case-insensitive substring matched against the tender title + organisation (e.g. 'road', 'software', 'CPWD'). Leave empty for the full active-tender feed.

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

Maximum tender records to return (1-500). Pages are walked until this cap or the end of pagination.

## `watchMode` (type: `boolean`):

When on, the first run seeds a baseline and emits nothing; later runs emit only NEW tenders since the last run (keyed on tender\_id). Ideal on a schedule.

## `watchLabel` (type: `string`):

Names the watch baseline so multiple saved tasks keep independent state.

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

Optional. CPPP eProcurement answers cold from a datacenter, so a proxy is NOT required. Enable RESIDENTIAL (country IN) only as runtime hardening if you ever hit rate limits.

## Actor input object example

```json
{
  "source": "all",
  "maxResults": 50,
  "watchMode": false,
  "watchLabel": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "keyword": "",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgendata/gem-tenders-india").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 = {
    "keyword": "",
    "maxResults": 50,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("nexgendata/gem-tenders-india").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "keyword": "",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call nexgendata/gem-tenders-india --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nexgendata/gem-tenders-india",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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