# World Bank Tenders Monitor — Procurement Notices (`gulfdata/worldbank-tenders-monitor`) Actor

Monitor World Bank procurement notices across 100+ countries via the official API. Filter by country, sector and keywords. Daily monitor mode pushes only NEW notices — clean JSON with contact data included.

- **URL**: https://apify.com/gulfdata/worldbank-tenders-monitor.md
- **Developed by:** [Ali Alshamrani](https://apify.com/gulfdata) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## World Bank Tenders Monitor — Procurement Notices API (100+ countries)

Monitor **World Bank procurement notices** across 100+ countries and get clean, deduplicated, analysis-ready JSON — **with contact data included** (name, email, organization).

Built on the World Bank's **official public API** — no scraping fragility, no proxies, fast and reliable. Built for **daily monitoring**: schedule it once, and every run pushes **only the notices that are new since the last run**.

### Why this Actor

- 🌍 **100+ countries in one feed** — civil works, goods, consulting and non-consulting services financed by the World Bank, published daily.
- 📇 **Contact data included**: implementing-agency contact name, email and organization on most notices — direct lead-gen value.
- 🔁 **Monitor mode**: previously seen notices are remembered across runs; you only pay for what's new.
- ⚡ **Official-API reliability**: no CAPTCHA, no proxy cost, fast runs.
- 🧹 **Clean data contract**: stable field names, ISO dates, deduplicated records, `first_seen_at` point-in-time timestamps.
- 🤖 **AI-agent friendly**: consistent JSON that drops straight into LLM pipelines, CRMs, Sheets, or Slack alerts. Same schema family as our Etimad (Saudi) tenders actor.

### Use cases

- **Consultancies** tracking World Bank country programs and upcoming bids.
- **Contractors & suppliers**: catch Invitations for Bids in your sector/countries early.
- **Lead-gen / BD teams**: new opportunities with contact emails, daily, into your CRM.
- **Development-sector analysts**: procurement activity by country, sector, method.

### Input

| Field | Type | Description |
|---|---|---|
| `keywords` | string | Matched against notice title and project name |
| `country` | string | Country name filter, e.g. "India" |
| `procurementGroup` | string | e.g. "CW" (civil works), "GO" (goods), "CS" (consulting) |
| `noticeType` | string | e.g. "Invitation for Bids" |
| `sinceDays` | integer | Only notices published in the last N days (default 7) |
| `maxRecords` | integer | Scan cap per run (default 500) |
| `monitorMode` | boolean | Push only NEW notices (default true) |
| `includeNoticeText` | boolean | Attach notice body text, capped at 5,000 chars (default false) |

### Output example

Real record (schema is stable — additive changes only):

```json
{
  "tender_id": "OP00377540",
  "reference_number": "IN-ASSAM PWD-510342-CW-RFB",
  "title": "Package 17- Construction of additional 5 Nos. of classrooms with labs and additional facilities in 2 Nos. of secondary schools each under Kaliabor & Barhampur Territorial Building Division, Nagaon",
  "agency": "Assam PWD",
  "activity": "CW",
  "tender_type": "Invitation for Bids",
  "submission_deadline": "2025-10-22T16:30:00Z",
  "published_date": "2026-08-26",
  "country": "India",
  "project_id": "P507865",
  "project_name": "Assam: School Education and Adolescent Wellbeing Project (ASAP)",
  "procurement_method": "Request for Bids",
  "contact_name": "Jyotismita Kashyap",
  "contact_email": "jyotismitadas144@gmail.com",
  "contact_organization": "Assam PWD",
  "notice_status": "Published",
  "notice_language": "English",
  "first_seen_at": "2026-08-28T01:22:58+00:00",
  "source": "worldbank",
  "source_url": "https://projects.worldbank.org/en/projects-operations/procurement-detail/OP00377540"
}
```

`source_url` opens the notice's public details page. `submission_deadline` combines the upstream date + time into one UTC ISO timestamp. `first_seen_at` is the point-in-time timestamp of when THIS pipeline first observed the notice.

### Scheduling

Typical setup: one scheduled run per day, `monitorMode: true`, `sinceDays: 7`, connected to a Slack/email/Sheets integration for instant alerts on new opportunities.

### Need all sources in one run?

[Global Tenders Radar](https://apify.com/gulfdata/global-tenders-radar) merges this feed with Saudi Etimad and UN (UNGM) procurement notices — one unified schema, one monitor, one run.

### Fair use & disclaimer

This Actor reads **publicly available procurement notices** from the World Bank's public search API at polite request rates. It is not affiliated with, or endorsed by, the World Bank Group. You are responsible for complying with the source's terms and applicable regulations, including how you use contact data.

# Actor input Schema

## `keywords` (type: `string`):

Optional keywords matched against the notice title and project name (case-insensitive substring).

## `country` (type: `string`):

Optional country name filter, e.g. 'India' or 'Saudi Arabia' (substring match).

## `procurementGroup` (type: `string`):

Optional procurement group code filter, e.g. 'CW' (civil works), 'GO' (goods), 'CS' (consulting services).

## `noticeType` (type: `string`):

Optional notice type filter, e.g. 'Invitation for Bids' or 'Request for Expression of Interest'.

## `sinceDays` (type: `integer`):

Ignore notices published earlier than this many days ago. Keeps monitor runs fast and cheap despite the 400k+ historical archive.

## `maxRecords` (type: `integer`):

Upper bound of notices scanned per run.

## `monitorMode` (type: `boolean`):

When enabled, previously seen notice IDs are remembered in a named key-value store and only new notices are pushed. Ideal for scheduled daily runs.

## `includeNoticeText` (type: `boolean`):

Attach the notice body (HTML stripped, capped at 5,000 chars) under `notice_text`.

## `useResidentialProxy` (type: `boolean`):

Not needed — the official API serves datacenter IPs fine. Enable only if you ever see blocks.

## Actor input object example

```json
{
  "sinceDays": 7,
  "maxRecords": 500,
  "monitorMode": true,
  "includeNoticeText": false,
  "useResidentialProxy": false
}
```

# Actor output Schema

## `notices` (type: `string`):

Normalized World Bank procurement notices scraped in this run (JSON items in the default dataset).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("gulfdata/worldbank-tenders-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("gulfdata/worldbank-tenders-monitor").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 '{}' |
apify call gulfdata/worldbank-tenders-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gulfdata/worldbank-tenders-monitor"
        }
    }
}

```

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/Wy3Os3OU3ilcqmcoj/builds/NRedIan1eZfM17ztM/openapi.json
