Skip to main content
Thirdwatchthirdwatch
Compliance & registries

Find India Government Contracts by Department (2026 Guide)

Search India eProcure CPPP portal by department to find government contracts. Extract structured tender data filtered by ministry and organization. Python.

May 26, 2026 · 6 min read · 1,390 words
See the scraper →

Thirdwatch's India Government Tenders Scraper extracts department-filtered tender data from India's Central Public Procurement Portal with pay-per-result pricing. Search by organization name and keyword, pull structured metadata including tender IDs, reference numbers, departments, submission deadlines, and opening dates. Built for procurement researchers, policy analysts, and market intelligence teams studying India's government spending patterns at the department level. Supports cross-department comparison with consistent schema across all ministries and organizations on eProcure.

Why search government contracts by department

India's central government is organized into 58 ministries, 94 departments, and hundreds of attached offices, autonomous bodies, and public sector undertakings. According to the Controller General of Accounts, total central government expenditure exceeded INR 44 lakh crore (approximately $530 billion) in FY 2024-25, with a significant share flowing through procurement. Each department has distinct procurement patterns, preferred vendor categories, budget cycles, and compliance requirements.

For researchers and market intelligence teams, department-level segmentation is essential. A policy analyst studying digital governance spending needs to isolate MeitY, NIC, and NeGD tenders from the broader CPPP corpus. A defence industry consultant tracks Ministry of Defence and DRDO procurement for capability gap analysis. A construction market researcher segments CPWD, NHAI, and BRO tenders to forecast infrastructure spending by region. An academic studying procurement transparency compares tender volumes and submission windows across departments to identify efficiency variations.

The eProcure portal supports organization-based browsing but does not offer bulk export, time-series analysis, or cross-department comparison. Structured extraction fills this gap by putting department-level procurement data into a queryable format where researchers can aggregate, compare, and visualize patterns that are invisible in the portal's one-at-a-time browsing interface.

How does this compare to the alternatives?

Approach Department granularity Historical data Cross-department comparison Export format
eProcure portal browsing Single organization at a time Limited to active tenders Manual, side-by-side tabs None, screen only
RTI (Right to Information) requests Full, but delayed 30-45 days Historical available on request Requires separate requests PDF, often scanned
Open Government Data Platform (data.gov.in) Aggregated, not tender-level Annual or quarterly aggregates Pre-built dashboards CSV, API
Thirdwatch eProcure Scraper Any organization, keyword, or combination Live snapshot per run, build history over runs Same schema across all departments JSON, CSV, Excel

The India Government Tenders Scraper provides tender-level granularity with consistent schema across departments, enabling cross-department analysis that is not possible with aggregated government datasets or manual portal browsing.

How to find contracts by department in 5 steps

Step 1: How do I set up the extraction environment?

Install the Apify client and set your API token.

pip install apify-client pandas
export APIFY_TOKEN="apify_api_xxxxxxxxxxxxxxxx"

Step 2: How do I search tenders for a specific department?

Use the organization field to filter by department and queries to narrow by procurement category.

from apify_client import ApifyClient
import os

client = ApifyClient(os.environ["APIFY_TOKEN"])

# Target: Ministry of Electronics and IT
run = client.actor("thirdwatch/india-government-tenders-scraper").call(
    run_input={
        "queries": ["software", "cloud", "cybersecurity", "data centre"],
        "maxResults": 100,
        "organization": "Ministry of Electronics and Information Technology",
        "fetchDetails": True,
    }
)

meity_tenders = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(f"MeitY tenders: {len(meity_tenders)}")

Step 3: How do I extract tenders from multiple departments for comparison?

Run parallel extractions across target departments and tag each result set.

DEPARTMENTS = {
    "MeitY": {
        "organization": "Ministry of Electronics and Information Technology",
        "queries": ["IT services", "software", "cloud", "network"],
    },
    "Railways": {
        "organization": "Indian Railways",
        "queries": ["signalling", "rolling stock", "track maintenance", "IT systems"],
    },
    "Defence": {
        "organization": "Ministry of Defence",
        "queries": ["communication equipment", "vehicle", "ammunition", "clothing"],
    },
    "Health": {
        "organization": "All India Institute of Medical Sciences",
        "queries": ["medical equipment", "pharmaceuticals", "hospital supplies"],
    },
    "Roads": {
        "organization": "National Highways Authority of India",
        "queries": ["highway construction", "bridge", "toll plaza", "road maintenance"],
    },
}

department_data = {}
for dept_name, config in DEPARTMENTS.items():
    run = client.actor("thirdwatch/india-government-tenders-scraper").call(
        run_input={
            "queries": config["queries"],
            "maxResults": 100,
            "organization": config["organization"],
            "fetchDetails": True,
        }
    )
    items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
    department_data[dept_name] = items
    print(f"{dept_name}: {len(items)} tenders")

Step 4: How do I analyze procurement patterns across departments?

Aggregate the extracted data into a comparative analysis.

import pandas as pd
from datetime import datetime

all_records = []
for dept_name, items in department_data.items():
    for item in items:
        item["_department_group"] = dept_name
        all_records.append(item)

df = pd.DataFrame(all_records)

# Tender volume by department
volume = df.groupby("_department_group").size().reset_index(name="tender_count")
print("\nTender volume by department:")
print(volume.sort_values("tender_count", ascending=False).to_string(index=False))

# Parse deadlines for submission window analysis
def parse_deadline(d):
    try:
        return datetime.strptime(d, "%d-%b-%Y %I:%M %p")
    except (ValueError, TypeError):
        return None

def parse_published(d):
    try:
        return datetime.strptime(d, "%Y-%m-%d")
    except (ValueError, TypeError):
        return None

df["_deadline_dt"] = df["bid_submission_deadline"].apply(parse_deadline)
df["_published_dt"] = df["published_date"].apply(parse_published)
df["_window_days"] = (df["_deadline_dt"] - df["_published_dt"]).dt.days

# Average submission window by department
window_stats = df.groupby("_department_group")["_window_days"].agg(
    ["mean", "median", "min", "max"]
).round(1)
print("\nSubmission window (days) by department:")
print(window_stats.to_string())

Step 5: How do I export department-level data for reporting?

Export to CSV and Excel for sharing with stakeholders who do not work in Python.

from pathlib import Path

output_dir = Path("department_analysis")
output_dir.mkdir(exist_ok=True)

# Per-department CSV files
for dept_name, items in department_data.items():
    dept_df = pd.DataFrame(items)
    dept_df.to_csv(output_dir / f"{dept_name.lower().replace(' ', '_')}_tenders.csv",
                   index=False)

# Combined Excel workbook with one sheet per department
with pd.ExcelWriter(output_dir / "cross_department_tenders.xlsx") as writer:
    for dept_name, items in department_data.items():
        dept_df = pd.DataFrame(items)
        dept_df.to_excel(writer, sheet_name=dept_name[:31], index=False)

# Summary sheet
summary = pd.DataFrame([
    {"Department": dept, "Tenders": len(items),
     "Earliest Deadline": min((t.get("bid_submission_deadline", "Z") for t in items), default="N/A"),
     "Latest Deadline": max((t.get("bid_submission_deadline", "") for t in items), default="N/A")}
    for dept, items in department_data.items()
])
summary.to_csv(output_dir / "summary.csv", index=False)
print(f"\nExported to {output_dir}/")

Sample output

Three records from different departments showing the consistent schema across organizations.

[
  {
    "tender_title": "Design and Development of AI-based Grievance Classification System",
    "tender_id": "2026_MEITY_223344_1",
    "tender_reference_number": "MeitY/AI/2026/GRV-007",
    "organization": "Ministry of Electronics and Information Technology",
    "department": "Artificial Intelligence Division",
    "published_date": "2026-05-20",
    "bid_submission_deadline": "18-Jun-2026 05:00 PM",
    "tender_opening_date": "19-Jun-2026 11:00 AM",
    "detail_href": "https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page"
  },
  {
    "tender_title": "Supply of Track Maintenance Machines for South Central Railway",
    "tender_id": "2026_IR_SCR_556677_1",
    "tender_reference_number": "SCR/MEC/2026/TMM-041",
    "organization": "Indian Railways",
    "department": "South Central Railway - Mechanical",
    "published_date": "2026-05-17",
    "bid_submission_deadline": "10-Jun-2026 03:00 PM",
    "tender_opening_date": "11-Jun-2026 10:00 AM",
    "detail_href": "https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page"
  },
  {
    "tender_title": "Construction of Residential Quarters at DRDO Complex Hyderabad",
    "tender_id": "2026_DRDO_889900_1",
    "tender_reference_number": "DRDO/CE/2026/CIV-019",
    "organization": "Defence Research and Development Organisation",
    "department": "Ministry of Defence",
    "published_date": "2026-05-22",
    "bid_submission_deadline": "22-Jun-2026 02:00 PM",
    "tender_opening_date": "23-Jun-2026 03:00 PM",
    "detail_href": "https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page"
  }
]

The organization and department fields together provide two-level classification. organization is the publishing entity (which may be a ministry, department, PSU, or autonomous body). department provides sub-unit granularity where available. tender_reference_number follows each organization's internal numbering scheme, useful for cross-referencing with published annual procurement plans.

Common pitfalls

Three issues recur when building department-level procurement research datasets. Organization name inconsistency -- eProcure does not enforce standardized organization names. "Ministry of Electronics and Information Technology" may appear as "MeitY", "Min. of Electronics & IT", or other abbreviations across different tenders. Normalize organization names downstream using a mapping table rather than relying on exact string matching. Maintain a canonical name for each organization and map all variants. Overlapping department hierarchies -- a single tender may be published by a sub-unit (e.g., "NIC, Kerala State Centre") that does not match a parent-level organization filter ("National Informatics Centre"). Search at both the parent and sub-unit levels to ensure complete coverage. The queries field with broad keywords sometimes catches tenders that the organization filter misses due to naming variations. Snapshot vs. longitudinal confusion -- each scraper run captures active tenders at that moment, not a historical archive. Tenders that have closed between runs disappear from results. For longitudinal research, store every run's output with its timestamp and build the time-series from your accumulated snapshots. There is no way to retroactively retrieve expired tenders from eProcure.

For academic research, cite each data collection run with its date and input parameters. eProcure data is ephemeral by nature -- tenders disappear after closure -- so your accumulated dataset becomes the only record of the full tender lifecycle. The Open Government Data Platform provides aggregated procurement statistics that complement tender-level data for macro-level analysis.

Related use cases

Frequently asked questions

Which departments publish the most tenders on eProcure?

By volume, Indian Railways, CPWD (Central Public Works Department), and the Ministry of Defence consistently publish the highest number of tenders. Railways alone accounts for 15-20% of all CPPP listings. For IT and technology tenders specifically, MeitY, NIC, and UIDAI are the most active. For healthcare procurement, AIIMS campuses and CGHS publish regularly. Volume correlates with budget allocation -- departments with larger plan expenditure publish more frequently.

Can I track procurement patterns across departments over time?

Yes. Run the scraper weekly or monthly with the same organization filter and store results with timestamps. Over 6-12 months, you build a time-series of tender volume, average submission windows, common procurement categories, and seasonal patterns per department. This is particularly useful for policy researchers studying procurement efficiency and for vendors planning their bid capacity across the fiscal year.

Related

Try it yourself

100 free credits, no credit card.

About 30 real searches. Add the MCP to Claude or Cursor in two minutes.