UK Tenders Scraper - Find a Tender & Contracts Finder
Pricing
from $1.50 / 1,000 procurements
UK Tenders Scraper - Find a Tender & Contracts Finder
Scrape UK public procurement from Find a Tender (above threshold) and Contracts Finder (below threshold). One row per procurement joins tender, award and contract notices - buyer, CPV codes, procedure, deadline, value, lots, suppliers, documents and notice link. Daily changes feed, JSON/CSV/Excel.
Pricing
from $1.50 / 1,000 procurements
Rating
0.0
(0)
Developer
Philip Kirkbride
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Features
Share
UK Procurement Tenders Scraper
UK public bodies publish their buying on two national services: Find a Tender for above-threshold procurements, and Contracts Finder for below-threshold ones. A procurement usually appears more than once — first as a tender notice, later as an award or contract notice — and the useful picture only appears when those notices are put together.
This actor reads both services and saves one clean row per procurement. It joins the tender, award and contract notices that share the same Open Contracting ID (OCID), so a row carries the buyer, the CPV codes, the procedure, the status, the submission deadline, the value, the lots, the suppliers and contract values when they are published, the documents and the link to the official notice.
Cost. $0.0015 per procurement plus a $0.005 run start, so the Console sample of 20 open procurements costs about $0.035 and 100 procurements about $0.155. See Pricing.
Who it is for
- UK suppliers and bid teams looking for work they can still bid on, filtered by what is being bought (CPV) rather than by title wording alone.
- Tender-alert and monitoring services that need one row per procurement with a stable id, plus only what changed since yesterday.
- Market research and analytics teams measuring what the public sector buys, from which buyers, at what value and from which suppliers.
- Award and contract tracking: turn on awards and read the suppliers, award values and contract dates once they are published.
Quick start
Open procurements from both services, 20 rows (the Console default):
{"maxItems": 20}
IT services on Find a Tender:
{"sources": ["fts"], "cpvPrefixes": ["72"], "maxItems": 50}
Construction on Contracts Finder, the below-threshold service:
{"sources": ["cf"], "cpvPrefixes": ["45"], "maxItems": 50}
A daily changes feed for one search — same input, on a schedule:
{"cpvPrefixes": ["72"], "mode": "changes", "stateKey": "it-services", "maxItems": 100}
Everything published in a date window, whatever its status:
{"publishedFrom": "2026-11-01", "publishedTo": "2026-11-30", "status": "all", "maxItems": 200}
What you get
- Source and OCID — whether the procurement is from Find a Tender (
FTS) or Contracts Finder (CF), and its stable Open Contracting ID - Title and description — as published, in full
- Buyer — name and identifier (for example
GB-FTS-9129or a company number when the buyer published one) - CPV codes — every code the notice uses, with the published description
- Procedure and status — for example "Open procedure",
active,completeorcancelled - Open flag — whether bids can still be submitted at the moment the run started
- Tender period — the start and the submission deadline, in the source's own time zone
- Value and currency — when the notice states one
- Lots — each lot with its description, status, value and contract period
- Awards and contracts — suppliers (name and identifier), award value, award date, contract value and contract dates, when the source has published them
- Documents — each published document with its type, description, link, date and format
- Release history — every release of the procurement with its id, date and tags, the latest release, and any amendments the source records
- Notice link — the official notice page
- How complete the row is — Find a Tender rows (with awards on) are built
from the procurement's full published record. Contracts Finder has no full
record to read, so its rows are joined from the notices the run read, and
older notices of a long-running procurement may be missing;
joinedFromandhistoryCompletesay which case a row is. If a Find a Tender record cannot be read, only that row falls back to the notices in the window andrecordIssuesays why; the run keeps reading the other records. A single run reads the full published record for at most 300 Find a Tender procurements; any beyond that are joined from the notices the run read, andrecordIssuenames the reason. - Possible matches on the other service — listed separately, never merged
Everything is passed through as published, including buyer and supplier names.
A field the notice leaves out is null; nothing is guessed, translated or
filled in.
How to search
All filters are optional. By default the actor reads both services and keeps open procurements whose submission deadline is still ahead.
| Filter | What it does |
|---|---|
| Services | Find a Tender, Contracts Finder, or both (default) |
| Keyword | Every word must appear in the title, description, buyer, CPV descriptions, lots or award suppliers |
| CPV code prefixes | Keep procurements whose CPV codes start with any listed prefix, for example 72 for IT or 45 for construction |
| Buyer | Case-insensitive buyer name or identifier match |
| Published from / to | Notice publication date range |
| Deadline from / to | Submission deadline date range |
| Status | Open only (default) or all statuses |
| Maximum procurements | How many rows to save (50 by default, up to 1,000) |
| Include awards and contracts | Join award and contract notices to the row (on by default) |
Narrow filters search a limited window. Find a Tender and Contracts Finder do not offer keyword or CPV search, so the actor reads the newest notices in order and applies those filters itself. It stops after five pages in a row with no match, and it never reads more than 40 pages per service. A narrow keyword or CPV search therefore looks at the most recent releases rather than the whole archive. Add a Published from / to range to search a particular period; the date range switches the five-page stop off (the window already bounds the search), so only the 40-page cap applies.
Change tracking
Set Mode to Changes since the last run and the actor stops repeating the whole result set. It remembers what it last delivered for each procurement, and each later run saves only what moved:
- new — a procurement this state has not delivered before
- amended — a tracked value changed;
changedFieldsnames the fields.previousgives the earlier value of each changed single value (title, status, deadline, value, buyer, latest notice). For text and lists (description, CPV codes, lots, awards, contracts, documents, amendments) the field is named, andpreviousshows the earlier content only when it was empty — for example"awards": []when a first award appears - closed — it was open at the previous run and is no longer open: the
notice was awarded, cancelled or withdrawn, or its submission deadline has
passed. A tracked procurement whose deadline passes is reported as closed
even if no new notice is published for it; that row is rebuilt from the
values delivered earlier and says so (
joinedFrom: "earlier runs")
A run only reads the most recent notices, so it may not see every notice of
an older procurement again. A value the notices read this run do not carry is
treated as unknown, never as a change: single values keep the value
delivered earlier, and the field is named in fieldsNotInScan. A missing
deadline never turns into a false "closed".
The first run of a state has nothing to compare against, so every row it delivers is new; the run status says so. Use the same State key on every run of the same search. If you leave it empty, the name is derived from the search filters, so the same filters resume the same state and a different search starts its own.
The state lives in a named store in your own Apify account. Only rows that were actually saved are remembered, so a run that stops early does not hide what it did not deliver. If the state cannot be read or is not one this actor wrote, the run fails before delivering or charging anything, instead of starting over and repeating every procurement as new. If the state cannot be saved, the run fails and its status says which rows the next run will deliver again. Procurements not seen for a year are dropped, and the store keeps at most 5,000 procurements, the most recently seen first; the status says when any were dropped.
When a run reaches Maximum procurements, it stops and says so in the status; in Changes mode the remaining changes are delivered by a later run.
Change rows also carry the source's own version markers: the release ids, dates and tags, the latest release tag, and any amendments the notice records.
Possible matches across the two services
Find a Tender and Contracts Finder cover different thresholds, so most procurements appear on only one of them. When the same buyer publishes a very similar title with overlapping dates on both services, each row lists the other as a possible match with a plain reason. These are hints for a human to check. The two procurements are never merged into one row, and no match is asserted as certain.
Good to know
- Dates keep the time zone the source published them in (UK local time, with the offset stated).
- Awards and contract values appear only when the source has published them; they are usually absent while a tender is still open.
- A search that matches nothing finishes successfully with zero rows and a plain status message.
- A narrow keyword or CPV search looks at a limited window of the newest notices; add a publication date range to target a particular period.
- If one Find a Tender record cannot be read — because it is missing, gone,
rejected by the source, empty or malformed — only that procurement falls back
to the notices in the window; the rest of the run continues, and
recordIssuenames the reason on the affected row. - A source that cannot be read is reported as an error, never as "no results".
- If one service is unavailable, the other service's rows are still delivered and the status says the run stopped early.
- If a run reaches Maximum procurements, the status says so: more procurements may match.
- A run that runs out of time before delivering anything fails, so an empty result never looks like "no matches".
- Contains public sector information licensed under the Open Government Licence v3.0.
Pricing
- $0.0015 per delivered procurement — one charge per row, whether the row is a tender, an amended tender or a closed one. A procurement that appears as a tender notice and later as an award notice is one row and one charge.
- $0.005 per run start, charged per GB of memory, so the default 512 MB run is one start charge. It applies even when a search matches nothing.
- Reading CPV codes, notices and awards, and filtering, adds run time, not charges.
| Run | Rows | Cost |
|---|---|---|
Console sample: both services, maxItems 20 | 20 | $0.035 |
| A CPV or keyword search on one service | 50 | $0.08 |
| A daily changes feed that finds 12 changes | 12 | $0.023 |
| Everything published in one month | 1,000 | $1.505 |
See the Pricing tab for the current price.
Output example
One row per procurement. This example is a Changes-mode row shortened to show the shape; repeated array entries are shortened too.
{"recordId": "FTS:ocds-h6vhtk-0323a9","ocid": "ocds-h6vhtk-0323a9","source": "FTS","title": "Provision of Conversion Support Services for Student Recruitment for Glasgow Caledonian University","description": "The University is seeking a Contractor for the Provision of a Conversion Partner who is equipped to provide a bespoke data driven, measurable series of conversion solutions…","buyerName": "Glasgow Caledonian University","buyerId": "GB-FTS-9129","buyerIdentifierScheme": null,"buyerIdentifierId": null,"cpvCodes": [{"code": "79411100", "description": "Business development consultancy services", "scheme": "CPV"}],"procedure": "Open procedure","procedureCode": "open","status": "active","isOpen": true,"tenderPeriodStart": null,"tenderPeriodEnd": "2026-12-04T12:00:00+00:00","valueAmount": 800000,"valueCurrency": "GBP","lots": [{"id": "1", "title": null, "description": "The University is seeking an experienced Higher Education conversion partner…", "status": "active", "valueAmount": null, "valueCurrency": null, "contractPeriodStart": null, "contractPeriodEnd": null, "hasRenewal": true}],"awards": [],"contracts": [],"documents": [{"id": "104855-2026", "documentType": "tenderNotice", "title": null, "description": "Tender notice on Find a Tender", "url": "https://www.find-tender.service.gov.uk/Notice/104855-2026", "datePublished": "2026-11-04T16:19:41+00:00", "format": "text/html", "language": null, "source": "tender"}],"releases": [{"id": "104700-2026", "date": "2026-11-01T08:30:00+00:00", "tags": ["tender"]},{"id": "104855-2026", "date": "2026-11-04T16:19:41+00:00", "tags": ["tenderUpdate"]}],"releaseIds": ["104700-2026", "104855-2026"],"releaseDates": ["2026-11-01T08:30:00+00:00", "2026-11-04T16:19:41+00:00"],"latestReleaseId": "104855-2026","latestReleaseDate": "2026-11-04T16:19:41+00:00","latestReleaseTag": "tenderUpdate","latestReleaseTags": ["tenderUpdate"],"releaseTags": ["tender", "tenderUpdate"],"amendments": [],"noticeUrl": "https://www.find-tender.service.gov.uk/Notice/104855-2026","joinedFrom": "full record","historyComplete": true,"recordIssue": null,"fieldsNotInScan": [],"observedAt": "2026-11-04T21:17:15+00:00","changeType": "amended","changedFields": ["tenderPeriodEnd", "latestReleaseId", "latestReleaseDate", "latestReleaseTag", "latestReleaseTags", "noticeUrl"],"previous": {"tenderPeriodEnd": "2026-11-27T12:00:00+00:00","latestReleaseId": "104700-2026","latestReleaseDate": "2026-11-01T08:30:00+00:00","latestReleaseTag": "tender","latestReleaseTags": ["tender"],"noticeUrl": "https://www.find-tender.service.gov.uk/Notice/104700-2026"},"firstSeenAt": "2026-11-01T09:00:00+00:00","lastSeenAt": "2026-11-04T21:17:15+00:00","contentHash": "…"}
In Full mode, changeType, previous, fieldsNotInScan, firstSeenAt,
lastSeenAt and contentHash are null, and changedFields is an empty
list.
FAQ
How much does a run cost? $0.0015 per delivered procurement plus a $0.005 run start: the 20-row Console sample costs $0.035 and 100 procurements cost $0.155. Filters do not add a charge; they only change how much of the sources has to be read.
How do I get only new tenders each day? Set "mode": "changes" with a
stateKey and schedule the run with the same input. The first run is the
starting point; later runs deliver only new, amended and closed procurements,
with the fields that moved and their previous values.
Why is my keyword or CPV search slow? Neither service offers keyword or
CPV search, so a narrow filter has to be applied to the newest notices in
order, and it stops after five pages in a row with no match. Narrow the source
(sources), add a publishedFrom / publishedTo window, or keep the filter
broad; a search that matches nothing finishes successfully with zero rows and
the run start charge.
Why do Contracts Finder rows have fewer fields than Find a Tender rows?
Find a Tender publishes a full procurement record; Contracts Finder publishes
notice by notice, so its rows are joined from the notices read. joinedFrom
and historyComplete say which case a row is, and recordIssue names a
record that could not be read.
Why did I get fewer rows than Maximum procurements? Either the filters matched less than you asked for, a service stopped after five pages with no match, or the run reached its time limit. The run status says which, and the next run continues from where it stopped in Changes mode.
Are the tender documents downloaded? No. Each row lists the published documents with their type, description, link, date and format; the files stay on the official notice page.
What happens when nothing matches? The run succeeds with an empty dataset and a plain status message. A source that cannot be read is reported as an error, never as "no results".
Can I call it from the API or on a schedule? Yes. Every Apify Actor runs from the API with the same JSON input and can be scheduled; see the API tab of this Actor.
Where does the data come from and what licence applies? Find a Tender (above threshold) and Contracts Finder (below threshold), both published under the Open Government Licence v3.0. Everything is passed through as published.