# Pakistan PPRA Tenders, Contracts & Evaluations (EPMS) (`a-g-d/pk-ppra`) Actor

Active tenders, awarded contracts and bid evaluation results from Pakistan's PPRA e-Publish & Monitoring System (epms.ppra.gov.pk) as clean JSON: tender and contract numbers, titles, organizations, winners, amounts in PKR, lowest bidders, dates and document links. No officer contact data.

- **URL**: https://apify.com/a-g-d/pk-ppra.md
- **Developed by:** [Aloever Dulay](https://apify.com/a-g-d) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 71.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 tender notices

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 PPRA Tenders, Contracts & Evaluations (EPMS)

Public procurement data from Pakistan's Public Procurement Regulatory Authority (PPRA): its
e-Publish & Monitoring System, [epms.ppra.gov.pk](https://epms.ppra.gov.pk), as clean,
structured JSON.

- **Active tenders** (`recordType: "tenders"`, the default): every tender open for bidding
  on EPMS, newest first, with the tender and reference numbers, title, description, sector,
  organization, office and city, status (including cancellations and corrigenda),
  advertisement date and closing time.
- **Awarded contracts** (`recordType: "contracts"`): contracts published after award, with
  the PPRA contract number, the winner, the awarded amount in rupees, the organization and
  office, the publication date and a link to the signed contract.
- **Bid evaluation results** (`recordType: "evaluations"`): published pre-qualification,
  technical and final evaluations, with the number of bids and the lowest bidder.

Turn on `includeDetail` to also read each record's own page for the fields only it has:
tender type, category, procedure, method, bid security, opening time and document links;
a contract's signing date, tender value, number of bids and integrity-pact and complaint
flags; an evaluation's tender dates and report link.

### Who needs this

- **Contractors, suppliers and consultants** bidding for Pakistani federal public contracts
  who want new tenders in their sector every morning instead of paging through the portal.
- **Tender-alert services and bid consultants** building feeds, e-mail digests or
  WhatsApp/Telegram alerts.
- **Sales and competitive-intelligence teams** tracking which companies win which
  contracts, for how much, from which ministries, and who comes in lowest in evaluations.
- **Analysts, journalists and researchers** studying public spending, competition (bids per
  tender), contract sizes and procurement methods.
- **Market-entry and trade teams** sizing public demand by sector and organization.
- **AI agents and automations** that need a stable schema instead of a heavy HTML portal.

### Input

| Field                | Type    | Default     | Description                                                                                                                                                                                                                                                     |
| -------------------- | ------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `recordType`         | string  | `"tenders"` | `tenders` (active tenders), `contracts` (awarded contracts) or `evaluations` (bid evaluation results). One run returns one record type.                                                                                                                         |
| `keyword`            | string  | `""`        | Matched by EPMS against titles, descriptions and numbers.                                                                                                                                                                                                       |
| `tenderNumber`       | string  | `""`        | One EPMS tender number, e.g. `TS0000014731E`; for contracts and evaluations, the tender they belong to.                                                                                                                                                         |
| `organization`       | string  | `""`        | The procuring organization, e.g. `Ministry of Energy (Power Division)`, `PPRA` or `NHA`. A name that identifies one EPMS organization is filtered by EPMS; otherwise the actor keeps records whose organization or office contains the text (case-insensitive). |
| `sector`             | string  | all         | **Tenders and evaluations**: one of the EPMS sectors, e.g. `Civil Works`, `Services`, `Health/Medicines`, `Info and Comm Tech`.                                                                                                                                 |
| `city`               | string  | `""`        | Only records of procuring offices in this city, e.g. `Lahore`.                                                                                                                                                                                                  |
| `evaluationType`     | string  | all         | **Evaluations**: `pq`, `technical` or `final`.                                                                                                                                                                                                                  |
| `minValue`           | integer | none        | **Contracts**: awarded amount of at least this many rupees.                                                                                                                                                                                                     |
| `maxValue`           | integer | none        | **Contracts**: awarded amount of at most this many rupees.                                                                                                                                                                                                      |
| `publishedSince`     | string  | `""`        | Records EPMS published on or after the Pakistan calendar day of this point: tenders by advertisement date, contracts and evaluations by publication date. A relative span (`24 hours`, `7 days`, `2 weeks`), a date (`2026-09-20`) or an ISO-8601 timestamp.    |
| `includeDetail`      | boolean | `false`     | Also read each record's detail page (one extra request per record, about 2.5 seconds each).                                                                                                                                                                     |
| `maxItems`           | integer | `100`       | Stop after this many records (1-10,000), newest first.                                                                                                                                                                                                          |
| `proxyConfiguration` | object  | no proxy    | Optional Apify Proxy. Not needed normally; use it only if runs fail with connection errors.                                                                                                                                                                     |

A filter that does not apply to the chosen record type is ignored, and the run log says
so. Examples:

```json
{ "publishedSince": "24 hours", "sector": "Civil Works", "maxItems": 500 }
```

```json
{ "recordType": "contracts", "minValue": 100000000, "includeDetail": true }
```

```json
{ "recordType": "evaluations", "organization": "PPRA", "evaluationType": "final" }
```

Every active tender: leave the filters empty and set `maxItems` to about 2,500 (EPMS lists
roughly 2,300 active tenders at a time).

### Output

One dataset item per tender, contract or evaluation. Every item has a `recordType` field,
`tender`, `contract` or `evaluation`; a run stores one record type only, so a run's dataset
is homogeneous. Text is kept as EPMS publishes it, trimmed and with HTML entities decoded.
Dates are Pakistan calendar days (`YYYY-MM-DD`), times are ISO-8601 in Pakistan time
(`+05:00`), amounts are numbers in Pakistani rupees next to the text as printed, and
`fetchedAt` is UTC. Fields that only the detail page has are `null` unless `includeDetail`
is on; `hasDetail` tells which. The Output tab on this page documents every field. The
dataset has three table views: "Tenders", "Contracts" and "Evaluations".

A real tender, with `includeDetail` (captured 2026-09-26):

```json
{
  "recordType": "tender",
  "tenderNumber": "TS0000014733E",
  "title": "Provision of Services for Building Repair and Maintenance at EOBI House (Ex-Awami Markaz), Karachi",
  "referenceNumber": "PRIMACO/P&C/Repair & Maintenance Karachi/10/01/2026",
  "description": "Provision of Services for Building Repair and Maintenance at EOBI House (Ex-Awami Markaz), Karachi",
  "note": "Provision of Services for Building Repair and Maintenance at EOBI House (Ex-Awami Markaz), Karachi",
  "sector": "Services",
  "organization": "Ministry of Overseas Pakistanis & Human Resource Development",
  "office": "PRIMACO - Pakistan Real Estate Investment & Management Company (Pvt) Ltd.",
  "city": "Islamabad",
  "country": "Pakistan",
  "status": "Published",
  "hasCorrigendum": false,
  "cancellationReason": null,
  "publishedOn": "2026-09-26",
  "closingAt": "2026-10-12T14:00:00+05:00",
  "tenderType": "Request for Proposal (RFP)",
  "procurementCategory": "Non-consultancy Services",
  "procurementProcedure": "Single Stage-One Envelope",
  "procurementMethod": "Competitive Bidding",
  "tenderNature": "Local",
  "workflowType": "Standard Evaluation Process",
  "remarks": null,
  "officeAddress": "2nd Floor, EOBI House, G-10/4, Islamabad [contact removed]",
  "openingTime": "14:30",
  "bidSecurityPkr": 200000,
  "bidSecurityText": "200,000.00",
  "bidValidity": "90 days",
  "tenderDocumentUrl": "https://epms.ppra.gov.pk/pdf?file=dGVuZGVyX2F0dGFjaG1lbnRzL1JGUF8tX0J1aWxkaW5nX1JlcGFpcl9hbmRfTWFpbnRlbmFjZV9FeC1Bd2FtaV9NYXJrYXpfS2FyYWNoaV9TZXB0ZW1iZXJfMjAyNi5wZGY=",
  "advertisementUrl": "https://epms.ppra.gov.pk/pdf?file=YWR2ZXJ0aXNlbWVudF9kb2NzL0FkdmVydGlzZW1lbnRfM194XzE3Xy1fUHJvdmlzaW9uX29mX1NlcnZpY2VzX2Zvcl9CXzE3OTA0MDgyMDYucGRm",
  "hasDetail": true,
  "detailUrl": "https://epms.ppra.gov.pk/public/tenders/tender-details/TS0000014733E",
  "sourceUrl": "https://epms.ppra.gov.pk/public/tenders/active-tenders?page=1",
  "fetchedAt": "2026-09-26T19:52:20.000Z"
}
```

A real awarded contract, with `includeDetail` (captured 2026-09-26):

```json
{
  "recordType": "contract",
  "contractNumber": "PCN-0070393443",
  "referenceNumber": "005/14/NATCAT (EPADS V2 No. P78409)",
  "tenderNumber": "TS0000011734E",
  "title": "Renewal of ThreatHawk SIEM Solution and Support Services for One Year",
  "organization": "Ministry of Planning, Development & Special Initiatives",
  "office": "National Disaster Risk Management Fund (NDRMF)",
  "city": "Islamabad",
  "winner": "Relacom Services Private Limited",
  "natureOfPurchase": "National",
  "awardedAmountPkr": 1526625,
  "awardedAmountText": "Rs. 1,526,625",
  "valueBand": "< Rs. 50 Million",
  "publishedOn": "2026-09-25",
  "contractDocumentUrl": "https://epms.ppra.gov.pk/pdf?file=Y29udHJhY3RfZG9jdW1lbnRzL0NBXy1fU0lFTV8tX1JlbGFjb20ucGRm",
  "signedOn": "2026-09-21",
  "publishedAt": "2026-09-25T16:15:00+05:00",
  "procurementPlanNumber": "P78409",
  "awardedAmountExactPkr": 1526625,
  "tenderValuePkr": 1552500,
  "tenderValueText": "Rs. 1,552,500.00",
  "bidsReceived": 2,
  "integrityPactSigned": false,
  "complaintReceived": false,
  "officeAddress": "5th floor, EOBI House, G 10/4 islamabad",
  "hasDetail": true,
  "detailUrl": "https://epms.ppra.gov.pk/public/contracts/contract-details/PCN-0070393443",
  "sourceUrl": "https://epms.ppra.gov.pk/public/contracts?page=1",
  "fetchedAt": "2026-09-26T19:52:22.000Z"
}
```

A real evaluation result, with `includeDetail` (captured 2026-09-26):

```json
{
  "recordType": "evaluation",
  "evaluationNumber": "EVL00000003792",
  "tenderNumber": "TS0000011409E",
  "tenderReference": "P68267",
  "title": "Procurement of Consultancy Services for the hiring of Consultant/Consulting firms for drafting Regulations",
  "evaluationType": "Final Evaluation",
  "bidsReceived": 9,
  "lowestBidder": "RIAA Barker Gillette",
  "sector": "Research & Development",
  "organization": "Public Procurement Regulatory Authority (PPRA)",
  "office": "Public Procurement Regulatory Authority",
  "city": "Islamabad",
  "country": "Pakistan",
  "publishedOn": "2026-09-26",
  "tenderAdvertisedOn": "2026-08-17",
  "tenderClosingAt": "2026-09-01T11:00:00+05:00",
  "reportUrl": "https://epms.ppra.gov.pk/pdf?file=ZXZhbHVhdGlvbl9yZXBvcnRzL2ZpbmFsLWV2YWx1YXRpb25fMV83Mi5wZGY=",
  "officeAddress": "Sector G-5/2, Islamabad",
  "hasDetail": true,
  "detailUrl": "https://epms.ppra.gov.pk/public/evaluations/evaluation-details/EVL00000003792",
  "sourceUrl": "https://epms.ppra.gov.pk/public/evaluations?page=1",
  "fetchedAt": "2026-09-26T19:52:24.000Z"
}
```

#### About dates

EPMS lists contracts and evaluations by the date it **published** them (`publishedOn`),
which is what `publishedSince` filters on. A contract's signing date (`signedOn`) and the
exact publication time are on its detail page only. Tenders carry their advertisement date
and their closing date and time; the bid opening time comes from the detail page.

#### About amounts

The contract list prints whole rupees (`Rs. 1,526,625`); `awardedAmountPkr` is that number
and `awardedAmountText` keeps the text as printed. With `includeDetail`,
`awardedAmountExactPkr` has the amount with paisa as the detail page prints it, and
`tenderValuePkr` the tender's value.

### Pricing

Pay per event, charged only for records actually stored in your dataset:

- **`tender-notice`**: one per active tender stored.
- **`award-result`**: one per awarded contract stored.
- **`evaluation-result`**: one per evaluation result stored.
- **`record-detail`**: one per stored record whose detail page was read (`includeDetail`).

A run charges one of the first three, depending on `recordType`, plus `record-detail` when
you ask for detail; the actor defines no start event of its own. It stores each page before
it is charged, plans every page against your spending limit before reading any detail page,
and stops cleanly when the limit is reached, so you never pay for data you cannot see.

### Data source and politeness

The data comes from the public, login-free pages of PPRA's e-Publish & Monitoring System:
Active Tenders, Contracts and Evaluation Results, and each record's public page. Pakistan's
Public Procurement Rules 2004 require procuring agencies to publish these notices, and EPMS
publishes no robots.txt restrictions. The actor:

- sends **one request at a time with at least 2 seconds between requests**, with an honest
  User-Agent that names the actor;
- reads list pages first (50 records each) and detail pages only when you ask for them;
- retries connection resets, timeouts and server errors with exponential backoff inside a
  fixed budget, and stops with a clear error if EPMS keeps refusing;
- stops shortly before the run's timeout and keeps what it has stored;
- never logs in, never uses the credentialed e-PADS interfaces and never downloads tender
  documents; it links to them.

EPMS pages carry a copyright notice of the Public Procurement Regulatory Authority. The
actor publishes metadata and links only; follow `detailUrl` and the document links for the
official pages and documents.

### Data and privacy

The output is procurement metadata exactly as the government publishes it by law. EPMS
detail pages name a contact officer for every record, with an e-mail address and often a
phone number, and larger contracts carry a beneficial-ownership block: the actor never
stores any of these. E-mail addresses and phone numbers that appear inside free text
(description, note, remarks, cancellation reason, office address) are replaced with
`[contact removed]`. Winners and lowest bidders are mostly companies and are kept as
published; a few are sole proprietors named after a person, and the actor adds nothing to
them. It does not enrich, profile or combine records with other sources. If you process
names of individuals, you are responsible for doing so lawfully.

### Limitations

- **Tenders are active tenders only**: the list EPMS shows as "Active Tenders", including
  cancelled ones until they close (`status: "Cancelled"`). Closed tenders are not included.
- **Federal procurement**: EPMS covers federal ministries, divisions, attached departments
  and federal companies. Provincial procurement is published on provincial portals.
- **Descriptions in the list are shortened** (ending in `...`); `includeDetail` gives the
  full text.
- **Some contracts have no publication date**: EPMS prints none for its oldest contracts,
  so `publishedOn` is `null` and a `publishedSince` filter leaves them out.
- **Detail fields can be missing** even with `includeDetail`: EPMS leaves out the number
  of bids, plan number or tender value for some contracts, and those fields are then
  `null`.
- **Organization matching**: EPMS filters by the top-level organization (usually a
  ministry or authority). A name that matches several organizations, or an office such as
  `NDRMF` that EPMS lists under a ministry, is matched by the actor against the newest
  records; it reads at most 5,000 records for such a search.
- **Dates are days**: `publishedSince` works on Pakistan calendar days, because EPMS lists
  publication dates without a time.
- The lists are read newest first while EPMS keeps publishing; a record that moves between
  pages during a run is stored once.

# Changelog

This Actor's version history is a separate document: https://apify.com/a-g-d/pk-ppra/changelog.md

# Actor input Schema

## `recordType` (type: `string`):

Active tenders (the default): tenders open for bidding on EPMS. Awarded contracts: contracts published after award, with the winner and amount. Evaluation results: published PQ, technical and final bid evaluations, with the lowest bidder. One run returns one record type.

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

Matched by EPMS against titles, descriptions and numbers. Leave empty for all records.

## `tenderNumber` (type: `string`):

Only records of this EPMS tender number, e.g. TS0000014731E (for contracts and evaluations: the tender they belong to).

## `organization` (type: `string`):

The procuring organization, e.g. "Ministry of Energy (Power Division)", "PPRA" or "NHA". A name that identifies one EPMS organization is filtered by EPMS; otherwise the actor keeps records whose organization or office contains the text. Case-insensitive.

## `sector` (type: `string`):

Tenders and evaluations only: the EPMS sector. Leave empty for all sectors. Ignored for contracts (the contract list has no sector).

## `city` (type: `string`):

Only records of procuring offices in this city, e.g. "Lahore" or "Karachi". Case-insensitive.

## `evaluationType` (type: `string`):

Evaluations only: PQ (pre-qualification), technical or final evaluations. Leave empty for all.

## `minValue` (type: `integer`):

Contracts only: keep contracts awarded for at least this many rupees.

## `maxValue` (type: `integer`):

Contracts only: keep contracts awarded for at most this many rupees.

## `publishedSince` (type: `string`):

Keep records EPMS published on or after the Pakistan calendar day of this point: tenders by advertisement date, contracts and evaluations by publication date. A relative span like "24 hours" or "7 days", a date like "2026-09-20" or an ISO-8601 timestamp. Leave empty for no lower bound.

## `includeDetail` (type: `boolean`):

Also read each record's detail page for the fields only it has (tenders: type, category, procedure, method, bid security, opening time, document links; contracts: signing date, tender value, bids received, integrity-pact and complaint flags; evaluations: tender dates and report link). One extra request per record, about 2.5 s each, charged as record-detail.

## `maxItems` (type: `integer`):

Stop after storing this many records (newest first).

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

Optional. The actor talks to epms.ppra.gov.pk directly; use Apify Proxy only if runs fail with connection errors.

## Actor input object example

```json
{
  "recordType": "tenders",
  "keyword": "",
  "tenderNumber": "",
  "organization": "",
  "city": "",
  "publishedSince": "",
  "includeDetail": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `tenders` (type: `string`):

Filled by runs with recordType "tenders" (the default): one item per active tender matching the input filters, newest first: tender and reference numbers, title, description, sector, organization, office and city, status, advertisement date and closing time in Pakistan time (+05:00); with includeDetail also type, category, procedure, method, bid security, opening time and document links.

## `contracts` (type: `string`):

Filled by runs with recordType "contracts": one item per awarded contract, newest publication first: PPRA contract number, reference and tender numbers, title, organization, office and city, winner, awarded amount in PKR, publication date and contract document link; with includeDetail also signing date, tender value, bids received and integrity-pact and complaint flags.

## `evaluations` (type: `string`):

Filled by runs with recordType "evaluations": one item per published evaluation (PQ, technical or final), newest first: evaluation and tender numbers, tender reference, title, evaluation type, bids received, lowest bidder, sector, organization, office and city and publication date; with includeDetail also the tender advertisement and closing dates and the evaluation report link.

# 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 = {
    "includeDetail": false,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("a-g-d/pk-ppra").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 = {
    "includeDetail": False,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("a-g-d/pk-ppra").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 '{
  "includeDetail": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call a-g-d/pk-ppra --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,a-g-d/pk-ppra"
        }
    }
}
```

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/w5oe1NALUmeRbD5zB/builds/pfV0kEgy7rKf6cztE/openapi.json
