# Changelog of UK & EU Public Tenders: Find a Tender, Contracts Finder & TED (`optimistprime/uk-eu-public-tenders`) Actor

- **URL**: https://apify.com/optimistprime/uk-eu-public-tenders/changelog.md
- **Full Actor documentation**: https://apify.com/optimistprime/uk-eu-public-tenders.md

## Changelog

### 1.0 (2026-10-03)

- First version: UK Find a Tender + UK Contracts Finder + EU TED in one typed schema (one row per notice).
- Filters: keywords, hierarchical CPV, buyer countries, stages (tender/planning), publication window, open only, deadline within N days, minimum value.
- UK limiter-aware pacing: ≤ 10 requests per rolling minute per UK host pair, ≥ 6 s apart, `Retry-After` (120 s) honoured, up to 3 retries; TED runs in parallel.
- Find a Tender read without the `stages` filter (which misses Procurement Act 2023 notices); tender/planning notices selected client-side.
- Monitor mode (new/changed only, charged only for those), FTS↔CF duplicate merge, fair maxItems sharing between UK and TED.
- Privacy: no contact names or phone numbers; role-mailbox emails only; free-text descriptions scrubbed of phones, personal emails and contact names.
- README: UK throughput figures replaced with platform measurements (Oct 3, 2026): ~4 pages ≈ 400 Find a Tender records/min including the server's 120 s pauses; 7 days ≈ 4.5 min, 31 days ≈ 26 min.

### 1.0.7 (2026-10-03)

- New input `timeBudgetSeconds` (default 60, 0 = unlimited): stops fetching after N seconds and returns the notices found so far; `RUN_SUMMARY` gets `truncated`, `timeBudgetSeconds` and `note`, and the status message says the results are partial. Only returned rows are charged; monitor mode only remembers notices it actually fetched. Rerun with `timeBudgetSeconds: 0` for a full UK pull.
- UK pacing: 5 requests/min (12 s apart), measured as the fastest pace with no forced 120 s wait on a 31-day pull (10/min: 7 waits, 26.4 min; 6/min: 429 after ~26 requests; 5/min: 0 waits, 21.9 min). Adaptive: after any 429/403 the pace drops by a third for the rest of the run (min 3/min).
- Contracts Finder: all selected stages in one request (`stages=planning,tender`), one pass instead of one per stage. Both UK APIs already used their maximum page size (100) and server-side date filters; Find a Tender's `stages` filter stays off (it drops Procurement Act 2023 notices).
- Status message returns to "Searching…" after a rate-limit wait.
- `truncated: true` / `stopReason: "timeBudget"` whenever the budget cut fetching short, even if the rows released afterwards fill `maxItems` (fix found in L1 on 1.0.6).

### 1.0.8 (2026-10-03)

- Quick calls (`timeBudgetSeconds` > 0): UK sources searched newest first (both UK APIs return newest-first, verified on real captures, so the cursor walk already goes backwards from now). Find a Tender is read first and each page's matches are pushed as soon as the page arrives; Contracts Finder follows if time allows, with duplicates of pushed Find a Tender notices dropped uncharged. Unlimited runs (`0`) keep the previous order (Contracts Finder first, merged into Find a Tender rows).
- Run summary: `pagesFetched`, `complete`, `coveredFrom`, `coveredTo` per source, plus total `pagesFetched` and overall `coveredFrom`/`coveredTo`.
- A truncated run with no matches now says: "0 matches in the N pages fetched so far (covering X to Y); rerun with timeBudgetSeconds 0 for a full pull." (status message and `note`).
- Monitor mode: still only notices actually fetched and pushed are remembered, so older notices beyond a truncated quick call are reported as new on the next run.

### 1.0.9 (2026-10-03)

- README: "Ready-to-run examples" section with published example tasks (one-click Try), copy-paste JSON inputs and real output excerpts. No code or pricing changes.

### 1.0.10 (2026-10-03)

- README: new "How to" section and a comparison FAQ entry (no competitors named), copy from Product Lead. No code or pricing changes.

### 1.0.11 (2026-10-05)

- maxItems stops now say how much was left: status message, log line and `RUN_SUMMARY.note` read "Returned 50 of N new notices. Raise maxItems to get them all." (monitor mode: N = new/changed notices; normal mode: "matching notices"). N is exact only when every source was paged to its end; otherwise it is an honest lower bound from the candidates already fetched ("50 of 73+", or "50 of 50+"), never estimated. `RUN_SUMMARY` adds `candidatesFound` and `candidatesExact`.
- README (monitor example): recommends `maxItems: 500` for daily GB/DE/FR monitoring, with a cost estimate from the live PPE prices (roughly $1.00–$1.50/day at ~500 new notices) and measured volume (TED DE+FR ~460–530 open notices per weekday, Sep 29–Oct 2; Find a Tender ~66 on 1 Oct).
- Tests: fixture test for the monitor `changed` path end to end through the Find a Tender lane (deadline/value change -> one `changed` row with `changedFields`, one `tender` charge, unchanged rows free; a changed row cut by maxItems is not charged and stays `changed`), plus maxItems-message tests. No pricing changes.

### 1.0.12 (2026-10-05)

- Input: `maxItems` default 100 -> **50**, Console prefill **5**, so a first one-click run costs under $0.02 including the start fee (5 × $0.003 + $0.002 = $0.017). API callers who omit `maxItems` get 50.
- README: example figures updated to the Oct 5 re-runs (UK cyber 46 s / 1 row / $0.005, Germany 4 s / 5 rows / $0.017, IT monitor 47 s / 5 rows / $0.017), example JSON matches the published tasks; default `maxItems` quoted as 50.
- The maxItems status line is logged once (was logged twice in 1.0.11).
