Poland Public Tender Monitor (BZP & e-Zamówienia)
Pricing
from $2.00 / 1,000 qualified notice alerts
Poland Public Tender Monitor (BZP & e-Zamówienia)
Real-time alerts for Polish public tenders (BZP). Filter by CPV, region & keywords; get only new, changed & awarded notices — via the official free API, no scraping.
Pricing
from $2.00 / 1,000 qualified notice alerts
Rating
0.0
(0)
Developer
MrArCode
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
19 days ago
Last modified
Categories
Share
Polish Public-Sector Procurement Alerts (BZP) — Qualified Event Feed
Extract structured procurement notices from the official, free Polish public-procurement database (BZP / e-Zamówienia) with hierarchical CPV matching, regional filtering, keyword monitoring, and incremental change tracking.
This Actor is designed for cybersecurity firms, IT integrators, public sector consultants, sales teams, and automation workflows that need clean, qualified, real-time alert feeds of Polish public tenders.
What does it do?
This Actor integrates directly with the official, free Polish e-Zamówienia Search API Gateway to retrieve public procurement notices. Instead of dumping raw database tables, it qualifies, normalizes, and filters notices client-side, returning a high-fidelity stream of procurement events (new opportunities, changed dates/deadlines, awarded contracts, and cancelled procedures) with a detailed whyMatched justification.
It supports incremental monitoring, meaning subsequent runs use a persistent state engine to deduplicate seen notices and deliver only the actual changes.
Key features
- Official API Integration: Queries the official public search gateway directly. No browser scraping, no HTML parsing, and no proxy fees.
- Hierarchical CPV Matching: Filter by CPV codes (e.g.,
72000000for IT services matches all subcategories like72200000or72222300automatically). - Client-Side Title Matching: Performs high-fidelity keyword matching in notice titles (
orderObject) to flag relevant tenders. - Regional & Authority Filtering: Filter notices by contracting authority names, NIP identifiers, or voivodeship regions (resolved automatically from names to BZP codes).
- State-Persisted Deduplication: Tracks seen notices and their volatile fields (
submittingOffersDate,procedureResult,contractors) in a Key-Value Store to detect changes. - Pure Pay-Per-Event Pricing: Charges only for qualified events (
new,changed,awarded,cancelled) that match your criteria. Unchanged notices are processed and delivered 100% free of charge. - Reliable Watermark Guard: Watermark (
__last_run_timestamp) is advanced only on a complete, error-free scan. If any sub-query fails, the watermark remains at its previous value, ensuring no notices are lost on the next run.
Use cases
- Cybersecurity & IT Alerts: Automatically monitor new tenders matching CPVs like
72000000and keywords likecyberorbezpieczeństwo. - Competitor & Award Tracking: Monitor who won specific public contracts and for what procedure results.
- Authority Sourcing: Monitor tenders published by specific municipalities, hospitals, or government entities using their NIP.
- Procurement Dashboards: Build real-time alerting dashboards for sales teams using webhooks.
- Downstream CRM Feeds: Route qualified events directly into Slack, Teams, or CRMs via webhooks.
Input
You can filter notices using CPV codes, keywords, region codes/names, and contracting authorities.
Basic IT search example
{"cpvCodes": ["72000000", "48000000"],"keywords": ["cyber", "bezpieczeństwo", "system"],"noticeTypes": ["contract", "award"],"mode": "new_only","dateLookbackDays": 3}
Contracting authority monitoring example
{"contractingAuthorities": ["Publiczna Szkoła", "7962452708"],"noticeTypes": ["contract"],"mode": "all","dateLookbackDays": 7}
Regional filtering example
{"cpvCodes": ["72000000"],"voivodeships": ["PL14", "Śląskie"],"noticeTypes": ["contract", "award", "plan"],"mode": "new_only","dateLookbackDays": 5}
Input fields
| Field | Type | Description |
|---|---|---|
cpvCodes | array | Hierarchical CPV codes to monitor (e.g., ["72000000", "48000000"]). Supports prefix matching. |
keywords | array | Keywords to match case-insensitively in notice titles (e.g., ["cyber", "bezpieczeństwo"]). |
voivodeships | array | BZP regional codes (PL02–PL32) or voivodeship names to filter on (e.g., ["PL14", "Mazowieckie"]). |
contractingAuthorities | array | Names or NIP identifiers of specific contracting authorities to monitor. |
noticeTypes | array | Types of notices to monitor. Supported: "contract", "award", "plan", "concession", "competition", "update". |
mode | string | Scraper mode: "new_only" (filters out unchanged) or "all" (returns all matches). Default: "new_only". |
dateLookbackDays | integer | Number of days to look back on a fresh run or if state is missing. Default: 7, max: 30. |
Output example
Every record emitted to the dataset follows this strict, drift-free schema:
{"objectId": "08ded05a-f5d3-a088-5fad-9500015f90c5","eventType": "awarded","noticeType": "TenderResultNotice","isTenderAmountBelowEU": true,"orderObject": "Dostawy sprzętu oraz oprogramowania w ramach zadania pn. „Cyberbezpieczny Powiat Węgrowski” – 2 podejście","cpvCode": "30233000-1 (Urządzenia...), 32420000-3 (Urządzenia...), 48000000-8 (Pakiety oprogramowania i systemy...)","organizationName": "Powiat Węgrowski","organizationProvince": "PL14","organizationNationalId": "8241765263","submittingOffersDate": null,"procedureResult": "zawarcieUmowy","contractors": [{"contractorName": "Net Complex Sp. z o.o","contractorCity": "Bielsko Biała","contractorProvince": "PL24","contractorCountry": "PL","contractorNationalId": "5472165461"}],"sourceUrl": "https://ezamowienia.gov.pl/mo-client-board/bzp/notice-details/html/08ded05a-f5d3-a088-5fad-9500015f90c5","whyMatched": ["CPV 48000000","keyword: cyber"],"firstSeenAt": "2026-06-24T05:07:06Z","lastSeenAt": "2026-06-24T05:07:06Z"}
Event types
The Actor classifies each qualified notice against previous runs into one of the following event types:
| eventType | Meaning | Chargeable? |
|---|---|---|
new | A notice that has not been seen before in this search context. | Yes |
changed | A notice seen in previous runs, but where a volatile field (e.g., deadline, result, contractors) changed. | Yes |
awarded | A result notice indicating a contract has been successfully awarded (TenderResultNotice). | Yes |
cancelled | A notice that has been explicitly cancelled (detected from the official procedureResult text in data). | Yes |
unchanged | A notice that has been seen before and has not changed. (Filtered out in new_only mode). | No |
Incremental & state
- Cross-Run State Persistence: State is stored in a named Key-Value Store (
bzp-scraper-state) under the keystate-{stateKey}. It tracks notice hashes and seen flags. - Watermark Guard: The scraper utilizes an
all_queries_okcheck. If any query fails due to an API timeout or transient gateway error, the watermark (__last_run_timestamp) is not advanced. This ensures that a subsequent run will repeat the lookback for the failed window, preventing any notices from being missed. Successfully fetched notices are still pushed, charged, and committed to seen state to avoid duplicate billing. - Cancelled notices from data: In procurement monitoring, notices do not "expire" by disappearing from the feed. Instead, cancellation is an active event detected when the official
procedureResultcontains cancellation information (e.g.,"unieważnienie"). The scraper never emits a cancellation event simply because a notice disappears from a scan window.
Data quality & limitations
- Search Payload Limitation: The official BZP Search API (
/Board/Search) does not return the HTML body of notices (it is always returned asnull). Direct keyword matching is therefore performed strictly on the notice title (orderObject). - No Value Field: The search gateway does not provide numerical budget or price fields. The only budget indicator is the boolean
isTenderAmountBelowEU. Numerical value filters (likeminValue) are not supported at the search level. - BZP Regional Coding: The API returns BZP regional codes (equivalent to old NUTS-3 / TERYT regional grouping) where the 16 Polish voivodeships are mapped to consecutive even numbers in alphabetical order (
PL02toPL32). The Actor automatically translates Polish province names to these codes.
Responsible usage
This Actor is designed to integrate with the official, free public read API gateway of e-Zamówienia. It does not perform HTML scraping, browser impersonation, or anti-blocking circumvention. It respects rate limits and applies exponential backoff on HTTP 429 errors. Please configure your run frequencies (e.g., hourly or daily) reasonably.
Pricing
This is a pure Pay-Per-Event Actor. You only pay for qualified notice events (new, changed, awarded, cancelled) that match your search filters.
- No Proxy Cost: Because this Actor uses the official free public gateway, it runs with zero proxy costs (no residential proxy charges).
- Unchanged notices are 100% free: Deduplicated
unchangedrecords are never charged.
FAQ
Does this Actor support direct BZP details URLs?
No. The Actor queries the official Search gateway by date and CPV code. Direct detail pages are represented in the dataset as sourceUrl links but cannot be scraped individually.
Can I monitor only new tenders?
Yes. Use "mode": "new_only" (default). This filters out all unchanged notices from your dataset, delivering only actionable events.
Why did I get a warning about the watermark?
If the e-Zamówienia API experiences transient failures or timeouts during a run, the Actor logs a warning: "Incomplete fetch — watermark not advanced to avoid missing notices." This is a safety feature ensuring that the next run will search the same time window again to fetch the missing data.
Downstream integration (Make / Slack / Webhooks)
This Actor is designed to be scheduled hourly or daily. You can configure an Apify Webhook that triggers whenever a run completes successfully to send qualified events directly to Slack, Teams, or your custom CRM via Make.com or Zapier.
Example Make.com flow:
- Apify Webhook: Run finished
- Apify Module: Get Dataset Items (filters out empty runs)
- Router:
- If
eventType == "new": Send Slack alert: "New tender opportunity discovered!" - If
eventType == "cancelled": Update CRM: "Tender has been cancelled."
- If