UK Public Tenders — Find a Tender + Contracts Finder avatar

UK Public Tenders — Find a Tender + Contracts Finder

Pricing

from $2.10 / 1,000 results

Go to Apify Store
UK Public Tenders — Find a Tender + Contracts Finder

UK Public Tenders — Find a Tender + Contracts Finder

One reliable feed of UK public procurement notices. Merges Find a Tender and Contracts Finder (the Procurement Act 2023 split) into a single schema, with CPV, value, region and keyword filters and a new-notices-only mode.

Pricing

from $2.10 / 1,000 results

Rating

0.0

(0)

Developer

Fatih İlhan

Fatih İlhan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 hours ago

Last modified

Categories

Share

One feed for UK public procurement notices. Since the Procurement Act 2023 came into force (24 February 2025), UK tenders are split across two government systems: Find a Tender (the above-threshold service, now with the new Act's notice types) and Contracts Finder (below-threshold and many central-government notices). This Actor reads both official OCDS APIs and returns them in a single, identical schema: planning/pipeline notices, tenders, awards and contracts, with buyer, value, CPV codes, region, deadline and supplier. No API key, no scraping, no HTML parsing.

Filter by keyword, CPV code, value, region and notice type, or turn on only-new mode and put it on an Apify schedule to get a daily feed of fresh notices.

Why it is built the way it is

  • Both sources, one schema. The same 24 fields for every notice, whichever service it came from. Missing data is null, never guessed.
  • If one source is down, you still get the other. A failing source is retried with exponential backoff and Retry-After handling; if it still fails, the other source's notices are returned, the run does not fail, and the failure is written to RUN_SUMMARY.
  • Complete, not "first page". Every page is read until the feed is exhausted. A run that stops early says so in RUN_SUMMARY (and onlyNew will not skip what was not read).
  • Server-side filters that lose notices are not used. Both APIs have a stages filter that silently drops notices (checked against the live feeds), so all filtering is done after fetching.
  • One record per call, even across the two services. The same tender is often published on both with different ids and slightly different titles; those are detected (buyer + title + deadline) and returned once, listing both sources.
  • Pay only for results. No placeholder rows, no error rows. Errors live in RUN_SUMMARY, not in your dataset.

Example inputs

IT and software opportunities from the last 24 hours (the default window; by default you get tender and planning notices)

{
"cpvCodes": ["72"]
}

Who won? Awarded contracts are opt-in: add award (and contract for contract details) to noticeTypes

{
"cpvCodes": ["72"],
"noticeTypes": ["award", "contract"],
"publishedFrom": "2026-10-01"
}

To get open tenders, pipeline and awards together, list every type: "noticeTypes": ["planning", "tender", "award", "contract", "implementation"]. In the Console, pick them in the "Notice types" box.

Everything from specific buyers (case-insensitive, partial match on the buyer name)

{
"buyers": ["Ministry of Defence", "Transport for London"],
"publishedFrom": "2026-09-01"
}

Contracts worth £100k or more

{
"minValue": 100000,
"noticeTypes": ["tender", "award"]
}

Daily new IT tenders (schedule this Actor to run every morning)

{
"cpvCodes": ["72"],
"onlyNew": true
}

Create an Apify Schedule (for example cron 0 7 * * *) for this input. The first run returns the last 24 hours (or whatever publishedFrom you set); every later run returns only what was published since. State is stored in the named key-value store uk-public-tenders-state under your account.

Input

All fields are optional.

FieldTypeMeaning
keywordsstring listTitle or description contains any of these (case-insensitive, from the start of a word: cyber matches cybersecurity).
cpvCodesstring listCPV prefix match, e.g. 72 = IT services, 72212 = application software, 45 = construction. Checks the notice's main and additional CPV codes.
publishedFrom / publishedTostringYYYY-MM-DD or ISO-8601 datetime (UTC if no zone). A bare publishedTo date includes the whole day. Default: the last 24 hours.
minValue / maxValueinteger (GBP)Keep notices whose value range overlaps this range. Notices that state no value are excluded when a value filter is set.
noticeTypeslistplanning, tender, award, contract, implementation. Default: tender + planning; awards and contracts are opt-in (see the example above).
buyersstring listBuyer (contracting authority) name contains any of these texts: case-insensitive, partial match (nhs, transport for london, council). Notices with no buyer name never match.
regionsstring listUK region names or NUTS codes (London, Scotland, UKI, UKD7). Names and codes match each other (against both region_code and region_name); England covers all nine English regions.
onlyNewbooleanOnly notices not returned by an earlier run with the same filters (new notices and new versions of known notices).
sourceslistfts, contracts_finder. Default: both.

To cap the number of results (and your spend), use the Apify "Maximum charged results" run option. The Actor returns at most that many notices, newest first, and reports in RUN_SUMMARY.truncation that it truncated and how many matches were left out.

Output

One dataset item per procurement (ocid). If the same procurement appears several times in the window (tender, then award, then amendments), the latest matching version is returned.

FieldDescription
notice_idNotice identifier (097437-2026 on Find a Tender, a UUID on Contracts Finder).
related_notice_idsNotice ids of same-source copies folded into this record (see "Known limitations"). Empty list when there are none.
sourceList: ["fts"], ["contracts_finder"], or both when the same ocid is in both services.
ocidOpen Contracting process id; stable across the notices of one procurement.
titleTitle exactly as published.
title_cleanThe title without leading reference prefixes such as CA18567 - , RFQ 2026/43 - , GB-Glasgow: or UK4 Tender Notice: (the original is in title).
descriptionNotice text. On Contracts Finder, an appended "Additional information:" section is dropped when it only repeats the main description, and kept when it adds something.
buyer_name, buyer_idContracting authority and its identifier.
notice_typeplanning, tender, award, contract or implementation.
statusProcurement status as published (active, complete, planned, ...).
published_dateUTC ISO-8601 publication time of the notice version.
deadline_dateTender submission deadline (UTC ISO-8601). null on award notices: a closed deadline is not an action date for an award.
tender_deadline_dateThe published submission deadline, kept on every notice type, including awards.
value_min, value_max, currencyValue as published (see "Known limitations").
cpv_codesAll CPV codes on the notice, main code first.
region_codeList of NUTS codes, e.g. ["UKK14"]. Contracts Finder region names are mapped to their NUTS1 code (Scotland -> UKM); non-UK codes such as CY are left as published. Empty list if unknown.
region_nameList of region names (NUTS1), e.g. ["South West"]; United Kingdom for a nationwide UK; England appears here only (it has no NUTS1 code). Empty list if unknown.
procedure_typeFor example "Open procedure", "Call-off from a framework agreement".
award_supplierAwarded supplier name(s), if any (several are separated by ; ).
urlThe notice page on Find a Tender / Contracts Finder, never an attachment/download link. On Find a Tender it is built from the notice id; on Contracts Finder it comes from the notice's own page link, so it is null in the rare case none is published.
source_urlThe API record the data was read from.
fetched_atWhen the Actor fetched it (UTC).

Example record (real, from a live run)

{
"notice_id": "cab39ee0-c192-4fb2-9253-472214e58ca7",
"related_notice_ids": [],
"source": [
"fts",
"contracts_finder"
],
"ocid": "ocds-b5fd17-4321ebe7-2ddb-47fa-81f9-fa095553b41b",
"title": "CA18567 - RFQ 2026/43 - Development of a Dublin Belfast Economic Corridor Investment Land Guide",
"title_clean": "Development of a Dublin Belfast Economic Corridor Investment Land Guide",
"description": "The DBEC Partnership wishes to appoint a suitably qualified and experienced consultant to produce an Investment Land Guide that will strengthen the Dublin Belfast Economic Corridor's investment proposition.\n\nTo access this competition: \n\nRegistered:\nLogin to https://suppliers.multiquote.com and v...",
"buyer_name": "Newry, Mourne and Down District Council (NMD)",
"buyer_id": "GB-CFS-333373",
"notice_type": "tender",
"status": "active",
"published_date": "2026-10-14T13:42:19Z",
"deadline_date": "2026-10-30T12:00:00Z",
"tender_deadline_date": "2026-10-30T12:00:00Z",
"value_min": null,
"value_max": 25000,
"currency": "GBP",
"cpv_codes": [
"79411100",
"72221000",
"73210000"
],
"region_code": [
"UK"
],
"region_name": [
"United Kingdom"
],
"procedure_type": "Open procedure",
"award_supplier": null,
"url": "https://www.contractsfinder.service.gov.uk/Notice/cab39ee0-c192-4fb2-9253-472214e58ca7",
"source_url": "https://www.contractsfinder.service.gov.uk/Published/Notices/OCDS/Search?publishedFrom=2026-10-12T12:00:00Z&publishedTo=2026-10-15T14:06:46Z&limit=100&cursor=cHVibGlzaGVkRnJvbT0yMDI2LTEwLTEyVDEyOjAwOjAwWnxwdWJsaXNoZWRUbz0yMDI2LTEwLTE1VDE0OjA2OjQ2WnxsaW1pdD0xMDB8bmV4dEN1cnNvcj03ODY3OTg=",
"fetched_at": "2026-10-15T14:06:49Z"
}

RUN_SUMMARY

Every run writes a RUN_SUMMARY record to the key-value store, including runs that return nothing or in which a source failed. For each source it reports pages and requests, releases fetched, how many were filtered out and why, how many were de-duplicated, retries and rate-limit responses, errors and duration; plus whether the run was truncated by the item limit, and the onlyNew state. A zero-result run can therefore always be told apart from "a source was down".

Known limitations

  • Long date ranges run slowly. The government APIs rate-limit clients: in testing, a burst of about 20 requests, then roughly 5 pages (up to 500 notices) a minute, and a 120-second pause each time the limit is hit. About 700 notices a day are published across both services, so one day takes seconds, a 3-day pull of everything took under a minute in testing, and a week or more can take several minutes or longer. Recommended use: a daily Apify schedule with onlyNew: true (see the example above). Each run then reads only what is new and finishes quickly. Use wide date ranges only for one-off backfills and narrow them with filters where you can.
  • Contracts Finder often has no region. Roughly half of its notices give only a postcode or country, so region_code / region_name are empty and they can never match a regions filter.
  • Some Find a Tender records have no CPV code. They cannot match a cpvCodes filter, so they will not appear in CPV-filtered results even if they concern that sector. (In testing about 3% of Find a Tender records had none, after reading CPV from lots, items and awards; Contracts Finder records always had one.)
  • Contracts Finder award values are tender values. For an award notice, value_min / value_max are the notice's tender-level figures (typically the estimated or framework value), not necessarily the amount finally awarded. Find a Tender award notices without a tender value fall back to the award or contract value, as a range, never summed.
  • Notices with no value never pass a value filter (minValue / maxValue); a non-GBP value does not either.
  • Notices re-published under a new id are folded into the newest one. Buyers sometimes publish the same notice twice within minutes (new notice id, new ocid, identical text). Within one service, notices with the same buyer id, title, description and type that were published within 48 hours of the newest one are returned as a single record; the older notice ids are listed in related_notice_ids. Deadlines and values are not compared, so two genuinely separate calls that reuse one text within 48 hours (for example lots published as separate notices) are also folded: check related_notice_ids if that matters to you.
  • Cross-source de-duplication is a match, not an id lookup. The two systems never share process ids, so a call published on both is recognised by the same buyer, the same title once reference prefixes are removed, the same tender-deadline day and the same notice type. This is deliberately strict: it applies to tender and planning notices only (awards repeat too often to be matched safely), and a copy whose title was reworded, or that has no deadline (most planning notices), is not matched and appears twice. A merged record keeps the later copy's fields and fills its gaps from the other.
  • Personal data is not output. Procurement officers' contact names and e-mails in the source data are deliberately left out.

Data source and licence

Data comes from the official OCDS APIs of:

Contains public sector information licensed under the Open Government Licence v3.0. This Actor is not affiliated with or endorsed by the UK Government. Notice content remains the responsibility of the publishing authority; check the notice itself before bidding.