EU + Poland Procurement Monitor — TED + BZP delta feed
Pricing
from $2.00 / 1,000 qualified-notices
EU + Poland Procurement Monitor — TED + BZP delta feed
One actor, two official procurement sources: TED (EU-wide) + BZP (Poland domestic). CPV/keyword-filtered, delta-only qualified notices in one normalized schema. Pay-per-event.
Pricing
from $2.00 / 1,000 qualified-notices
Rating
0.0
(0)
Developer
Atlas Dataworks
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
One actor, complete Polish procurement coverage, one normalized schema:
- TED (Tenders Electronic Daily,
api.ted.europa.eu) — the EU's official journal of public procurement. Covers every EU country, including all Polish notices above the EU threshold. You can widen or narrow the country filter freely (default: Poland + neighbors). - BZP (Biuletyn Zamówień Publicznych via
ezamowienia.gov.pl) — Poland's official domestic bulletin. Covers Polish notices below the EU threshold, which never reach TED.
Together the two sources are the complete Polish public-procurement picture — plus as much of the rest of the EU as you ask for. Both are official open government APIs; no scraping of third-party aggregators, no proxies, no credentials.
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 24 h), so a
missed schedule slot heals itself on the next run. A zero-emit delta run tells you which
kind of zero it was: the status message reads "Nothing new — fetched N notices, all
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). 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 | per normalized notice delivered | $0.002 ($2.00 / 1,000 notices) |
Actor Start | once per run, 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. 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.
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 collection per run. On very broad filters with a long window the cap can truncate; anything truncated in delta mode is emitted by the next run.- Data is republished from official public registers unchanged; verify legal details on the linked source notice before acting on them.