EU & Poland Tenders Monitor: Public Procurement, TED + BZP
Pricing
from $1.50 / 1,000 tender notices
EU & Poland Tenders Monitor: Public Procurement, TED + BZP
Public procurement tenders from TED (all EU) and BZP (Poland, below the EU threshold) in one actor and one normalized schema. Filter by CPV code, keyword and country; delta mode returns only new tender notices each run. Official APIs, no proxies. Pay-per-event.
Pricing
from $1.50 / 1,000 tender notices
Rating
0.0
(0)
Developer
Atlas Dataworks
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
14 hours ago
Last modified
Categories
Share
EU & Poland Tenders Monitor: Public Procurement Notices from TED + BZP
Monitor public procurement tenders across the EU and Poland from one actor. It reads the two official sources, TED (every EU country, above the EU threshold) and BZP (Poland, below the EU threshold), filters them by CPV code, keyword and country, and returns every tender notice in one normalized schema. Run it on a schedule and each run returns only notices you have not received before. $2.00 per 1,000 notices, and you pay only for notices delivered.
What does this tenders monitor do?
- Reads TED (Tenders Electronic Daily,
api.ted.europa.eu), the EU's official journal of public procurement: every EU country, including all Polish notices above the EU threshold. Widen or narrow the country filter freely (default: Poland and its neighbours). - Reads BZP (Biuletyn Zamówień Publicznych,
ezamowienia.gov.pl), Poland's official domestic bulletin: the Polish notices below the EU threshold, which never reach TED. - Filters by CPV code (a prefix matches its whole family:
72is all IT services), by keyword and by buyer country. - Returns one record shape for both sources: title, buyer, CPV codes, published date, submission deadline, notice type and links to the notice page and its XML or PDF.
- Delivers a delta feed: with delta mode on (the default) each run returns only new notices, so a schedule gives you a clean alert stream with no dedup work.
Both sources are official open government APIs: no scraping of third-party aggregators, no proxies, no login.
Who uses it
- Companies that bid on public contracts. Get every new IT, construction, medical or services tender in Poland and the EU each morning, with its deadline.
- Bid consultants and tender-alert services. Feed clients' CPV profiles into scheduled tasks and forward the results.
- Market and sales intelligence. Track which public buyers are buying what, by CPV and region.
- AI agents. Call it as an MCP tool and get typed JSON back (see below).
How much does it cost to monitor tenders?
Pay per event: you pay per notice delivered (qualified-notice, $0.002), not for run time or
compute. Notices filtered out or already delivered cost nothing.
| What you run | Notices | Cost |
|---|---|---|
The prefilled run (CPV 72, IT services, up to 50 notices) | up to 50 | up to $0.10 |
| 1,000 notices | 1,000 | $2.00 |
| A schedule every 6 hours that finds 20 new notices a day (example) | about 600 a month | about $1.21 a month ($1.20 + 120 run starts) |
The table shows the Free-plan price. On Apify's paid plans each notice costs less: $1.85 per 1,000 on Bronze, $1.70 on Silver, $1.50 on Gold and above.
Set Budget cap (USD) and the run stops at it: it delivers what fits, tells you how much of the result set that was, and never charges past the cap.
How to monitor public tenders
- Click Try for free (or Start). The input is prefilled with CPV
72(IT services) and 50 notices, over the last 72 hours in Poland and its neighbours, so one click returns data. - Replace the CPV codes, keywords and countries with your own.
- Save it as a Task and add a Schedule (every 6 hours works; both sources publish on business days). Read each run's dataset as JSON, CSV, Excel or through the API, or send it on with an integration (Slack, email, Google Sheets, Make, Zapier, n8n, webhooks).
The product: a delta feed, not a dump
With deltaMode on (the default), the actor remembers every notice it has already emitted
(in the named key-value store dataworks-procurement-state) and each run outputs only
notices it has never emitted before. Run it on a schedule and the dataset of each run is
a clean incremental feed:
- Create a Task with your CPV codes / keywords / countries.
- Schedule it (e.g. every 6 hours; both sources publish continuously on business days).
- Consume each run's dataset (webhook, integration, or MCP): every record is new, no dedup work on your side.
The date window defaults to "since the last successful run" (first run: last 72 h, so a first run
on a weekend still reaches Friday's notices), so a
missed schedule slot heals itself on the next run. A task paused for more than 30 days restarts
30 days back, not at its last run, so it does not deliver (or charge for) a backlog of notices whose
deadlines have passed; the run log and OUTPUT.lookbackClampedFrom say when that happened. A zero-emit delta run tells you which
kind of zero it was: the status message starts with "Nothing new" and counts the
notices fetched and already seen when the sources are alive (fine), but a source that fetched/matched
nothing at all is flagged as degraded in the status message and in
OUTPUT.degradedSources: treat that as a pipeline problem (state store deleted, API
change) rather than a quiet market, because Polish public procurement alone publishes
hundreds of notices every business day. Outside delta mode, a run where every requested
source matches zero notices fails red instead of shipping an empty dataset.
Set deltaMode: false for a one-off, stateless date-range query (backfills, research).
Input
| Field | Default | Notes |
|---|---|---|
sources | both | ted, bzp, or both. |
cpvCodes | [] = all | CPV codes or prefixes ("72" = the whole IT-services family; a full code such as 72000000 or 72200000 covers its whole family too). Prefix/hierarchical matching on both sources. |
keywords | [] = all | OR-combined. TED: server-side full-text search. BZP: matched against title + buyer name. |
tedCountries | ["POL","DEU","CZE","SVK","LTU","UKR"] | TED buyer-country filter, ISO 2- or 3-letter. Empty list = all EU. |
includeAwardNotices | false | Also emit contract-award/result notices. |
dateFrom / dateTo | last run → now | ISO dates. Explicit values override delta defaults. |
maxNotices | 200 | Clamped to 1..5000, applied to the emitted feed. |
deltaMode | true | See above. |
Output: one normalized record for both sources
| Field | Example | Notes |
|---|---|---|
source | "ted" / "bzp" | |
noticeId | "557023-2026" / "2026/BZP 00388143/01" | Source-native id. |
uid | "ted:557023-2026" | Globally unique, the dedup key. |
type | "contract-notice" | "contract-award" | "other" | Normalized. |
rawType | "cn-standard" / "ContractNotice" | The source's own type string. |
title | "Poland – IT services … umowa ramowa" | TED: English preferred (EU-translated), original otherwise; BZP: Polish. titleLang says which. |
buyer | { name, nameLang, city, province, country } | province is a NUTS code where available. |
cpv | ["72000000","72250000"] | Normalized 8-digit codes, deduped. |
publishedAt | "2026-08-12" / "2026-08-12T04:50:05Z" | TED publishes day granularity; BZP a full timestamp. |
deadlineAt | "2026-09-11" | Tender-submission deadline when the notice carries one. |
belowEU | true | BZP only, below-EU-threshold flag. |
sourceUrl | notice page on ted.europa.eu / ezamowienia.gov.pl | Human-readable. |
rawLinks | { html, xml, pdf } | Machine formats (TED XML, BZP PDF). |
scrapedAt | ISO timestamp |
Each run also writes an OUTPUT summary (per-source fetch/match counts, already-seen
count, per-source errors) to its default key-value store; check it before trusting an
empty dataset.
Pricing (pay-per-event)
| Event | Fires | Price |
|---|---|---|
qualified-notice (Tender notice) | per normalized notice delivered | $0.002 ($2.00 / 1,000 notices) on Free; $1.85 Bronze, $1.70 Silver, $1.50 Gold and above |
Actor Start | per run, one per GB of memory (the default 512 MB is one), charged by the platform | $0.00005 ($0.05 / 1,000 runs) |
Result | per record stored, charged by the platform | $0.00001 ($0.01 / 1,000 records) |
The last two rows are Apify platform events rather than ours, listed so this table matches the pricing shown on the Store page exactly. They matter most on a schedule: a delta run that finds nothing new still pays the run charge, so an hourly schedule costs about $0.04 a month even in a completely quiet month (at the default 512 MB; more memory means more start events). Platform usage, compute and network, is bundled: no separate usage line.
You pay for delivered records, not runtime: filtered-out and already-seen notices cost
nothing. Runs respect your budget cap (maxTotalChargeUsd): when the cap is reached the
actor stops delivering, reports how much of the result set was delivered, and never
charges past it.
Using it from an AI agent (MCP)
The actor works well as an agent tool via Apify's MCP server: an agent can call it with a CPV set and get back a compact, normalized JSON feed it can reason over.
"Watch Polish public tenders for IT services. Every morning give me anything new above or below the EU threshold, with deadlines."
An agent handling this calls the actor with {"cpvCodes": ["72"], "sources": "both"} on a
schedule (delta mode on) and summarizes each run's dataset, the uid, deadlineAt, and
sourceUrl fields are all it needs to track, remind, and link.
FAQ
Is this legal? Both sources are official open government APIs that publish these notices for reuse, and the actor republishes their content unchanged. Check the linked source notice before you act on a tender.
Which CPV codes should I use? The two-digit division covers its whole family. Common ones: 72 IT
services, 48 software packages, 45 construction work, 33 medical equipment and
pharmaceuticals, 79 business services, 90 sewage, refuse and cleaning. Leave the list empty for
every notice.
Does it cover countries other than Poland? Yes for TED: set tedCountries to any EU countries, or
empty for all of them. The below-threshold notices are Poland only (BZP).
Why did my second run return nothing? Delta mode returned only what is new since the first run.
That is the product working: schedule it and each run carries the new notices. For a one-off query
over dates, set deltaMode to false and give dateFrom and dateTo.
Can I run several tasks with different filters? Yes. Each filter set (sources, CPV codes,
keywords, countries, award notices) keeps its own delta state, so a task for CPV 72 and a task for
CPV 45 each get every new notice of their own, whichever ran last. Order, letter case and
duplicates do not matter: ["72", "48"] and ["48", "72"] are the same task. Changing
maxNotices or the dates keeps the state; changing a filter starts a new one (its first run reads
the last 72 h).
Can I get the results in Slack, email or Google Sheets? Yes, through Apify's integrations and webhooks on the task: each run's dataset is the list of new notices.
Also from Atlas DataWorks
- Poland IT Jobs Scraper: justjoin.it, pracuj.pl and NoFluffJobs in one run, with parsed salaries.
- Amazon Product Scraper, Walmart Product Scraper and AliExpress Search Scraper.
Honest limits
- Poland-complete, EU-partial by design. Below-EU-threshold coverage is Poland only (BZP). Other countries' domestic below-threshold bulletins are not included.
- TED publishes day-granularity dates, so
publishedAt/deadlineAtfrom TED carry no time of day. Delta mode makes overlapping windows safe. - BZP filtering is client-side (the official API has no CPV/keyword parameters), so a very narrow filter over a long date range reads more pages than it emits records. Keep scheduled windows short; delta mode does this for you.
- Keyword search is literal, not stemmed:
kolejalso matcheskolejny, and Polish inflection meansministerstwowill not matchministerstwa. Prefer CPV codes for precision; keywords are a complement. maxNoticescaps the new notices per run. Notices already delivered do not count against it. On a broad filter with a long window the cap can truncate; in delta mode the run delivers the newest notices first, the status message says more are waiting, and the next run continues with them.- A delta task reaches back at most 30 days. For an older backfill, run with
deltaModeoff and an explicitdateFrom. - Data is republished from official public registers unchanged; verify legal details on the linked source notice before acting on them.