# PhilGEPS PH Tender Leads Scraper (`leafy-dev-jr/philgeps-tender-leads-scraper`) Actor

Find relevant PhilGEPS bid opportunities before they close. Get budgets, agencies, contacts, and closing dates. Ready to export, monitor, or automate.

- **URL**: https://apify.com/leafy-dev-jr/philgeps-tender-leads-scraper.md
- **Developed by:** [Leafy](https://apify.com/leafy-dev-jr) (community)
- **Categories:** Lead generation, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## PhilGEPS Tender Leads Scraper

**Find relevant Philippine government tenders before the deadline.** Search public PhilGEPS opportunities by keyword and receive structured leads with the buyer, budget, closing date, delivery area, contact details, and full notice information—ready to export, monitor, or send into your sales workflow.

Stop repeatedly checking PhilGEPS by hand. Run one search for the products and services you sell, then schedule the Actor to build a fresh opportunity feed every day or week.

### What you get

Each result is one clean, deduplicated tender lead. Depending on what PhilGEPS publishes, records can include:

- Tender title, category, and description
- Procuring agency and area of delivery
- Reference and solicitation numbers
- Approved budget for the contract
- Publication date, closing date, and days remaining
- Procurement mode and classification
- Contact person, email, and phone number
- Public document links and the original PhilGEPS notice URL
- Keywords that matched the opportunity

Missing information is returned as `null`—the Actor does not guess or manufacture lead data.

### Who this Actor is for

- **Suppliers and distributors** looking for government buyers that need their products
- **Contractors and service providers** searching for active projects in their category
- **Sales and business development teams** building targeted public-sector lead lists
- **Procurement analysts and researchers** tracking demand, budgets, agencies, and deadlines
- **Teams creating tender alerts** for specific products, services, industries, or locations

### Popular use cases

- Monitor tenders for products such as solar equipment, laptops, medical supplies, or vehicles
- Discover construction, consulting, security, cleaning, catering, and other service opportunities
- Create daily or weekly keyword-based tender alerts
- Export qualified opportunities for review in a spreadsheet or CRM
- Track public procurement activity by agency, category, budget, or deadline

### Input example

```json
{
  "keywords": ["solar"],
  "location": "South Cotabato",
  "scrapeAllMatches": false,
  "maxResults": 100
}
````

#### Input options

| Field | Description |
| --- | --- |
| `keywords` (optional) | Products, services, or project terms to search for. Each term is searched separately, then results are combined and deduplicated. Keyword searches return matching tenders of any age. Prefilled with `solar` for an immediate trial run — replace it with terms relevant to your business, or **leave it empty to browse the whole open-opportunities listing** (see below). |
| `location` (optional) | City, province, region, or delivery area. Only tenders connected to it are kept. Matches agency, delivery area, title, category, and description. Leave empty to include every location. |
| `scrapeAllMatches` | On: collect every open tender for your search with no result cap. Off: stop at `maxResults`. Full tender details are collected either way. Default: `false`. |
| `maxResults` | Maximum tenders to return when `scrapeAllMatches` is off. Ignored when it is on. Default: `100`; maximum: `1000`. |
| `debugMode` | Enable detailed troubleshooting logs. Does not change your results. Default: `false`. |

> **Note:** When you run without keywords, results are automatically limited to tenders published in the last 30 days. This is a built-in safeguard for the very large full listing and is not configurable. Keyword searches are never date-limited.

### Output example

```json
{
  "title": "Supply, Delivery, Installation, Testing, and Commissioning of Off-Grid Solar Photovoltaic Systems",
  "agency": "DEPARTMENT OF SCIENCE AND TECHNOLOGY - REGION XII",
  "category": "Electrical Systems and Lighting Components",
  "publishDate": "2026-06-12",
  "closingDate": "2026-07-31T10:00:00+08:00",
  "daysUntilDeadline": 28,
  "isExpired": false,
  "referenceNumber": "13055012",
  "solicitationNumber": "DOST XII-2026-019",
  "approvedBudget": "PHP 25,700,000.00",
  "areaOfDelivery": "South Cotabato",
  "procurementMode": "Public Bidding",
  "classification": "Goods",
  "contactPerson": "Publicly listed contact person",
  "contactEmail": "public-contact@example.gov.ph",
  "contactPhone": "Publicly listed phone number",
  "documentUrls": [],
  "detailUrl": "https://notices.philgeps.gov.ph/...",
  "matchedKeywords": ["solar"],
  "source": "PhilGEPS",
  "scrapedAt": "2026-07-03T15:00:12.844Z"
}
```

Results are saved to the default Apify dataset and can be downloaded or connected to your automation workflow. A `SUMMARY` record is also saved in the key-value store with pages scraped, rows found, detail-page results, duplicates skipped, errors, and final output count.

### Get better results

- Use specific buyer language such as `solar`, `IT equipment`, `security services`, or `road construction`.
- Add related keyword variations because PhilGEPS searches each supplied term separately.
- Add a location when you only want opportunities connected to a city, province, region, or delivery area.
- Use the maximum-results setting for quick monitoring runs, or enable all-matches mode for complete keyword coverage.
- Schedule focused searches daily for time-sensitive categories, or weekly for market research.

The Actor deduplicates opportunities that appear under multiple keywords and merges their `matchedKeywords` values.

#### Scrape every matching open opportunity

Enable `scrapeAllMatches` to collect every open opportunity returned for your keywords instead of stopping at the normal result or page limits. This can be a long-running job for broad terms because every public tender detail page is collected automatically.

#### Browse every open tender (no keywords)

Leave `keywords` empty to skip keyword filtering entirely and browse the full PhilGEPS open-opportunities listing. This is useful for a broad market sweep, but it returns far more records than a focused search, so runs take longer:

Keyword-less runs are automatically limited to tenders published in the last 30 days because the full listing is very large (see below).

- **Keywords empty + `scrapeAllMatches` off** — returns a capped sample of the latest open tenders (up to `maxResults`, last 30 days).
- **Keywords empty + `scrapeAllMatches` on** — scrapes every open tender from the last 30 days without a result cap. This is the most complete run and also the longest, and it collects every tender's detail page.

Add a `location` to keep an unkeyworded sweep focused on a specific area.

#### Keeping runs bounded

To avoid runaway scrapes, every run is bounded:

- **30-day recency safeguard (keyword-less runs only)** — when no keywords are supplied, the Actor keeps only tenders published in the last 30 days and stops paging once it reaches older ones. This is a fixed backend safeguard for the very large full listing; it is not a user setting and never applies to keyword searches.
- **`maxResults`** — caps the number of tenders when `scrapeAllMatches` is off.
- **Page ceiling** — even with `scrapeAllMatches` on, the listing crawl stops after a fixed maximum number of pages, so a portal that never ends its pagination can't page forever.

The `SUMMARY` record includes `dateFilteredSkipped` (tenders dropped for being outside the 30-day window) and `recencyLimitDays` (the window used, or `null` for keyword searches).

Location filtering is applied after detail extraction, so it can use the published area of delivery and description as well as list-level fields.

### Reliability and limitations

PhilGEPS uses legacy ASP.NET pages, so the Actor relies on visible labels, tender-link patterns, dates, and pagination text instead of fragile generated element IDs. Navigation failures are retried, and a failed detail page does not discard the tender found in the listing.

Results depend on PhilGEPS availability and the completeness and accuracy of information published by procuring entities. CAPTCHA, rate limits, malformed dates, temporary portal errors, or future website changes can affect a run. Public document URLs are returned only when exposed on the notice page.

Always confirm important requirements, deadlines, eligibility rules, and documents on the original PhilGEPS notice before preparing a bid.

### Legal and ethical use

This Actor only collects publicly visible PhilGEPS information. It does not require a login or bypass authentication, CAPTCHA, paywalls, or access restrictions. Use reasonable schedules and crawl delays, and follow PhilGEPS terms and applicable laws.

### Contact / feedback

Bug reports, feature requests, and use-case tips welcome — email the developer at leafydevjr@gmail.com.

# Actor input Schema

## `keywords` (type: `array`):

Products, services, or project terms to look for on PhilGEPS. Add each term separately — every term is searched on its own, then the results are combined and deduplicated (e.g. solar, IT equipment, road construction). Keyword searches return matching open tenders of any age. Leave this empty to instead browse the whole open-opportunities listing — because that listing is very large, keyword-less runs are automatically limited to tenders published in the last 30 days (this limit never applies when you provide keywords).

## `location` (type: `string`):

Only keep tenders connected to this city, province, region, or delivery area. Matched against the agency, area of delivery, title, category, and description. Leave empty to include every location.

## `scrapeAllMatches` (type: `boolean`):

On: collect every open tender for your search, with no result cap. Off: stop at the maximum set below. Full tender details are collected either way. With no keywords, runs only cover tenders published in the last 30 days because the full listing is very large.

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

The most tenders to return in a single run. Applies only when "Scrape every matching tender" is off — it is ignored when that switch is on.

## `debugMode` (type: `boolean`):

Turn on only when troubleshooting — it adds detailed diagnostic logs but does not change your results.

## Actor input object example

```json
{
  "keywords": [
    "solar"
  ],
  "location": "Cebu",
  "scrapeAllMatches": false,
  "maxResults": 100,
  "debugMode": false
}
```

# Actor output Schema

## `tenderLeads` (type: `string`):

Structured PhilGEPS opportunities produced by this run.

## `runSummary` (type: `string`):

Run statistics, keyword coverage, and captured errors.

# 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 = {
    "keywords": [
        "solar"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leafy-dev-jr/philgeps-tender-leads-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 = { "keywords": ["solar"] }

# Run the Actor and wait for it to finish
run = client.actor("leafy-dev-jr/philgeps-tender-leads-scraper").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 '{
  "keywords": [
    "solar"
  ]
}' |
apify call leafy-dev-jr/philgeps-tender-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=leafy-dev-jr/philgeps-tender-leads-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "PhilGEPS PH Tender Leads Scraper",
        "description": "Find relevant PhilGEPS bid opportunities before they close. Get budgets, agencies, contacts, and closing dates. Ready to export, monitor, or automate.",
        "version": "1.0",
        "x-build-id": "s9fdcXR9UjbDJzhue"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/leafy-dev-jr~philgeps-tender-leads-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-leafy-dev-jr-philgeps-tender-leads-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/leafy-dev-jr~philgeps-tender-leads-scraper/runs": {
            "post": {
                "operationId": "runs-sync-leafy-dev-jr-philgeps-tender-leads-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/leafy-dev-jr~philgeps-tender-leads-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-leafy-dev-jr-philgeps-tender-leads-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "keywords": {
                        "title": "Search keywords",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Products, services, or project terms to look for on PhilGEPS. Add each term separately — every term is searched on its own, then the results are combined and deduplicated (e.g. solar, IT equipment, road construction). Keyword searches return matching open tenders of any age. Leave this empty to instead browse the whole open-opportunities listing — because that listing is very large, keyword-less runs are automatically limited to tenders published in the last 30 days (this limit never applies when you provide keywords).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "location": {
                        "title": "Location filter (optional)",
                        "type": "string",
                        "description": "Only keep tenders connected to this city, province, region, or delivery area. Matched against the agency, area of delivery, title, category, and description. Leave empty to include every location."
                    },
                    "scrapeAllMatches": {
                        "title": "Scrape every matching tender",
                        "type": "boolean",
                        "description": "On: collect every open tender for your search, with no result cap. Off: stop at the maximum set below. Full tender details are collected either way. With no keywords, runs only cover tenders published in the last 30 days because the full listing is very large.",
                        "default": false
                    },
                    "maxResults": {
                        "title": "Maximum number of tenders",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "The most tenders to return in a single run. Applies only when \"Scrape every matching tender\" is off — it is ignored when that switch is on.",
                        "default": 100
                    },
                    "debugMode": {
                        "title": "Debug logging",
                        "type": "boolean",
                        "description": "Turn on only when troubleshooting — it adds detailed diagnostic logs but does not change your results.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
