Skip to main content
Thirdwatchthirdwatch
Compliance & registries

Scrape India Government Tenders for Bid Tracking (2026)

Track live government tenders from India's eProcure CPPP portal with structured data. Automate bid discovery, filter by department, and never miss a deadline.

May 26, 2026 · 5 min read · 1,177 words
See the scraper →

Thirdwatch's India Government Tenders Scraper extracts live tender listings from India's Central Public Procurement Portal (eProcure CPPP) with pay-per-result pricing. Pull tender titles, reference numbers, organizations, deadlines, and detail links into structured JSON. Built for founders and operations leads at companies that bid on government contracts and need systematic discovery instead of manual portal browsing.

Why track India government tenders programmatically

India's Central Public Procurement Portal (CPPP) at eprocure.gov.in is the mandatory listing platform for central government tenders. According to the Ministry of Finance's 2024-25 procurement report, over 60,000 active tenders are listed at any given time across hundreds of departments, ministries, and public sector undertakings. According to the World Bank's India procurement assessment, India's public procurement spending exceeds 20% of GDP, making it one of the largest government procurement markets globally. For any company that bids on government work, manually checking the eProcure portal is a daily time sink that scales poorly.

The job-to-be-done is straightforward. A construction firm tracks CPWD and NHAI tenders for road and infrastructure projects. An IT services company monitors MeitY and NIC tenders for software development contracts. A medical supplies distributor watches AIIMS and state hospital tenders for equipment procurement. A defence contractor filters Ministry of Defence tenders by category. All of these reduce to the same workflow: query the portal daily, extract structured tender data, filter by relevance, and flag approaching deadlines before the submission window closes.

Manual checking fails at scale. With hundreds of new tenders published daily across dozens of departments, a human reviewer misses opportunities, discovers them too late, or wastes hours scrolling through irrelevant listings. Programmatic extraction solves this by delivering filtered, structured data to your inbox or dashboard every morning.

How does this compare to the alternatives?

Approach Reliability Setup time Maintenance Structured output
Manual eProcure portal browsing Human-dependent, inconsistent None Daily time investment No, copy-paste
Paid tender aggregation platforms (TenderTiger, BidAssist) High Days Subscription lock-in Partial, proprietary format
Custom scraper built in-house Variable Weeks Ongoing dev maintenance Yes, full control
Thirdwatch eProcure Scraper Production-tested 30 minutes Thirdwatch maintains extraction Yes, clean JSON

Paid aggregation platforms bundle tenders from multiple sources but charge monthly subscriptions regardless of volume and lock you into their interface. An in-house scraper gives full control but requires ongoing maintenance as the eProcure portal changes. The India Government Tenders Scraper gives you structured output with pay-per-result pricing and zero maintenance burden.

How to track government tenders in 5 steps

Step 1: How do I get my Apify API token?

Sign up at apify.com (free tier, no credit card required). Navigate to Settings, then Integrations, and copy your personal API token. All examples below assume the token is set as an environment variable:

export APIFY_TOKEN="apify_api_xxxxxxxxxxxxxxxx"

Step 2: How do I install the Apify Python client?

pip install apify-client

Step 3: How do I run a basic tender search?

Use the queries field to search for tenders by keyword and maxResults to control volume. The organization field narrows results to a specific department.

from apify_client import ApifyClient
import os

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

run = client.actor("thirdwatch/india-government-tenders-scraper").call(
    run_input={
        "queries": ["road construction", "highway maintenance"],
        "maxResults": 50,
        "organization": "National Highways Authority of India",
        "fetchDetails": True,
    }
)

items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(f"Found {len(items)} tenders")
for item in items[:3]:
    print(f"{item['tender_title']} | Deadline: {item['bid_submission_deadline']}")

Step 4: How do I filter tenders by approaching deadlines?

Post-process the results to flag tenders with submission deadlines within the next 7 days.

from datetime import datetime, timedelta

today = datetime.now()
cutoff = today + timedelta(days=7)

urgent = []
for item in items:
    deadline_str = item.get("bid_submission_deadline", "")
    if deadline_str:
        try:
            deadline = datetime.strptime(deadline_str, "%d-%b-%Y %I:%M %p")
            if today <= deadline <= cutoff:
                urgent.append(item)
        except ValueError:
            continue

print(f"\n{len(urgent)} tenders with deadlines in the next 7 days:")
for t in urgent:
    print(f"  {t['tender_title']}")
    print(f"  Org: {t['organization']} | Deadline: {t['bid_submission_deadline']}")
    print(f"  Ref: {t['tender_reference_number']}\n")

Step 5: How do I schedule daily automated runs?

Use the Apify scheduling API to trigger the scraper every morning.

schedule = client.schedules().create(
    name="daily-tender-check",
    cron_expression="0 7 * * *",  # 7:00 AM daily
    actions=[{
        "type": "RUN_ACTOR",
        "actorId": "thirdwatch/india-government-tenders-scraper",
        "runInput": {
            "queries": ["IT services", "software development", "cloud infrastructure"],
            "maxResults": 100,
            "fetchDetails": True,
        },
    }],
)
print(f"Schedule created: {schedule['id']}")

Sample output

Each record from the dataset contains the full tender metadata. Three rows of this shape weigh approximately 4 KB.

[
  {
    "tender_title": "Supply and Installation of Network Equipment for NIC Data Centre",
    "tender_id": "2026_NIC_812345_1",
    "tender_reference_number": "NIC/PROC/2026-27/NET-045",
    "organization": "National Informatics Centre",
    "department": "Ministry of Electronics and Information Technology",
    "published_date": "2026-05-20",
    "bid_submission_deadline": "15-Jun-2026 03:00 PM",
    "tender_opening_date": "16-Jun-2026 03:30 PM",
    "detail_href": "https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page"
  },
  {
    "tender_title": "Construction of 4-Lane Highway Bypass on NH-48 Karnataka Section",
    "tender_id": "2026_NHAI_887654_1",
    "tender_reference_number": "NHAI/PIU-BLR/2026/HW-112",
    "organization": "National Highways Authority of India",
    "department": "Ministry of Road Transport and Highways",
    "published_date": "2026-05-18",
    "bid_submission_deadline": "10-Jun-2026 05:00 PM",
    "tender_opening_date": "11-Jun-2026 11:00 AM",
    "detail_href": "https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page"
  },
  {
    "tender_title": "Annual Maintenance Contract for Medical Imaging Equipment at AIIMS Delhi",
    "tender_id": "2026_AIIMS_445566_1",
    "tender_reference_number": "AIIMS/STORES/2026/MED-089",
    "organization": "All India Institute of Medical Sciences",
    "department": "Ministry of Health and Family Welfare",
    "published_date": "2026-05-22",
    "bid_submission_deadline": "20-Jun-2026 02:00 PM",
    "tender_opening_date": "21-Jun-2026 10:00 AM",
    "detail_href": "https://eprocure.gov.in/eprocure/app?page=FrontEndTendersByOrganisation&service=page"
  }
]

tender_reference_number is the canonical identifier for cross-referencing with your internal bid management system. bid_submission_deadline is the critical field for deadline tracking. organization and department enable filtering and routing to the right internal team. detail_href links to the full tender document on eProcure for downloading specifications and bid documents.

Common pitfalls

Three issues surface repeatedly when building tender tracking workflows. Deadline timezone ambiguity -- eProcure displays deadlines in IST but does not include timezone markers in all formats. Always assume IST (UTC+5:30) when parsing bid_submission_deadline and convert to your local timezone before setting alerts. Stale results from infrequent scraping -- tenders with short submission windows (7-10 days) can expire between weekly runs. Daily scraping is the minimum viable cadence; twice-daily for time-sensitive categories like emergency procurement. Duplicate tenders across queries -- overlapping search terms (e.g., "road construction" and "highway construction") return the same tenders. Deduplicate on tender_id before inserting into your database to avoid double-counting and duplicate alerts.

The eProcure portal occasionally goes through maintenance windows during off-hours. Schedule runs during IST business hours (10 AM - 6 PM) for the most reliable extraction. Pair the tender scraper with a notification system (Slack webhook, email, or SMS) to ensure your bid team sees urgent opportunities within hours of publication rather than days.

Related use cases

Frequently asked questions

How often should I scrape eProcure for new tenders?

Daily scraping catches most new publications. CPPP publishes tenders throughout the day, but the bulk appear during IST business hours (10 AM - 6 PM). A daily morning run at 7 AM IST captures the previous day's publications and gives your team a full business day to evaluate and prepare bids before submission windows close.

Can I filter tenders by a specific government department?

Yes. The organization input field lets you filter by any publishing organization on eProcure, such as Indian Railways, CPWD, or Defence Ministry. This narrows results to only tenders from your target department, reducing noise and letting your team focus on relevant opportunities without manual sorting.

Related

Try it yourself

100 free credits, no credit card.

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