# Bhutan e-GP Tenders & Contract Awards (egp.gov.bt) (`a-g-d/bt-egp`) Actor

Tenders and contract awards (Notifications of Award) from Bhutan's national e-GP portal (egp.gov.bt) as English-keyed JSON: tender ID, title, ministry, procuring agency, method, publication and closing times, winner, exact contract value in ngultrum and links to the notices.

- **URL**: https://apify.com/a-g-d/bt-egp.md
- **Developed by:** [Aloever Dulay](https://apify.com/a-g-d) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% 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

## Bhutan e-GP Tenders & Contract Awards (egp.gov.bt)

Tenders and contract awards from Bhutan's national Electronic Government Procurement
system, [egp.gov.bt](https://www.egp.gov.bt), as clean, English-keyed JSON.

- **Tenders** (`recordType: "tenders"`, the default): tenders from the portal's All
  Tenders list, newest publication first. Live tenders (open for bids) by default; archived
  (closed) and cancelled tenders on request. Each has the tender ID, reference number, full
  brief, procurement category and bidding document, type and method, the ministry,
  department, dzongkhag, agency and procuring agency, publication and closing times,
  status and a link to the notice.
- **Contract awards** (`recordType: "awards"`): every awarded contract from the portal's
  Notification of Award list, newest award first, with the contract, tender and lot IDs,
  title, ministry, procuring agency, method, advertisement time, award date, the supplier
  the contract was awarded to and the **exact contract value in ngultrum**.

### Who needs this

- **Contractors and suppliers** bidding for Bhutanese public contracts who want new
  tenders in their field every morning instead of checking the portal by hand.
- **Tender-alert services and bid consultants** building feeds, email digests or
  WhatsApp/Telegram alerts.
- **Market-entry and trade teams** sizing public demand for works, goods and consulting
  by ministry, dzongkhag and agency.
- **Analysts, journalists and researchers** studying public procurement: who buys what,
  by which method, and which companies win contracts of what size.
- **Development partners and civil society** following how public money is spent.
- **AI agents and automations** that need a stable schema instead of a JSP portal.

### Input

| Field                | Type    | Default     | Description                                                                                                                                                                                        |
| -------------------- | ------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `recordType`         | string  | `"tenders"` | `tenders` or `awards` (contract awards). One run returns one record type.                                                                                                                          |
| `tenderStatus`       | string  | `"live"`    | **Tenders only**: `live` (open for bids, including amended ones), `archived` (closed: being processed, re-tendered or awarded), `cancelled`, or `all`.                                             |
| `keyword`            | string  | `""`        | Tenders: matched against the title, reference number and tender ID. Awards: matched by the portal against the package description (title). Case-insensitive.                                       |
| `ministry`           | string  | `""`        | Only records whose ministry contains this text, e.g. `Home Affairs` or `Ministry of Health`. Case-insensitive.                                                                                     |
| `agency`             | string  | `""`        | Only records whose department, agency or procuring agency contains this text, e.g. `Department of Surface Transport`, `Thimphu Thromde`, `Gewog`, `Technical Training Institute`.                  |
| `procurementNature`  | string  | all         | **Tenders only**: `goods`, `works` or `services`.                                                                                                                                                  |
| `method`             | string  | all         | Procurement method code: `OTM`, `LTM`, `LEM`, `DCM`, `QCBS`, `LCS`, `SFB`, `SBCQ`, `SSS`, `IC`, `FC`, `e-RA`. For awards, `LEM` also matches rows printed as `RFQ`, and `DCM` those printed `DPM`. |
| `dzongkhag`          | string  | all         | Only records of agencies filed under this dzongkhag's administration (dzongkhag, gewog and dungkhag offices), e.g. `Punakha`, `Samdrup Jongkhar`.                                                  |
| `publishedSince`     | string  | `""`        | **Tenders only**: tenders published after this point. A relative span (`24 hours`, `7 days`, `2 weeks`), a date (`2026-09-20`, midnight Bhutan time) or an ISO-8601 timestamp.                     |
| `awardedSince`       | string  | `""`        | **Awards only**: contracts whose notification of award is dated on or after the Bhutan calendar day of this point. Same formats as `publishedSince`.                                               |
| `maxItems`           | integer | `100`       | Stop after this many tenders or awards (1-20,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", "procurementNature": "works", "maxItems": 200 }
```

```json
{ "recordType": "awards", "ministry": "Infrastructure", "awardedSince": "90 days" }
```

The portal lists about 170 live tenders at a time, about 14,400 tenders in all
(`tenderStatus: "all"`) and about 8,300 contract awards since 2017. A run for all 8,300
awards takes about a minute and a half.

### Output

One dataset item per tender or per awarded contract. Every item has a `recordType` field,
`tender` or `award`; a run stores one record type only, so a run's dataset is
homogeneous. Keys are English; text is kept exactly as the portal publishes it, trimmed
and with HTML entities decoded. Times are ISO-8601 in Bhutan time (`+06:00`), the award
date is a calendar day (`YYYY-MM-DD`), and `fetchedAt` is UTC. The Output tab on this
page documents every field. The dataset has two table views: "Tenders" and "Awards".

A real tender (captured 2026-09-26):

```json
{
  "recordType": "tender",
  "tenderId": "27606",
  "referenceNo": "DoID/ROID/Pun-06/2026-2027/49",
  "title": "Construction of Goolinga Irrigation System",
  "procurementNature": "works",
  "procurementNatureLabel": "Works",
  "biddingDocument": "Large",
  "procurementType": "NCB",
  "procurementTypeLabel": "National Competitive Bidding",
  "method": "OTM",
  "methodLabel": "Open Tendering Method",
  "ministry": "Ministry of Home Affairs",
  "department": "Punakha",
  "dzongkhag": "Punakha",
  "agency": "Shengana",
  "procuringAgency": "Shenga-Bjimi Gewog, Punakha",
  "publishedAt": "2026-09-26T16:00:00+06:00",
  "closingAt": "2026-10-11T16:00:00+06:00",
  "status": "Live",
  "amendmentCount": 0,
  "detailUrl": "https://www.egp.gov.bt/resources/common/ViewNotice.jsp?id=27606&h=t",
  "sourceUrl": "https://www.egp.gov.bt/TenderDetailsServlet",
  "fetchedAt": "2026-09-26T20:10:56.531Z"
}
```

A real award (captured 2026-09-26):

```json
{
  "recordType": "award",
  "contractId": "22037",
  "contractNo": "MoIT/DoST/PD-01/2026-2027/122",
  "tenderId": "26842",
  "lotId": "39011",
  "referenceNo": "MoIT/DoST/PD-01/2026-2027/122",
  "title": "Supply of Bitumen Emulsion",
  "ministry": "Ministry of Infrastructure and Transport",
  "department": null,
  "dzongkhag": null,
  "procuringAgency": "Office of Secretary",
  "method": "OTM",
  "methodLabel": "Open Tendering Method",
  "advertisedAt": "2026-08-18T11:00:00+06:00",
  "awardedOn": "2026-09-15",
  "winnerName": "Wangmo Impex",
  "contractValueNu": 9168314,
  "contractValueExact": true,
  "contractValueMillionNu": 9.168,
  "contractValueText": "9.168",
  "detailUrl": "https://www.egp.gov.bt/resources/common/ViewNotice.jsp?id=26842&h=t",
  "sourceUrl": "https://www.egp.gov.bt/SearchNoaServlet",
  "fetchedAt": "2026-09-26T20:11:08.320Z"
}
```

#### About contract values

The award list publishes each contract's value in **millions of ngultrum** (its column
reads "Value (Million Nu.)"), rounded to three decimals. The actor also reads the same
page of the portal's advanced award search, which prints the exact amount, and pairs the
two by contract: `contractValueNu` is the exact value in ngultrum (9,168,314 Nu above,
printed as 9.168 in the list), and `contractValueExact` is `true`. The actor only takes
an exact amount that rounds to the published figure; if one is ever missing,
`contractValueNu` is the published figure × 1,000,000 (precise to 1,000 Nu) and
`contractValueExact` is `false`. `contractValueMillionNu` and `contractValueText` keep the
published figure as a number and as printed.

#### About agencies and dzongkhags

The portal files every procuring agency under a hierarchy: a ministry, then a department
(or, under the Ministry of Home Affairs, a dzongkhag), sometimes an agency, gewog or
dungkhag, then the procuring agency itself. Autonomous bodies (thromdes, colleges,
commissions, the courts) sit under a placeholder the actor turns into `ministry: null`,
with `department: "Autonomus Bodies"` as the portal spells it. `dzongkhag` is filled when
the hierarchy names one; central agencies and autonomous bodies have none.

#### About awards

The award list is ordered by the date of the notification of award (`awardedOn`), newest
first. It has one row per contract: a lot split between several suppliers gives one award
per supplier, all with the same `lotId`, each with its own `contractId`.

### Pricing

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

- **`tender-notice`**: one per tender stored.
- **`award-result`**: one per contract award stored.

A run charges one of the two, depending on `recordType`; the actor defines no start event
of its own. It stores each page before it is charged and stops cleanly when your spending
limit is reached, so you never pay for data you cannot see.

### Data source and politeness

The data comes from the public, login-free lists of Bhutan's e-GP system, run by the
Procurement Management and Development Division (PMDD) of the Department of Procurement
and Properties, Ministry of Finance: the "All Tenders" page and the Notification of Award
search (plus its advanced search, for exact values). 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 large pages (up to 500 rows) so a typical run needs only one to a few requests;
- retries connection resets, timeouts and server errors with exponential backoff inside a
  fixed budget, and stops with a clear error if the portal keeps refusing;
- asks public resolvers (1.1.1.1, 8.8.8.8) and then the portal's own nameservers when the
  platform's DNS cannot resolve the portal, and keeps that answer for the run;
- stops shortly before the run's timeout and keeps what it has stored;
- never logs in and never downloads tender documents.

The portal's terms and conditions are a user agreement for registered bidders and
agencies; they state that the materials on the system are copyrighted to PMDD, Ministry
of Finance, Royal Government of Bhutan. The actor publishes metadata and links only, not
documents; follow `detailUrl` for the official notice.

### Data and privacy

The output is procurement and award metadata exactly as the government publishes it.
Contracts are often awarded to sole proprietorships named after their owner, and
individual consultants are named in person, so `winnerName` can be a person's name: the
actor keeps it as published and adds nothing to it. The award list also prints each
winner's address, sometimes with phone numbers; the actor leaves the address out. It does
not open notice pages (which name the inviting official and give phone numbers), does not
enrich, profile or combine records with other sources, and does not guess personal
attributes. If you process names of individuals, you are responsible for doing so
lawfully.

### Limitations

- **Tender briefs are rich text**: some agencies add scope notes, lot lists or bidding
  instructions after the title. `title` holds the whole brief as plain text.
- **Filters the portal cannot apply are applied by the actor.** Keyword, ministry, agency
  and dzongkhag for tenders, and ministry, agency, method and dzongkhag for awards, are
  matched on the newest records; a run reads at most 20,000 rows, more than either list
  holds.
- **Dzongkhags are sparse on awards**: the award list prints only the first two levels of
  the hierarchy, and many Ministry of Home Affairs awards show the ministry alone, so
  `dzongkhag` is known for only about 3.5% of awards (it is known for most dzongkhag,
  gewog and dungkhag tenders).
- **Award titles have no commas**: the award list strips them from package descriptions;
  the notice page keeps the original. Some titles carry mis-encoded characters (such as
  `Ã¢??`) served by the portal itself; the actor keeps them as published.
- **The award list has no procurement category** and the tender list has no award date,
  so `procurementNature` and `awardedSince` apply to one record type each.
- **Award links go to the tender notice**: the portal's own contract pages are not
  publicly viewable (they answer with an error), so `detailUrl` opens the notice of the
  tender the contract was awarded under.
- Method names come from the portal's notice pages; `SBCQ`, `FC` and `e-RA` have never
  been spelled out there, so their `methodLabel` is `null`.
- A few awards carry something other than a date where the advertisement time belongs;
  `advertisedAt` is then `null`.
- The portal is sometimes slow (a page occasionally takes over a minute); the actor waits
  and retries.

# Changelog

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

# Actor input Schema

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

Tenders (the default): tenders from the All Tenders list, live ones unless "Tender status" says otherwise. Contract awards: awarded contracts from the Notification of Award list, newest award first, with the exact contract value. One run returns one record type.

## `tenderStatus` (type: `string`):

Tenders only: live (open for bids, including amended ones), archived (closed: being processed, re-tendered or awarded), cancelled, or all of them. Ignored for awards.

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

Tenders: matched against the title, reference number and tender ID. Awards: matched by the portal against the package description (title). Case-insensitive; leave empty for all records.

## `ministry` (type: `string`):

Only records whose ministry contains this text, e.g. "Home Affairs" or "Ministry of Health". Case-insensitive. Autonomous bodies have no ministry: find them with "Agency" instead.

## `agency` (type: `string`):

Only records whose department, agency or procuring agency contains this text, e.g. "Department of Surface Transport", "Thimphu Thromde", "Gewog" or "Technical Training Institute". Case-insensitive. (The award list names the department and procuring agency only.)

## `procurementNature` (type: `string`):

Tenders only: goods, works or services. Leave empty for all. Ignored for awards (the award list does not show it).

## `method` (type: `string`):

Only records under this procurement method. Leave empty for all methods. For awards, LEM also matches the rows the award list prints as RFQ, and DCM those it prints as DPM.

## `dzongkhag` (type: `string`):

Only records of agencies the portal files under this dzongkhag's administration (dzongkhag, gewog and dungkhag offices of the Ministry of Home Affairs). Central agencies, thromdes and autonomous bodies have no dzongkhag.

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

Tenders only: keep tenders published after this point. A relative span like "24 hours" or "7 days", a date like "2026-09-20" (midnight Bhutan time) or an ISO-8601 timestamp. Leave empty for no lower bound.

## `awardedSince` (type: `string`):

Awards only: keep contracts whose notification of award is dated on or after the Bhutan calendar day of this point. A relative span like "30 days", a date like "2026-09-01" or an ISO-8601 timestamp. Leave empty to start from the newest award with no lower bound.

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

Stop after storing this many tenders or awards (newest first).

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

Optional. The actor talks to egp.gov.bt directly; use Apify Proxy only if runs fail with connection errors.

## Actor input object example

```json
{
  "recordType": "tenders",
  "tenderStatus": "live",
  "keyword": "",
  "ministry": "",
  "agency": "",
  "publishedSince": "",
  "awardedSince": "",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Filled by runs with recordType "tenders" (the default): one item per tender matching the input filters (live tenders unless tenderStatus says otherwise), newest publication first: tender ID, reference number, title, procurement category and bidding document, type and method, ministry, department, dzongkhag, agency and procuring agency, publication and closing times in Bhutan time (+06:00), status and a link to the notice page.

## `awards` (type: `string`):

Filled by runs with recordType "awards": one item per awarded contract, newest notification of award first: contract, tender and lot IDs, contract and reference numbers, title, ministry, department, dzongkhag and procuring agency, method, advertisement time, award date, the supplier it was awarded to and the contract value in ngultrum (exact, and in millions as published), with a link to the notice page.

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

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

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

```

## MCP server setup

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

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/Rvq1Wcd1MbqLYh4hD/builds/EnDrwnDVOyJAasJ0Q/openapi.json
