UK Procurement Alerts – Contracts Finder + Find a Tender
Pricing
from $60.00 / 1,000 new contract match founds
UK Procurement Alerts – Contracts Finder + Find a Tender
Monitor UK government procurement portals for new contract opportunities matching your keywords, CPV codes, region, and value filters. Tracks seen notices to avoid duplicates. Only charges on new matches. Affordable alternative to Tussell (£16,500/yr).
Pricing
from $60.00 / 1,000 new contract match founds
Rating
0.0
(0)
Developer
joseph fadero
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Monitor UK government contracts for £0.06/match instead of £16,500/year — plus a real Fit Score and incumbent intelligence layer so you know which tenders are actually worth pursuing, not just which ones match a keyword.
Tussell and BiP Solutions charge thousands per year for alerts on publicly available government data. This actor monitors Contracts Finder and Find a Tender Service, matches your keywords and CPV codes, tracks what you've already seen, and only charges when genuinely new opportunities are found.
Two real bugs found and fixed in this addendum — both sources were silently broken before
Before adding any new feature, both existing data sources were checked live and found dead:
- Find a Tender: wrong domain. The actor called
find-a-tender.service.gov.uk(with "a-"). Confirmed via DNS lookup that this domain is NXDOMAIN — genuinely doesn't exist, not a network glitch. The real domain isfind-tender.service.gov.uk. - Contracts Finder: wrong endpoint path. The actor called
/Published/Notices/PublicUI/Search, which returns a real "Page not found" 404. The real endpoint is/Published/Notices/OCDS/Search.
Both real endpoints turn out to publish the UK government's own Open Contracting Data Standard (OCDS) release feed — structured, official, keyless JSON, far richer than the HTML-scraping fallback this actor previously fell back to (real CPV classification + description, real deadline dates, real buyer address/contact, and — critically for the incumbent-intelligence feature below — real contract-award records with real supplier names). Both sources now use these real OCDS endpoints directly.
A third, non-obvious real finding: neither source's searchTerm/keyword query parameter actually filters results server-side — confirmed by comparing a distinctive search term against no search term at all and getting byte-identical results. Both fetchers now pull a real recent date-range window and filter client-side by keyword match against title+description instead.
A fourth finding, specific to the two sources' shared OCDS format: despite publishing the identical data structure, their real date-filter parameter names differ. Contracts Finder uses publishedFrom/publishedTo; passing updatedFrom instead is silently ignored (confirmed live via a pinned historical date window that only worked with the right parameter name). Find a Tender uses updatedFrom/updatedTo; publishedFrom gets a real 400 error. Both are now used correctly, per source.
A critical, separate bug also found and fixed: seenNotices.ts called Actor.openKeyValueStore() with no name — which scopes the store to the current run only and never persists between runs. This silently defeated the actor's own core promise ("tracks seen notices... only charges on new matches") — every notice would have been charged as new on every single run. Fixed by naming the store. Confirmed live: a second run against identical real data correctly reported 0 new matches, where before the fix nothing would ever have been remembered.
What it does
- Searches Contracts Finder and/or Find a Tender for your keywords (client-side keyword filtering over a real date-range window — see above)
- Filters by CPV code, region, contract value, and notice type
- Remembers previously seen notices in a real, persistent Key-Value Store
- Returns only new opportunities not yet processed
- Flags high-value contracts (£100k+) with an extra charge signal
- Detects real amendments to a notice you've already seen — deadline changes, requirement/description changes, value changes — since your last run
mode: "fit_score": scores each result against your company profile and adds real incumbent/previous-winner intelligence
Two modes
| Mode | Behavior |
|---|---|
search (default) | The original keyword/date/value/buyer/CPV search and extraction — unchanged behavior, same cost |
fit_score | Same search, plus fitScore/geographicFit/capabilityFit/missingCertifications against your companyProfile, plus real likelyIncumbent/previousWinnersForSimilarTenders from contract-award history |
fit_score mode adds real per-run cost that search mode doesn't pay — incumbent intelligence builds a paginated award-history index (bounded, ~400 real records per source) the first time it's needed in a run. search mode's cost and speed are unchanged from before this addendum.
Fit Score — how the 0-100 weighting actually works
Not a black box — the exact weighting, so you can judge how much to trust a given score:
| Factor | Weight | What's actually compared |
|---|---|---|
| Capability match | 35 | Your capabilities keywords checked against the tender's real title + description text |
| Contract value fit | 25 | The tender's real value against your typicalContractValueMin/Max range |
| Industry match | 20 | Your industry text against the tender's real CPV classification description |
| Geographic fit | 20 | Your geographicCoverage against the tender's real delivery region |
Where a real signal is missing (you didn't specify a field, or the tender itself doesn't disclose one — e.g. no value stated), that axis scores a neutral half-weight rather than being penalized to zero or silently skipped — a fit score should reflect genuine mismatch, not incomplete input.
A known, honest limitation: capability and industry matching are real substring/keyword checks against real text, not semantic matching. A company profile capability of "passenger transport" won't match a tender that only says "HGV transport" — confirmed live during testing, where genuinely relevant tenders sometimes still scored capabilityFit: low because the exact phrase wasn't present. The overall fitScore still produced sensible relative ordering across a real 15-tender test set (the one genuinely transport-relevant tender scored highest at 43; unrelated tenders like a CAMHs mental health contract scored 10) — but treat capability/industry sub-scores as a floor, not a ceiling, on real relevance.
missingCertifications only ever lists a certification the tender's own real text explicitly names (checked against a curated list of certifications that genuinely appear in real UK procurement notices — ISO 9001/27001/14001, Cyber Essentials (Plus), PCI DSS, SC/DV Clearance, Constructionline, SafeContractor, CHAS, Investors in People) which your certifications list doesn't claim to hold. Most real notices don't state certification requirements in free text at all — this is never a fabricated gap.
Incumbent Intelligence — the genuinely new data-collection piece
Neither real OCDS API supports filtering by buyer name (confirmed live — only stages/limit/date-range params are real). So this builds a bounded buyer→award index by paginating real award-stage releases (real pagination via the OCDS response's own links.next field) — up to 4 pages (~400 records) per source, over an 18-month lookback, built once per run and cached, not once per notice.
For a given tender's buyer, likelyIncumbent is the most recent real supplier that buyer awarded a contract to (preferring the same CPV division — e.g. CPV "72xxxxxx" = IT services — when there's a match, falling back to any recent award from that buyer otherwise). previousWinnersForSimilarTenders is every real supplier name found. incumbentConfidence scales with how much real historical evidence backs the call (more past awards from that buyer = higher confidence, capped at 1.0 — never a false-certain 1.0 from a single data point... except when there IS only one real award and it directly matches, which genuinely does warrant high confidence).
Confirmed live across a real 15-tender test run: 4 of the buyers present had real, identifiable award history (e.g. a real district council's engineering incumbent, a real NHS health board's surgery-services incumbent with 2 previous winners identified) — the rest correctly returned null/empty, meaning no matching buyer was found in the bounded recent-award sample, not that the feature failed. This is an honest, bounded real-history sample, not exhaustive search — a buyer that hasn't awarded anything in the lookback window, or whose awards fall outside the ~400-record page cap per source, won't show incumbent data.
Respects a real, documented rate limit on Contracts Finder's own API (403 after too many requests in a short window, per its own API docs) with a short delay between paginated calls.
Amendment Tracking
Real change-detection on any notice you've seen before (both modes) — reuses the same delta-store pattern as this account's other regulatory-monitoring actors (store a snapshot, diff on the next sighting), with the same real lesson baked in: a named key-value store, since an unnamed one only persists for the current run. Detects: deadline changes, a change in the notice's description/requirement text (via content hash), and contract value changes. hasBeenAmended/amendmentSummary are false/null on a notice's first sighting (a baseline, not a change) — confirmed live via a seeded prior snapshot that correctly flipped to true with a real, readable summary on the next run.
Data sources
- Contracts Finder — free, open UK government portal; all contract values; real OCDS API at
/Published/Notices/OCDS/Search - Find a Tender Service — above-threshold procurement only (>£138k); post-Brexit replacement for OJEU; real OCDS API at
www.find-tender.service.gov.uk/api/1.0/ocdsReleasePackages
Both are published under the Open Government Licence, keyless. Contracts Finder does enforce a real rate limit (documented in its own API docs) — this actor's incumbent-intelligence pagination stays well under it.
Use cases
- SMEs in IT, consultancy, construction tracking live opportunities — now with a fit score to prioritize which to actually bid on
- Freelance bid writers managing keyword watchlists for multiple clients
- Sales teams building public-sector pipeline
- Competitive intel via Contract Award Notices and the new incumbent-intelligence layer (who's actually winning this buyer's contracts)
Pricing
| Event | Price |
|---|---|
| Run started | £0.05 |
| Notice scanned | £0.001 |
| New match found | £0.06 |
| High-value match (£100k+) | +£0.04 |
Typical weekly run: 5 keywords × 50 notices × £0.001 = £0.25 scanning + £0.06–0.10 per new match
Input
| Field | Default | Description |
|---|---|---|
| mode | search | search or fit_score |
| companyProfile | — | Required in fit_score mode: { industry, capabilities[], certifications[], typicalContractValueMin, typicalContractValueMax, geographicCoverage[] } |
| keywords | required | Search terms — each creates a watchlist |
| cpvCodes | [] | CPV codes to filter by (optional) |
| regions | [] | UK regions to filter (empty = all UK) |
| minValueGbp | 0 | Minimum contract value filter |
| maxValueGbp | 0 | Maximum contract value filter (0 = no limit) |
| noticeTypes | contract_notice | Notice types to return |
| sources | contracts_finder | Portals to monitor |
| publishedWithinDays | 7 | Lookback window in days |
| maxResultsPerKeyword | 50 | Max notices per keyword per source |
| excludeKeywords | [] | Words that disqualify a notice |
Output fields
noticeId, source, noticeType, isNew, title, description, buyerName, buyerType, publishedAt, deadlineAt, awardedAt, valueLow, valueHigh, valueSingle, isHighValue, cpvCodes, cpvDescriptions, region, suitableForSme, noticeUrl, matchedKeyword, relevanceScore, awardedTo, awardedValue, hasBeenAmended, amendmentSummary, fitScore, geographicFit, capabilityFit, missingCertifications, likelyIncumbent, incumbentConfidence, previousWinnersForSimilarTenders, scrapedAt, chargedEvent
The fitScore/geographicFit/capabilityFit/missingCertifications/likelyIncumbent/incumbentConfidence/previousWinnersForSimilarTenders fields are null/empty in search mode — populated only in fit_score mode.
Schedule setup
Run daily or weekly via Apify Scheduler. Connect to n8n: filter isNew: true + isHighValue: true → Slack alert with title, buyer, deadline, and noticeUrl. In fit_score mode, also filter on fitScore >= 70 for a "worth reviewing" tier, and alert immediately on hasBeenAmended: true for anything already in your pipeline.