World Bank Tenders, Contract Awards & Bid Deadlines
Pricing
from $1.05 / 1,000 procurement notice rows
World Bank Tenders, Contract Awards & Bid Deadlines
Tender notices and contract awards of World Bank-financed projects as rows: what is bought, the bid deadline in UTC with days left, borrower country, project, procurement method, reference number and the notice text. Filter by keyword, country, notice type or method. Keyless official API.
Pricing
from $1.05 / 1,000 procurement notice rows
Rating
0.0
(0)
Developer
Samat Makatov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
14 days ago
Last modified
Categories
Share
Tender notices and contract awards of World Bank-financed projects as rows: what is bought, the bid deadline in UTC with days left, borrower country, project, procurement method, reference number and the notice text. Filter by keyword, country, notice type or method. Keyless official API.
The source is the Bank's own procurement-notice index — about 420 000 records today, 300 000 of them awarded contracts, the rest opportunities that were once open for offers. It covers what the Bank finances in its borrower countries: a road in Nigeria, a hospital's equipment in Pakistan, a feasibility study in Kazakhstan. It does not cover the Bank's own office purchasing and it is not a national tender portal — a country's tenders appear here only when the Bank pays for the project. No key, no login, no captcha, no browser: a run is a handful of small JSON requests, sent one at a time. Data is published by the World Bank under Creative Commons Attribution 4.0. Made by Yadroo.
Two things the source cannot do, and this actor does instead: it has no date parameter of any kind, so the publication and deadline windows below are applied while paging, in UTC; and it takes one value per filter field, so several countries or notice types are sent as several searches and merged by notice id.
Use cases
- What can I bid on, and what closes first —
onlyOpen: true,deadlineWithinDays: 30,sort: "deadlineAsc": the queue a bid manager works through, withdaysToDeadlinealready counted and the buying agency's name, e-mail and phone on every row. - My market, my trade —
countries: ["Nigeria"],procurementGroups: ["CW"]: civil-works tenders of financed projects in one country. SwapGOfor equipment,CSfor consulting,NCfor transport, printing or maintenance. - Consulting assignments only —
noticeTypes: ["Request for Expression of Interest"],procurementGroups: ["CS"]: the expression-of-interest feed that firms and individual experts live off, without a single equipment tender in it. - Who won —
mode: "awards",query: "solar": awarded contracts in a sector. The winning firm, the amount and the evaluation are insidenoticeText, because that is where the source puts them (see What an award row contains). - The full history of one programme —
projectIds: ["P177816"],mode: "all": every notice and every award of one financed project, from the first general notice to the signed contracts. What auditors, journalists and NGOs ask for. - A weekly digest that never repeats itself —
sinceDays: 7,onlyNew: trueon a schedule: the actor remembers the notice ids it has already written and returns only what appeared since the previous run. - A tool for an agent — one call answers one question, the row is flat JSON, and
fieldscuts it down to the handful of keys a model should see.
Input
Nothing is required. With no input at all the actor writes the 50 newest tender notices of any kind, in any country.
| Field | Type | Default | Notes |
|---|---|---|---|
mode | string | notices | notices (the four opportunity types), awards (contract awards), all. Presets noticeTypes; see Modes |
query | string | — | Free text over bid description, project name and notice text. Prefilled with solar in the console |
queryMatch | string | all | all = keep only notices containing every word; any = the source's own behaviour. See Keyword matching |
countries | string[] | — | Country names as the source spells them, e.g. ["Kazakhstan"], ["Nigeria", "Ghana"]; any letter case. An unknown name stops the run with "did you mean". See Countries and regions |
countryField | string | either | either, project, implementing. Which of the two country fields to match; see Two countries per notice |
noticeTypes | string[] | follows mode | Multi-select of the 5 notice types. One search per value |
procurementGroups | string[] | — | GO, CS, CW, NC — see Categories |
procurementMethods | string[] | — | Method codes, e.g. ["RFB", "ICB"], any letter case; any other value stops the run. See Procurement methods |
projectIds | string[] | — | e.g. ["P177816", "P171577"]. The letter P and five to seven digits |
languages | string[] | — | English, French, Spanish; Castilian, Portuguese. See Languages |
onlyOpen | boolean | false | Keep only rows whose deadline day has not passed in UTC. Drops awards and most general notices, which have no deadline |
deadlineWithinDays | integer | — | 1–365. Keep deadlines between today and N days out; switches onlyOpen on |
sinceDays | integer | — | 1–3650. Keep notices published in the last N days, by notice date |
onlyNew | boolean | false | Write only notice ids no earlier run with the same filters has written; a run with nothing new writes no row. See Scheduling |
sort | string | noticeDateDesc | noticeDateDesc, noticeDateAsc, deadlineAsc, deadlineDesc. See Order and paging |
maxItems | integer | 50 | 1–5000. Hard cap on the rows written, and on what you pay for. Your max cost per run caps it too |
maxRequests | integer | 25 | 1–200. Second guard: the run stops after this many searches and says so |
includeNoticeText | boolean | true | Add the notice body as plain text (HTML removed, entities resolved) |
noticeTextMaxChars | integer | 4000 | 200–40000. Cut per row; noticeTextTruncated marks the rows that were cut |
fields | string[] | all | Keep only these output fields, in this order. rowType is always kept; unknown names are ignored and named in the status |
Three rules decide what a run returns:
- Different filters are combined with AND.
countries: ["Nigeria"]+procurementGroups: ["CW"]+noticeTypes: ["Invitation for Bids"]returned 335 records on 30 September 2026 — Nigerian civil-works tenders, nothing else. - Several values inside one filter are combined with OR, at the price of one request per value, because the source refuses a list (a comma-separated country returns nothing, a repeated parameter returns only the first value). Four notice types and two countries are eight searches; the actor merges them and drops duplicate notice ids.
- The windows are ours, the rest is the source's. Keyword, notice type, country, category, method, project id and
language are filters the source applies, so rows outside them are never fetched.
onlyOpen,deadlineWithinDays,sinceDays,onlyNewand all-words matching are applied here, on fetched rows — the run summary says how many rows each of them removed.
Reference
Modes
mode is a preset for noticeTypes, nothing more; setting noticeTypes yourself overrides it.
| Mode | Keeps | Deadlines | Typical use |
|---|---|---|---|
notices | Invitation for Bids, Request for Expression of Interest, General Procurement Notice, Invitation for Prequalification | yes, on most rows | bidding, monitoring |
awards | Contract Award | no | market research, who won, prices paid |
all | everything, no type filter at all | on the opportunity rows | one project's full history |
Notice types
Counts are the whole index on 30 September 2026 (420 975 records), to show the shape of the data.
| Value | What it is | Records |
|---|---|---|
Invitation for Bids | A concrete tender open for offers, with a deadline | ~45 700 |
Request for Expression of Interest | Consultants and experts asked to apply for an assignment | ~60 600 |
General Procurement Notice | Early notice of what a project intends to buy, months before the tender | ~3 500 |
Invitation for Prequalification | Bidders qualified before a large tender is issued | ~700 |
Contract Award | A contract that has been awarded | ~310 400 |
noticeTypes takes exactly these five values (a list in the input form); the platform rejects any other spelling
before the run starts.
Categories
procurementGroups — the source's own four groups. The readable label is written to procurementGroupName.
| Code | Name | Covers |
|---|---|---|
GO | Goods | equipment, vehicles, medicines, supplies |
CS | Consulting services | studies, design, supervision, individual experts |
CW | Civil works | construction, roads, buildings, networks |
NC | Non-consulting services | transport, printing, catering, maintenance, drilling |
Procurement methods
procurementMethods takes the codes below; procurementMethodName carries the readable name. Records from before the
Bank's 2016 procurement framework use the older codes, which is why both sets are listed. Counts are of the whole index
on 30 September 2026.
| Code | Name | Records |
|---|---|---|
RFQ | Request for Quotations | ~119 700 |
INDV | Individual Consultant Selection | ~89 300 |
RFB | Request for Bids | ~85 400 |
QCBS | Quality And Cost-Based Selection | ~29 900 |
CQS | Consultant Qualification Selection | ~27 700 |
CDS | Direct Selection (consulting) | ~19 400 |
DIR | Direct Selection | ~18 400 |
ICB | International Competitive Bidding (legacy) | ~16 400 |
LCS | Least Cost Selection | ~3 300 |
QBS | Quality Based Selection | ~1 600 |
RFP | Request for Proposals | ~900 |
FBS | Fixed Budget Selection | ~700 |
NCB | National Competitive Bidding (legacy) | ~600 |
UN | UN Agencies (Direct) | ~460 |
SSS | Single Source Selection (legacy) | 2 |
Any letter case works (rfb). A code outside this list — a partial one such as IC or CQ too — stops the run with
the list in the message instead of silently returning nothing or another method's notices. About 7 000 records carry
no method code at all — mostly general procurement notices.
Languages
languages takes English (~80 % of the index), French (~74 300 records), Spanish; Castilian (~30 500) and
Portuguese. The Spanish value looks odd because the source stores the cataloguing label with its suffix; pick it from
the list — the platform rejects any other spelling before the run starts. No other language exists in the index —
Russian, Arabic and Chinese notices are not there.
Two countries per notice
Every record carries two countries and they disagree more often than you would expect:
projectCountryis the country the financed project is booked under. For a regional programme that is a region:Central Asia,Western and Central Africa,Eastern and Southern Africa,Caribbean,Pacific 1.implementingCountryis the country of the agency that publishes the notice and receives the bids.
Kazakhstan on 30 September 2026: 854 records under Kazakhstan, plus 418 more whose project country reads
Central Asia and whose buyer sits in Kazakhstan. countryField: "either" (the default) sends both searches, merges
them by notice id and writes the country you asked for into matchedCountry, so nothing regional is lost. Use
project or implementing when you want exactly one side.
Countries and regions
Names must match the source's spelling; it does no partial matching (Egypt finds nothing, Egypt, Arab Republic of
finds 1 447 records). Letter case and punctuation do not matter (st lucia is St. Lucia), and the everyday names
below are translated; every translation is named in the run status. Anything else stops the run before a request is
sent, with the closest labels as "did you mean": a typo is never swapped for the nearest label, because the nearest
label is often another country (Nigera is one letter from both Nigeria and Niger). Labels in the index today:
Afghanistan · Albania · Algeria · Angola · Antigua and Barbuda · Argentina · Armenia · Azerbaijan · Bangladesh · Barbados · Belarus · Belize · Benin · Bhutan · Bolivia · Bosnia and Herzegovina · Botswana · Brazil · Bulgaria · Burkina Faso · Burundi · Cabo Verde · Cambodia · Cameroon · Central African Republic · Chad · Chile · China · Colombia · Comoros · Congo, Democratic Republic of · Congo, Republic of · Costa Rica · Cote d'Ivoire · Croatia · Djibouti · Dominica · Dominican Republic · Ecuador · Egypt, Arab Republic of · El Salvador · Eritrea · Eswatini · Ethiopia · Fiji · Gabon · Gambia, The · Georgia · Ghana · Grenada · Guatemala · Guinea · Guinea-Bissau · Guyana · Haiti · Honduras · Hungary · India · Indonesia · Iran, Islamic Republic of · Iraq · Jamaica · Jordan · Kazakhstan · Kenya · Kiribati · Korea, Republic of · Kosovo · Kyrgyz Republic · Lao People's Democratic Republic · Lebanon · Lesotho · Liberia · Madagascar · Malawi · Maldives · Mali · Marshall Islands · Mauritania · Mauritius · Mexico · Micronesia, Federated States of · Moldova · Mongolia · Montenegro · Morocco · Mozambique · Myanmar · Namibia · Nepal · New Caledonia · Nicaragua · Niger · Nigeria · North Macedonia · Pakistan · Palau · Panama · Papua New Guinea · Paraguay · Peru · Philippines · Poland · Romania · Russian Federation · Rwanda · Samoa · Sao Tome and Principe · Senegal · Serbia · Seychelles · Sierra Leone · Solomon Islands · Somalia · Somalia, Federal Republic of · South Africa · South Sudan · Sri Lanka · St Maarten · St. Kitts and Nevis · St. Lucia · St. Vincent and the Grenadines · Sudan · Suriname · Syrian Arab Republic · Tajikistan · Tanzania · Thailand · Timor-Leste · Togo · Tonga · Trinidad and Tobago · Tunisia · Turkey · Turkiye · Turkmenistan · Tuvalu · Uganda · Ukraine · Uruguay · Uzbekistan · Vanuatu · Viet Nam · Vietnam · West Bank and Gaza · Yemen, Republic of · Zambia · Zimbabwe
Regional and programme labels of the project-country field, which are not countries: Africa · Andean Countries · Caribbean · Central Africa · Central Asia · DRC - Angola · East Asia and Pacific · Eastern Africa · Eastern and Southern Africa · Europe and Central Asia · Horn of Africa · Latin America · Middle East and North Africa · OECS Countries · Pacific 1 · Pacific 2 · Pacific Islands · South Asia · Southern Africa · Southwest Indian Ocean · Western Africa · Western Balkans · Western and Central Africa · World
Everyday names are translated for you: egypt, yemen, iran, syria, russia, korea, laos, kyrgyzstan,
macedonia, gambia, ivory coast, cape verde, swaziland, east timor, micronesia, palestine, drc,
dr congo, congo, burma, mena, oecs, saint lucia, st kitts, sint maarten. Two countries kept two
spellings in the index and both are queried when you name one of them: Viet Nam (4 517 records) with Vietnam
(1 005), and Turkiye with Turkey.
Keyword matching
The source treats a multi-word query as any of these words: water supply matched 84 617 records on
30 September 2026, far more than either word alone. queryMatch: "all" (the default) keeps only the fetched rows whose
bid description, project name, reference or notice text contains every word, case-insensitively. Set any to write
the source's own result set unchanged. A single word behaves the same either way. Because a word may sit in the notice
text rather than in the short description, a matched row does not always show the word in bidDescription — and since
the match reads the whole notice while noticeText is cut at noticeTextMaxChars (4 000 characters by default), the
word can lie past the cut and be missing from the written noticeText too. Raise noticeTextMaxChars to see it.
Order and paging
sort orders the dataset after the merge, so it applies to the run as a whole and not per search. Rows with no notice
date or no deadline sort last in both directions.
The paging order is chosen by the tightest window you set, which is what keeps a monitoring run cheap:
| Window set | Paged by | Stops at |
|---|---|---|
sinceDays | notice date, newest first | the first notice older than the window |
onlyOpen or deadlineWithinDays | deadline, furthest first | the first deadline that has passed |
| none | notice date, newest first (or deadline for deadlineDesc, oldest-first for noticeDateAsc) | maxItems |
With a window set and an order the source cannot page in (for example deadlineAsc), the walk covers the whole window
before the sort picks the rows, so "the earliest deadline in the next 60 days" really is the earliest one. When the
paging order is the output order, each search stops as soon as its rows can no longer make the cut. Only the best
maxItems rows are held while the actor reads, and they are written once the walk ends (or when your max cost per run
or the run timeout stops it). deadlineAsc without any window cannot do that — the earliest deadlines in
the index are from 2003 — so it then orders the newest notices by deadline and says so in a warning.
What an award row contains
The source publishes awards as prose: there is no supplier field, no amount field and no score field in the record.
The winning firm, the contract value, the duration and the evaluation of the other bidders are inside noticeText,
under headings such as Awarded Bidder, Contract Amount and Evaluated Bidders. This actor passes that text
through as plain text and does not pretend to have parsed it. bidDescription, projectId, procurementMethodCode
and bidReference are structured on award rows as on any other.
Examples
Open tenders closing in the next two months, published in the last three weeks, earliest deadline first:
{"mode": "notices","sinceDays": 21,"onlyOpen": true,"deadlineWithinDays": 60,"sort": "deadlineAsc","maxItems": 25}
Civil-works tenders in Nigeria (335 records in the index on 30 September 2026):
{"mode": "notices","countries": ["Nigeria"],"countryField": "project","procurementGroups": ["CW"],"noticeTypes": ["Invitation for Bids"],"maxItems": 25}
Consulting assignments, newest first, without the notice text for a narrow dataset:
{"mode": "notices","noticeTypes": ["Request for Expression of Interest"],"procurementGroups": ["CS"],"includeNoticeText": false,"fields": ["bidDescription", "projectCountry", "submissionDeadline", "daysToDeadline", "contactOrganization", "url"],"maxItems": 50}
Everything Kazakh, regional Central Asia programmes included, notices and awards together:
{"mode": "all","countries": ["Kazakhstan"],"countryField": "either","sort": "noticeDateDesc","maxItems": 25}
Awarded contracts that mention solar, with the award text (the winner and the amount live in there):
{"mode": "awards","query": "solar","queryMatch": "all","includeNoticeText": true,"noticeTextMaxChars": 8000,"maxItems": 25}
A scheduled weekly digest of new hospital tenders in three markets:
{"mode": "notices","query": "hospital","countries": ["Pakistan", "Bangladesh", "Nepal"],"sinceDays": 7,"onlyNew": true,"maxRequests": 40,"maxItems": 100}
Output
One row per notice. A real row from a cloud run of the first example above (run ul1eCKC8rs58fieLT, 25 rows in 7 s);
noticeText is shortened here, the run wrote 4 000 characters of it:
{"rowType": "notice","noticeId": "OP00462366","noticeType": "Request for Expression of Interest","noticeStatus": "Published","noticeDate": "2026-09-10","noticeLanguage": "English","bidReference": "S43 (IDP)","bidDescription": "Selection of Training Service Provider for skill enhancement of the officials and instructors of DYD under IDP Procurement","projectId": "P178077","projectName": "Economic Acceleration and Resilience for NEET (EARN)","projectCountry": "Bangladesh","implementingCountry": "Bangladesh","matchedCountry": null,"procurementGroup": "CS","procurementGroupName": "Consulting services","procurementMethodCode": "QCBS","procurementMethodName": "Quality And Cost-Based Selection","submissionDeadline": "2026-09-30T00:00:00.000Z","submissionDeadlineTime": "03:00","daysToDeadline": 0,"isOpen": true,"noticeSubmittedDate": "2026-09-10","contactOrganization": "Department of Youth Development","contactName": "Kazi Moklesur Rahman","contactEmail": "pd.earn@dyd.gov.bd","contactPhone": "+880-02-55101121","contactAddress": "Level-19, NSC Tower, 62/3, Purana Paltan-1000, Dhaka, Bangladesh., Tel: (880-2) 9559389","noticeText": "Government of the People’s Republic of Bangladesh\nDepartment of Youth Development\nEconomic Acceleration and Resilience for NEET (EARN) Project\n…","noticeTextTruncated": true,"url": "https://projects.worldbank.org/en/projects-operations/procurement-detail/OP00462366","fetchedAt": "2026-09-30T21:12:03.177Z"}
Always filled: rowType, noticeId, noticeType, noticeStatus, projectId, projectName, projectCountry,
isOpen, url, fetchedAt.
| Field | Type | When it is filled |
|---|---|---|
rowType | string | notice for data, notFound for the single row a run writes when nothing matched |
noticeId | string | The source's stable id, e.g. OP00462366. Use it to deduplicate across runs |
noticeType | string | One of the five notice types |
noticeStatus | string | Published on every record in the index; see Limits |
noticeDate | string | Publication day, YYYY-MM-DD, converted from the source's 10-Sep-2026. Empty on about a thousand of the oldest records |
noticeLanguage | string | Language label of the notice |
bidReference | string|null | The buyer's own reference number of the lot or contract |
bidDescription | string|null | The one-line "what is procured". Never filled on general procurement notices, rarely missing elsewhere |
projectId / projectName | string | The financed project, e.g. P178077 |
projectCountry | string | Country or region the project is booked under |
implementingCountry | string|null | Country of the buying agency; often empty on awards |
matchedCountry | string|null | The country you filtered on, repeated; null when you filtered on none |
procurementGroup / procurementGroupName | string|null | CS and Consulting services; empty on some general notices |
procurementMethodCode / procurementMethodName | string|null | QCBS and its readable name |
submissionDeadline | string|null | Deadline day as ISO 8601 UTC at midnight — the source publishes no time zone. null on awards |
submissionDeadlineTime | string|null | Local clock time of the deadline as the buyer entered it, e.g. 15:00. No zone is given, and some afternoon deadlines arrive in 12-hour form without AM/PM (the example above is 15:00 Bangladesh time in the notice text) — confirm the time in noticeText before relying on it |
daysToDeadline | number|null | Whole UTC days from the run day to the deadline day; 0 = closes today, negative = passed |
isOpen | boolean | true while the deadline day has not passed in UTC; false when it has or when there is none |
noticeSubmittedDate | string|null | When the notice reached the Bank, ISO date |
contactOrganization | string|null | The buying agency. Filled on opportunities, usually empty on awards |
contactName / contactEmail / contactPhone / contactAddress | string|null | The bid-submission contact exactly as the source publishes it for bidders. Drop them with fields if you do not need them |
noticeText | string|null | The notice body as plain text, HTML and entities resolved; null with includeNoticeText: false |
noticeTextTruncated | boolean | true when the text hit noticeTextMaxChars |
url | string | The notice page on the source's site |
fetchedAt | string | Run timestamp, ISO 8601 UTC |
found / message | boolean / string | Only on a notFound row: what matched nothing and what to change |
Dataset views (Export → view in the console): Notices — id, published, type, country, what is procured, deadline, days left, method, category, project, reference, link. Deadlines — the bidder's queue: deadline, local time, days left, still open, both countries, matched country, what is procured, buyer, type, link. Contract awards — published, country, contract, project id, project, method, reference, award text, link.
Every run also writes a SUMMARY record to the default key-value store (linked from the run's Output tab): the
searches sent, requests used, rows fetched against rows written, how many rows each of the actor's own filters removed,
duplicates merged, the window in UTC days, the paging order, whether maxRequests, your max cost per run or the run
timeout stopped the run, every input correction, and the widest match count the source reported.
Use it from code / agents
curl -X POST "https://api.apify.com/v2/acts/yadroo~world-bank-procurement/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"mode":"notices","onlyOpen":true,"deadlineWithinDays":30,"sort":"deadlineAsc","maxItems":25}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('yadroo/world-bank-procurement').call({countries: ['Nigeria'], procurementGroups: ['CW'], noticeTypes: ['Invitation for Bids'], maxItems: 25,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('SUMMARY');
from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("yadroo/world-bank-procurement").call(run_input={"mode": "awards", "query": "solar", "projectIds": ["P177816"], "maxItems": 25})items = client.dataset(run["defaultDatasetId"]).list_items().items
MCP: add https://mcp.apify.com to Claude, Cursor or any MCP client and call the yadroo/world-bank-procurement tool
with the same JSON input. One call answers one question, which is what makes it a clean tool for an agent. Cut the row
down first so a model reads only what it needs:
"fields": ["bidDescription","projectCountry","submissionDeadline","daysToDeadline","procurementGroupName","url"] —
rowType is always kept, and switching includeNoticeText off keeps the rows small.
On a schedule, set onlyNew: true and a sinceDays window. The notice ids are remembered in a named key-value store,
one slot per filter set, so two schedules with different filters do not blind each other; the first run returns the
current window and later runs return only what is new. Only rows really written are remembered: a run stopped by your
max cost per run hands the rest to the next one. A run with nothing new writes no row (its status says "nothing new
since the last run"), and a filter that matches nothing at all writes its notFound row once, not on every run. A
daily run with sinceDays: 2 costs two or three requests.
Pricing
Pay per event: $0.001 per run start + $0.0015 per dataset row. The start event is charged on every run, including a run whose filters match nothing. Bronze −10 %, Silver −20 %, Gold and above −30 % on the row price; the start event is the same on every plan; platform usage is included.
Worked examples at full price:
- A 25-row deadline queue: $0.001 + 25 × $0.0015 = $0.0385.
- The default 50 rows: $0.001 + 50 × $0.0015 = $0.076.
- A 500-row market export: $0.001 + 500 × $0.0015 = $0.751.
- A scheduled run with
onlyNewthat finds nothing new: the start event only = $0.001. - A run whose filters match nothing: $0.001 start + one
notFoundrow = $0.0025.
You pay for rows written, not rows fetched: the deadline and date windows and the all-words keyword throw their rows
away before anything is written, and maxItems caps the rest. A typical run is 256 MB for well under a minute — the
25-row example above used 8 seconds and 7 requests — so compute is a fraction of a cent. maxRequests is the brake on
a wide crawl: raise it only when the run summary says it stopped you.
Limits & FAQ
- No date filter at the source, at all. Every documented date parameter and every range syntax left the match
count unchanged, so
sinceDaysand the deadline windows are applied while paging. A wide window therefore costs requests:sinceDays: 21over the four opportunity types took 7 requests and fetched 1 400 rows to write 25.maxRequestsstops it and the summary says the window may be incomplete. - One value per filter field. Several countries, types, categories, methods, project ids or languages are sent as
the cross product of one search each, capped at 60 searches per run. The run warns when the number of searches
exceeds
maxRequests. - Awards carry no structured supplier or amount. They are in
noticeTextonly; see What an award row contains. projectCountrycan be a region, and then the buyer's country is inimplementingCountry. This is whycountryField: "either"is the default.- Deadlines are days, not moments. The source dates every deadline at midnight and puts the local clock time in a
separate field without a time zone. A notice therefore counts as open while its deadline day has not passed in UTC,
and
daysToDeadlineis a whole number of days — the hour of your run never changes a row. On the deadline day a row can still sayisOpen: trueafter the buyer's office has closed. The clock time is passed through as typed and is not always right: notices checked on 2026-10-02 carried afternoon deadlines in 12-hour form without AM/PM (4:00 PMin the notice text,04:00in the field), and the time zone, when given, is only in the notice text (15:00 HOURS Bangladesh Standard Time). notice_statusisPublishedon everything. A cancelled, postponed or amended tender is not marked as such in the index; the amendment appears as a new notice. Check the notice page before you bid.- Paging depth. The source refuses an offset beyond 100 000 rows of one search (HTTP 400). To go deeper into a 400 000-record filter, narrow it — by country, type, category or keyword.
- General procurement notices have no bid description and no deadline: they announce what a project plans to buy, and the detail is in the notice text.
- About a thousand of the oldest records carry no notice date. With
sort: "noticeDateAsc"they are skipped and counted in the summary, because "oldest first" is useless when the date is empty. - No accounts, no attachments. Bidding documents live behind the buyer's own process; this actor reads the public notice index only. It does not log in anywhere and sends one request at a time, at least half a second apart.
- Max cost per run and timeout. The run never charges more than your "Maximum cost per run": it writes the best rows
that limit pays for and ends with "Stopped at your spending limit: N rows delivered". Near the run timeout (default
15 minutes) it stops reading and writes what it has, with "Stopped before the run timeout"; a wide crawl at
maxRequests: 200takes a few minutes. A restarted run (platform migration) never writes or bills a row twice. - Memory. Only the best
maxItemsrows are held while the actor reads, each notice text already cut atnoticeTextMaxChars. A run that would hold more notice text than its memory allows (thousands of rows at 40 000 characters each) stops reading early and says so; lowermaxItemsornoticeTextMaxChars. - Coverage is Bank-financed projects. National portals, other development banks and the Bank's own corporate purchasing are out of scope.
- Licence and attribution. The notices are open data under Creative Commons Attribution 4.0, which allows
commercial reuse with attribution to the World Bank; every row keeps the
urlof the original notice. Check the source's terms before you republish large extracts. - If the source changes. Fields are read by name, so a new or reordered field cannot corrupt a row; a renamed one
would need a fix. The actor reads exactly one endpoint on
search.worldbank.organd no other host.
Made by Yadroo. Sibling actors: world-bank-indicators · data-gov-datasets · federal-register-documents · uk-planning-applications · sanctions-screen