# Pakistan Tender Matcher: Score PPRA Tenders for Your Profile (`akramkhan/pakistan-tender-matcher`) Actor

Describe what you sell and get only the open Pakistani government tenders that fit, each scored 0-100 with the matching keywords listed.

- **URL**: https://apify.com/akramkhan/pakistan-tender-matcher.md
- **Developed by:** [Muhammad Akram Khan](https://apify.com/akramkhan) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 matched tenders

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

## Pakistan Tender Matcher: Score PPRA Tenders Against Your Profile

Get a short, scored list of the open Pakistani government tenders that fit your business. Describe what you supply in a few sentences. The Actor reads every active tender on the federal PPRA portal (EPMS), scores each one against your profile from 0 to 100, and returns only the best matches, with the words that matched.

No API key, no login, no setup. Results in about two minutes.

### What you get

- **Only the relevant tenders** out of the 2,000+ listed on the portal on a typical day
- **A score and the matched keywords** for each tender, so you can see why it matched
- **Closing date, days left, bid security, procurement procedure and opening time**
- **Direct links** to the tender page and the tender document PDF
- **Daily alerts:** schedule it and get only the tenders that are new since your last run

### Who it's for

- **Suppliers and contractors** who want a short daily list instead of scrolling through thousands of tenders
- **Bid consultants** tracking tenders for several clients (one scheduled run per client profile)
- **Sales and business-development teams** selling to government departments, defence, utilities and state companies

### How to use

1. Click **Try for free**.
2. In **Company profile**, write 2 to 10 sentences about what you supply: products, services, sectors, cities, certifications, past clients. Concrete product words ("laptops", "solar inverters", "lab chemicals") work best.
3. Optional: add **Must include** keywords (a tender must mention at least one) or **Exclude keywords**.
4. Click **Start**. A run takes about one to two minutes.

Example input:

```json
{
  "companyProfile": "We are an IT hardware supplier based in Islamabad and Lahore. We supply desktop computers, laptops, servers, networking equipment (switches, routers, firewalls), UPS and power backup, printers, scanners and CCTV systems to government departments, universities and hospitals. We are registered with FBR and SECP, hold authorised-dealer status for major brands, and have delivered similar supply contracts for provincial and federal organisations.",
  "maxMatches": 5
}
```

### Example output

Top 5 results for the input above, run on 17 October 2026:

| Score | Tender | Matched keywords |
| --- | --- | --- |
| 100 | TS0000015837E · Procurement of IT Equipment (Desktop, Color Printer, Laptop and Video Conference System) | desktop, laptops, printers, computers, systems, equipment |
| 85 | TS0000015106E · PROCUREMENT OF LAPTOPS, DESKTOP COMPUTERS, SERVERS AND HCI SOLUTION | desktop, servers, laptops, computers, equipment |
| 84 | TS0000015720E · Procurement of IT Equipment Laptops, Desktops, Printers and LED Monitors | desktop, laptops, printers, equipment |
| 83 | TS0000015578E · Computers & Printers / Laptops | laptops, printers, computers, equipment |
| 72 | TS0000015836E · TENDER FOR PROCUREMENT OF COMPUTER SYSTEMS, LAPTOP, PRINTERS, SCANNERS AND UPS FOR PNSC BUILDING | scanners, ups, laptops, printers, computers, systems |

One full result row:

```json
{
  "score": 100,
  "matchModeUsed": "keyword",
  "title": "Procurement of IT Equipment (Desktop, Color Printer, Laptop and Video Conference System)",
  "organisation": "Ministry of Defence Production",
  "portal": "federal_epms",
  "tenderNumber": "TS0000015837E",
  "closingDate": "2026-10-27T11:00+05:00",
  "daysLeft": 10,
  "matchedKeywords": [
    "desktop",
    "laptops",
    "printers",
    "computers",
    "systems",
    "equipment"
  ],
  "reason": null,
  "scopeSummary": null,
  "category": "Goods",
  "eligibilityHints": [],
  "redFlags": [],
  "detailUrl": "https://epms.ppra.gov.pk/public/tenders/tender-details/TS0000015837E",
  "documentUrl": "https://epms.ppra.gov.pk/pdf?file=dGVuZGVyX2F0dGFjaG1lbnRzL0NvbXBsZXRlX3RlbmRlcl9kb2N1bWVudHNfZm9yX0VQQURzXy1UVS01MTIzLTIwMjZfMS5wZGY=",
  "bidSecurityPkr": 50000,
  "bidSecurityPercent": null,
  "procedure": "Single Stage-Two Envelope",
  "openingTime": "11:30 AM",
  "isCorrigendum": false,
  "isUpdate": false
}
```

### How the score works

Each tender is scored on how strongly its wording overlaps your profile. Specific words ("servers", "inverter") count for more than common ones ("supply", "items").

The score is **relative to today's best match**: the strongest tender in the run scores 100, and the rest are measured against it. A minimum score of 60 means "at least 60% as strong a match as today's best". Scores can shift from day to day as tenders open and close. If no tender fits your profile well, none of them reaches 100.

Some defence tenders are listed only as store codes (for example "5 x P-14, 32 x P-26"). These have no descriptive words to match, so they rank low.

### Get daily tender alerts

1. Switch on **Only new since last run**. Each run then returns only tenders you haven't seen, plus any tender whose closing date was changed by a corrigendum.
2. Save your input as a **Task**, then add a **Schedule**, for example every day at 8:00 AM Pakistan time.
3. Connect the results wherever you work using Apify's integrations: email, Slack, Google Sheets, Make, Zapier or webhooks.

Bid consultants can create one task per client profile.

### Pricing

You pay only for tenders the Actor returns to you.

| Event | Price |
| --- | --- |
| Run start | $0.01 per run |
| Matched tender returned | $0.02 per tender |

- 5 matches: $0.01 + 5 × $0.02 = **$0.11**
- 25 matches (the default maximum): **$0.51**
- No matches: **$0.01**
- Daily monitoring with about 3 new matches a day: roughly **$2 a month**

Tenders that are filtered out or score below your minimum score are never charged. Use **Maximum matches** to cap the cost of any single run.

### Output fields

| Field | Meaning |
| --- | --- |
| `score` | 0 to 100, relative to today's best match |
| `title`, `organisation`, `portal`, `tenderNumber` | As published on the portal (`portal` is `federal_epms`) |
| `matchedKeywords` | Words from your profile found in the tender, strongest first |
| `closingDate`, `daysLeft` | Closing date and time (Pakistan time) and whole days remaining |
| `category` | Goods, Works, Consultancy or Non-consultancy services |
| `bidSecurityPkr` / `bidSecurityPercent` | Bid security as an amount in rupees, or as a percentage of estimated cost |
| `procedure`, `openingTime` | Procurement procedure and bid opening time |
| `isCorrigendum`, `isUpdate` | A corrigendum was issued; the tender was shown before but its closing date changed |
| `detailUrl`, `documentUrl` | Links to the tender page and the tender document |
| `matchModeUsed` | How the row was scored (`keyword`) |

The fields `reason`, `scopeSummary`, `eligibilityHints` and `redFlags` are reserved for the optional AI summaries planned for a later version. They are present in every row but empty for now.

Download the results as JSON, CSV or Excel, or read them through the Apify API.

### FAQ

**Where does the data come from?**
The federal PPRA e-Publishing and Monitoring System (epms.ppra.gov.pk), which lists tenders from federal ministries, defence organisations, utilities, state-owned companies, universities and some provincial bodies. Data is read live at run time, so it is as fresh as the portal.

**Is this legal?**
The Actor reads only public tender pages that anyone can view without logging in, and it crawls politely. It is an independent tool and is not affiliated with or endorsed by PPRA.

**Why did I get fewer results than expected?**
Try lowering **Minimum score**, raising **Closing within (days)**, removing keyword filters, or adding more specific product words to your profile.

**Can I use it from my own code or an AI agent?**
Yes, through the Apify API, the JavaScript and Python clients, or the Apify MCP server.

**What's coming next?**
Khyber Pakhtunkhwa (KPPRA) tenders, and optional AI summaries of each tender's scope and eligibility using your own API key.

**Something wrong?**
Open an issue on the **Issues** tab and I'll usually reply within a day.

# Actor input Schema

## `companyProfile` (type: `string`):

2 to 10 sentences: what you supply, which sectors and cities you serve, certifications and past clients. Tenders are scored by how strongly their wording overlaps this text, so concrete product words work best.

## `mustIncludeKeywords` (type: `array`):

Hard filter applied first: a tender must mention at least one of these words, e.g. solar, inverter. Leave empty to skip.

## `excludeKeywords` (type: `array`):

Tenders mentioning any of these words are dropped, e.g. construction of building.

## `minScore` (type: `integer`):

Only tenders scored at or above this (0-100) are returned and charged. The score is relative, not a percentage of relevance: 100 is the best-matching open tender in today's run, so 60 means "at least 60% as strong a match as the best one today". It can move from day to day as tenders open and close.

## `maxMatches` (type: `integer`):

The Actor stops after this many matching tenders.

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

Skip tenders that close later than this many days from now, and tenders that are already closed.

## `onlyNewSinceLastRun` (type: `boolean`):

For scheduled runs: skips tenders you were already shown. A tender comes back only if its closing date changed (a corrigendum).

## Actor input object example

```json
{
  "companyProfile": "We are an IT hardware supplier based in Islamabad and Lahore. We supply desktop computers, laptops, servers, networking equipment (switches, routers, firewalls), UPS and power backup, printers, scanners and CCTV systems to government departments, universities and hospitals. We are registered with FBR and SECP, hold authorised-dealer status for major brands, and have delivered similar supply contracts for provincial and federal organisations.",
  "mustIncludeKeywords": [],
  "excludeKeywords": [],
  "minScore": 60,
  "maxMatches": 25,
  "closingWithinDays": 90,
  "onlyNewSinceLastRun": false
}
```

# Actor output Schema

## `matchedTenders` (type: `string`):

Default dataset: one item per matched tender (score, title, organisation, closing date, matched keywords, bid security, links). Fields are described in the dataset schema; the Overview view is selected by default.

# 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 = {
    "companyProfile": "We are an IT hardware supplier based in Islamabad and Lahore. We supply desktop computers, laptops, servers, networking equipment (switches, routers, firewalls), UPS and power backup, printers, scanners and CCTV systems to government departments, universities and hospitals. We are registered with FBR and SECP, hold authorised-dealer status for major brands, and have delivered similar supply contracts for provincial and federal organisations."
};

// Run the Actor and wait for it to finish
const run = await client.actor("akramkhan/pakistan-tender-matcher").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 = { "companyProfile": "We are an IT hardware supplier based in Islamabad and Lahore. We supply desktop computers, laptops, servers, networking equipment (switches, routers, firewalls), UPS and power backup, printers, scanners and CCTV systems to government departments, universities and hospitals. We are registered with FBR and SECP, hold authorised-dealer status for major brands, and have delivered similar supply contracts for provincial and federal organisations." }

# Run the Actor and wait for it to finish
run = client.actor("akramkhan/pakistan-tender-matcher").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 '{
  "companyProfile": "We are an IT hardware supplier based in Islamabad and Lahore. We supply desktop computers, laptops, servers, networking equipment (switches, routers, firewalls), UPS and power backup, printers, scanners and CCTV systems to government departments, universities and hospitals. We are registered with FBR and SECP, hold authorised-dealer status for major brands, and have delivered similar supply contracts for provincial and federal organisations."
}' |
apify call akramkhan/pakistan-tender-matcher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,akramkhan/pakistan-tender-matcher"
        }
    }
}
```

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/nWBF8PRb3Si58v3QE/builds/7DwznCJhMjA1XgwRH/openapi.json
