Belgium e-Procurement Tenders Scraper: BOSA Notices avatar

Belgium e-Procurement Tenders Scraper: BOSA Notices

Pricing

Pay per event

Go to Apify Store
Belgium e-Procurement Tenders Scraper: BOSA Notices

Belgium e-Procurement Tenders Scraper: BOSA Notices

Pricing

Pay per event

Rating

0.0

(0)

Developer

Francesco Correnti

Francesco Correnti

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Features

Limited permissions

Share

Monitor Belgian public procurement: Benelux and EU bid teams, consultants and suppliers track new overheidsopdrachten / marchés publics on BOSA e-Procurement (publicprocurement.be) by keyword, CPV, NUTS region, buyer, notice type or date, as clean rows.

Live sample, pulled 2026-11-06 (noticeTypes: ["16","17"], publishedFrom: 2026-11-01), 12 rows in sample.json:

noticeIdtitlebuyerKBO/BCE no.mainCpvpublishednoticeUrl
46fa7ef2-35cd-4749-8bf5-947022aecc77Cahier Spécial des Charges n°57/53/4/26/083 - Ligne 43 : RivInfrabel Projects South0869763267452200002026-11-06https://www.publicprocurement.be/publication-workspaces/46fa7ef2-35cd-4749-8bf5-947022aecc77/general
62361823-708a-40ff-93ba-519ab050b2cfZuidijzerpolder: Onderhoudswerken aan onbevaarbare waterlopeZUIDIJZERPOLDER0851235970452400002026-11-06https://www.publicprocurement.be/publication-workspaces/62361823-708a-40ff-93ba-519ab050b2cf/general
7291a5d2-15ff-48ee-a598-4b73b8ccca8b57/53/4/26/145 L166 : Gedinne -Bertrix Commune de Bertrix EnInfrabel Projects South0869763267450000002026-11-06https://www.publicprocurement.be/publication-workspaces/7291a5d2-15ff-48ee-a598-4b73b8ccca8b/general
2bc73dfb-4ddd-4b39-a50c-3a8bbbe1d35cAchat d'un camion d'occasion équipé d'une plate-forme élévatStadt Sankt Vith0207078568341370002026-11-05https://www.publicprocurement.be/publication-workspaces/2bc73dfb-4ddd-4b39-a50c-3a8bbbe1d35c/general
b1859abc-4fc0-4904-aa8a-f8ba389be4fbSlibruiming van de Aa te Vorselaar en LilleVlaamse Milieumaatschappij0887290276452460002026-11-05https://www.publicprocurement.be/publication-workspaces/b1859abc-4fc0-4904-aa8a-f8ba389be4fb/general

Text is kept as served (NL/FR/DE/EN). title is the first available in the order EN > NL > FR > DE, language says which; titles has every language version. Empty values (null) are not published by the buyer.

Input

fieldexamplemeaning
keywords"informatique"free-text search
cpv["72000000"]list of 8-digit CPV codes
noticeTypes["16","17"]BOSA notice subtype codes (16/17 contract notices, 20 modification, E1-E6 eForms); empty = all
location"BE10"Belgian NUTS code (BE10 Brussels, BE2 Flanders, BE3 Wallonia, BE332 Liège)
buyer"Infrabel"buyer name contains (filtered client-side)
publishedFrom / publishedTo"2026-10-01"publication date range, YYYY-MM-DD
deadlineFrom"2026-11-10"tender deadline on or after (server-side; notices without deadline drop out)
includeDetailstruedefault true; one extra request per notice for KBO/BCE number, value, documents link
maxItems50default 50, max 1000

Newest first.

Output

fieldmeaning
noticeIdBOSA publication workspace id (UUID, unique)
referenceNumberbuyer's file reference
title, titles, language, languagestitle (EN>NL>FR>DE), all title versions {lang: text}, chosen language, publication languages
descriptionas served; e-mail addresses stripped
buyerName, buyerOrgNumberbuyer and Belgian KBO/BCE company number (10 digits; needs includeDetails)
noticeType, procedureType, nature, statuse.g. 16, OPEN, WORKS/SUPPLIES/SERVICES, ACTIVE
cpvCodes (array), mainCpv8-digit CPV
nutsCodesNUTS codes
estimatedValue, currencyonly when the notice states a value (needs includeDetails); mostly null
publicationDate, deadlinedate / local timestamp
noticeUrl, documentsUrlpublicprocurement.be page, tender documents link (needs includeDetails)
scrapedAtISO timestamp

Pricing

Pay per event: $0.005 per start (actor-start) + $0.002 per notice (notice). Example: 1000 notices = $0.005 + 1000 x $0.002 = $2.005. The run stops cleanly at your spending cap; nothing is pushed beyond maxItems.

Source and limits

Step 0 findings (2026-11-06): publicprocurement.be is a Vue SPA calling its own JSON APIs (no registration, no captcha). Plain calls without a token get 403; the SPA first takes an anonymous visitor token, which the actor does the same way:

  • GET https://www.publicprocurement.be/env.config.js publishes the public frontend client id/secret.
  • POST https://www.publicprocurement.be/auth/realms/supplier/protocol/openid-connect/token (grant_type=client_credentials, Basic auth with that public client) -> 200, 1 h visitor token. No account or private key involved.
  • POST https://www.publicprocurement.be/api/sea/search/publications -> 200. Body {terms, cpvCodes, nutsCodes, noticeSubtypes, publicationDateFrom/To, tenderSubmissionDeadlineFrom/To, page, pageSize<=100}, needs Authorization: Bearer + BelGov-Trace-Id.
  • GET https://www.publicprocurement.be/api/dos/publication-workspaces/{noticeId} -> 200 (eForms XML: KBO/BCE number, documents URL, deadline).

Limits: unofficial API that can change; the visitor-token route relies on the site's public client, so it may be closed without notice; buyer filter applies after the search; the source rarely states estimated values; max 1000 items per run. No proxy.

Business data only

Buyer organisation, notice, CPV, value, dates and URLs. Contact persons, personal e-mails and phones are not read or output.

Run / test

python3 check.py (offline against fixtures/belgium.json, real BOSA responses; asserts query mapping, maxItems, PPE charge counts, no personal data). python3 check.py --live makes 1 real search request, needs 5+ notices (last result: live.log, 2026-11-06). Run: put input in storage/key_value_stores/default/INPUT.json, node src/main.js.

Publishing

publish.py --noruns (needs APIFY_TOKEN) creates/updates the actor without test runs. Not run: #469's publish.py was not run either, so this one is ready, not published.