# UK Find a Tender Scraper: Tenders, Awards, Buyers (`automation_craft/uk-find-a-tender-scraper`) Actor

Scrape UK public tenders and contract awards from Find a Tender, the official government service, with no login or API key. Each notice: buyer and contact, value, deadline, CPV, region, notice type, lots, suppliers with Companies House numbers, documents. Filter, monitor new notices, pay per notice.

- **URL**: https://apify.com/automation\_craft/uk-find-a-tender-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 notices

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### UK Find a Tender Scraper: Tenders, Awards, Buyers

**Scrape UK public sector tenders and contract awards from Find a Tender**, the official UK government procurement service, through its open OCDS API. Every notice comes back as one clean, flat record for bid teams (title, buyer, value, deadline, CPV, region, lots, suppliers, documents) plus the complete official OCDS release for developers. No login, no API key, no browser.

Built for supplier lead generation, bid monitoring and public sector market research: filter by CPV code, keyword, region, value, buyer, supplier, notice type, stage, deadline and SME or VCSE suitability, or name a monitor and get only the notices that are new since your last run.

### Quick start

1. Leave **Days back** at 3 (or set **Date from** and **Date to**).
2. Pick **Notice types**, for example `UK4` (tender notices = open opportunities), or leave it empty for everything.
3. Add filters: **CPV codes** such as `72000000` (IT services), **Regions** such as `London`, **Minimum value**, **Keywords**.
4. Set **Maximum notices** (each delivered notice is one paid result).
5. Click **Start**, then export JSON, CSV or Excel, or call the Actor through the API, a schedule or an MCP client.

An empty input `{}` scans the last 7 days and returns up to 100 notices.

Ready-made example: [Find open IT tenders in London](https://apify.com/automation_craft/uk-find-a-tender-scraper/examples/uk-find-a-tender-open-it-tenders-london) (UK4 notices, IT CPV codes, London, still open for bids).

### What you get

One row per published notice. Measured on 2,233 notices published 2026-09-22 to 2026-09-28 (every notice of that week, ids 089389 to 091621 with no gaps):

| Field | What it is | Filled |
|---|---|---|
| `noticeId`, `noticeUrl`, `ocid` | Notice id, link to the notice page, procurement id shared by every notice of one procurement | 100% |
| `noticeType`, `noticeTypeName` | Procurement Act 2023 code and name (UK4 Tender notice, UK6 Contract award notice, ...); null for notices under the 2015 regulations (`legacyRegime: true`) | 85% |
| `stage`, `releaseTags`, `isUpdate`, `regime` | planning, tender, award or contract; OCDS tags; whether the notice changes an earlier one; legal regime | 100% |
| `title`, `description` | Full title and description, never cut | 100%, 96% |
| `buyerName`, `buyerEmail`, `buyerTelephone`, `buyerPostcode`, `buyerType`, `buyer` | Contracting authority with contact, address, PPON id and organisation type | 100% (name, email) |
| `valueAmount`, `valueAmountGross`, `currency`, `valueSource` | Value excluding and including VAT, and whether it is the tender estimate, the lot total or the awarded total | 78% (83% of UK4) |
| `cpvCodes`, `cpvMain`, `cpvDetails` | Every CPV code on the notice, its lots and items, with descriptions | 96% |
| `regions`, `regionNames` | NUTS / ITL delivery regions and their names | 75% (82% of UK4) |
| `tenderDeadline`, `enquiryDeadline`, `expressionOfInterestDeadline`, `engagementDeadline` | Deadlines in ISO 8601 UTC | 90% of UK4 |
| `daysUntilDeadline`, `isOpenForBids` | Days left at run time; whether the tender is still open | 100% of UK4 |
| `submissionUrl` | Where to bid (the buyer's e-tendering portal) | 89% of UK4 |
| `suitableForSme`, `suitableForVcse` | True when a lot is marked suitable for SMEs or VCSEs | 72% of UK4 carry the SME flag |
| `lots` | Every lot: title, value, SME and VCSE flags, contract period, renewal, options, award and selection criteria | 96% |
| `awards` | Every award: value, date, status, suppliers, standstill end, contract period | 100% of UK6 and UK7 |
| `suppliers`, `supplierNames`, `supplierCompaniesHouseNumbers` | Every supplier with Companies House number and link, PPON, charity number, scale (sme or large), VCSE flag, address and contact email | 100% of UK6 and UK7 (Companies House number on 60%) |
| `contracts` | Contract value, date signed, period, final value, termination reasons | UK7, UK10, UK11 |
| `documents`, `attachmentCount` | Notice links and tender document attachments with type, format and publication date | 85% |
| `amendments`, `relatedProcesses`, `bidsReceived` | Changes listed in the notice, linked framework procurements, number of bids received | where published |
| `ocdsRelease` | The complete official OCDS release (every field Find a Tender publishes) | 100% (turn off with Include the full OCDS release) |

With **Link every notice of the procurement** on, each row also gets `processNotices` (every notice of that procurement in date order), `originalNoticeId`, `previousNoticeId` and `laterNoticeIds`, so an amendment, award or termination is tied back to the original tender.

A final `summary` row (free) reports the window scanned, pages, notices scanned, delivered and charged, notices removed by each filter, and the API's own answers.

### How much does it cost to scrape Find a Tender?

Pay per notice delivered, plus a small fee for the notices the Actor reads through while it applies your filters (the official API has no search, so a narrow filter over a long window reads thousands of notices to find a few). Duplicates, notices your monitor has already seen, status rows and the summary are free as notices.

| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| Notice, per 1,000 | $0.50 | $0.50 | $0.45 | $0.40 |
| Scanned notice, per 1,000 | $0.01 | $0.01 | $0.01 | $0.01 |
| Actor start, per run (256 MB) | $0.002 | $0.002 | $0.002 | $0.002 |

SILVER is 10% off and GOLD 20% off the Notice price; the scanned notice and Actor start prices are the same on every plan.

The Store pricing card shows these prices per 1,000 events: "$0.50 / 1,000" on the Notice row means one notice costs a twentieth of a cent. Examples at the BRONZE tier: every notice of one week (about 2,200) costs about $1.14; a daily monitor that reads a day of Find a Tender (about 400 notices) and delivers 20 new ones costs about $0.016 a day; a 30 day search that reads 9,200 notices to find 60 costs about $0.12.

### Input

- **What to scan:** `daysBack` (default 7) or `dateFrom` / `dateTo`; or `noticeIds` (notice ids like `091621-2026`, procurement ids like `ocds-h6vhtk-06dce3`, or notice URLs).
- **Filters (run in the Actor):** `noticeTypes` (UK1 to UK17, LEGACY), `stages` (planning, tender, award, contract), `includeUpdates`, `keywords`, `excludeKeywords`, `cpvCodes` (codes or prefixes, `72000000` keeps the whole IT services branch), `regions` (NUTS or ITL codes, or names like London, Wales, England), `includeNationwide`, `minValue`, `maxValue`, `buyerNames`, `supplierNames`, `supplierCompanyNumbers`, `procurementCategories`, `smeSuitableOnly`, `vcseSuitableOnly`, `aboveThresholdOnly`, `openForBidsOnly`, `deadlineWithinDays`, `deadlineFrom`, `deadlineTo`.
- **Monitoring and output:** `monitorName`, `resetMonitor`, `includeProcessHistory`, `includeOcdsRelease`, `maxItems`, `maxPagesToScan`, `useApifyProxy`.

Example: open IT tenders in London worth at least 100,000 pounds, closing in the next 30 days:

```json
{
    "daysBack": 30,
    "noticeTypes": ["UK4"],
    "cpvCodes": ["72000000", "48000000"],
    "regions": ["London"],
    "minValue": 100000,
    "deadlineWithinDays": 30
}
```

### Monitoring: only new or changed notices

Set `monitorName` (for example `it-tenders-london`) and schedule the Actor daily. Each run scans from where the last complete run stopped (with a two hour overlap) and delivers only notices it has not delivered before under that name, marked `changeType: "new"`, or notices whose content changed, marked `"changed"`. Known notices are skipped and never charged again as notices. If a run stops early (Maximum notices or your spending limit), the next run rescans the same window, so nothing is skipped. Two runs on one monitor name at the same time are not allowed: the second one delivers its notices free and remembers nothing. If you change a monitor's filters, the next run also rescans the Days back window so notices the old filters removed are not missed. With a moving deadline window (`deadlineWithinDays`), notices that close later than the window are remembered and delivered on the run when their deadline comes inside it. A monitor remembers every notice it has delivered, for good; a monitor of every Find a Tender notice grows by about 5 MB a year, and a memory that grows past the storage limit makes runs free until it is reset or split.

### How it works with the Find a Tender API

- The official API allows 12 requests per two minutes per IP. The Actor waits 11 seconds between requests, honours the service's Retry-After answer, and uses one Apify datacenter IP for the whole run. It scans about 545 notices a minute: one day takes about a minute, a month about 25 minutes.
- The API's own stage filter returns only notices under the 2015 regulations, so stages are filtered in the Actor instead. Tools that pass the stage filter to the API miss almost every Procurement Act 2023 notice.
- The API reads its date window in UK local time; the Actor converts your UTC dates, and checks the window the API echoes back.

### What this Actor does NOT do

- It covers Find a Tender only. Contracts Finder (lower value English contracts) is a separate service.
- It does not download or read attachment files; it lists their links.
- Value filters drop notices that publish no value.
- Scotland, Wales and Northern Ireland notices are included only where their buyers publish on Find a Tender.

### FAQ

#### What is the difference between Find a Tender and Contracts Finder?

Find a Tender is the UK service for higher value public procurement notices across the whole UK, and the one the Procurement Act 2023 notices (UK1 to UK17) are published on. Contracts Finder lists lower value contracts in England. This Actor scrapes Find a Tender.

#### Which notice types can I filter?

Every Procurement Act 2023 type Find a Tender publishes: UK1 pipeline, UK2 preliminary market engagement, UK3 planned procurement, UK4 tender, UK5 transparency, UK6 contract award, UK7 contract details, UK9 contract performance, UK10 contract change, UK11 contract termination, UK12 procurement termination, UK13 to UK16 dynamic market notices, UK17 payments compliance, plus LEGACY for notices under the 2015 and 2016 regulations.

#### How do I get only open tenders I can still bid for?

Set `noticeTypes` to `UK4` and turn on `openForBidsOnly`, or use `deadlineWithinDays` for a closing window. Each row has `tenderDeadline` in ISO 8601 UTC, `daysUntilDeadline` and `submissionUrl`.

#### Can I track which companies win contracts?

Yes. Award and contract notices (UK6, UK7) list every supplier with name, Companies House number where published, scale (SME or large) and contact. Filter by `supplierNames` or `supplierCompanyNumbers` to follow a competitor.

#### Is the data official and can I reuse it?

It comes straight from the Find a Tender OCDS API run by the Cabinet Office, published under the Open Government Licence v3.0.

#### Why does this Actor run with limited permissions?

Least privilege: it only reads and writes its own run storage, plus the monitor memory, which is a named key-value store the Actor creates for your monitor name the first time you use it.

### More data tools by Automation Craft

- [UK Food Hygiene Ratings Scraper - FSA Register](https://apify.com/automation_craft/uk-food-hygiene-ratings-scraper)
- [UK EPC Register Scraper - Energy Certificates](https://apify.com/automation_craft/uk-energy-certificate-scraper)
- [US Building Permits Scraper - 38 City Sources](https://apify.com/automation_craft/us-building-permits-scraper)
- [US New Business Registrations Scraper - LLC Leads](https://apify.com/automation_craft/us-new-business-registrations-scraper)
- [Google News Scraper: Search, Topics, Decoded URLs](https://apify.com/automation_craft/google-news-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation\_craft/uk-find-a-tender-scraper/changelog.md

# Actor input Schema

## `daysBack` (type: `integer`):

Scan notices published or updated in the last N days (used when Date from is empty). Example: 7. One day is about 400 notices.

## `dateFrom` (type: `string`):

Start of the window, YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS (UTC). Overrides Days back. Find a Tender starts on 2021-01-01.

## `dateTo` (type: `string`):

End of the window, YYYY-MM-DD (whole day, UTC) or YYYY-MM-DDTHH:MM:SS. Empty means now.

## `noticeIds` (type: `array`):

Fetch these notices directly instead of scanning a window: notice ids like 091621-2026, procurement process ids (ocids) like ocds-h6vhtk-06dce3 (returns every notice of that process), or Find a Tender notice URLs. Filters are not applied to this list.

## `stages` (type: `array`):

Keep notices at these stages of the procurement: planning (UK1 to UK3), tender (UK4, UK12), award (UK5, UK6) or contract (UK7, UK9 to UK11). Filtered in the Actor, because the API's own stage filter returns only legacy notices. Empty means all.

## `noticeTypes` (type: `array`):

Keep only these Procurement Act 2023 notice types. LEGACY keeps notices published under the 2015 and 2016 regulations. Empty means all types.

## `includeUpdates` (type: `boolean`):

Keep notices that change an earlier notice (revised tender notices, cancellations, contract changes). Off keeps only first publications.

## `keywords` (type: `array`):

Keep notices whose title, description or lot text contains at least one of these words or phrases (case insensitive, matched at word starts, so "ai" does not match "maintenance"). Example: cleaning, software.

## `excludeKeywords` (type: `array`):

Drop notices whose title, description or lot text contains any of these words or phrases.

## `cpvCodes` (type: `array`):

Keep notices with at least one matching CPV code. A full code with trailing zeros means its whole branch (72000000 keeps every IT service code); a prefix like 4521 works too. Check digits (-5) are ignored.

## `regions` (type: `array`):

Keep notices delivered in these places: NUTS or ITL codes of any level (UKI, UKH11, TLH1) or names (London, Wales, Scotland, England, Northern Ireland, South East). The buyer's region is used when a notice names no delivery region.

## `includeNationwide` (type: `boolean`):

When a region filter is set, also keep notices delivered across the whole UK (region code UK).

## `minValue` (type: `integer`):

Keep notices whose estimated or awarded value (excluding VAT where given) is at least this. Notices without a value are dropped when a value filter is set.

## `maxValue` (type: `integer`):

Keep notices whose value is at most this.

## `buyerNames` (type: `array`):

Keep notices whose buyer name contains one of these texts, for example NHS, Council, Ministry of Defence.

## `supplierNames` (type: `array`):

Keep award and contract notices naming a supplier that contains one of these texts. Use it to track a competitor's wins.

## `supplierCompanyNumbers` (type: `array`):

Keep notices naming a supplier with one of these Companies House numbers (8 characters, leading zeros optional).

## `procurementCategories` (type: `array`):

Keep notices whose main category is one of these.

## `smeSuitableOnly` (type: `boolean`):

Keep notices where at least one lot is marked suitable for small and medium enterprises.

## `vcseSuitableOnly` (type: `boolean`):

Keep notices where at least one lot is marked suitable for voluntary, community and social enterprises.

## `aboveThresholdOnly` (type: `boolean`):

Keep notices for contracts above the procurement thresholds.

## `openForBidsOnly` (type: `boolean`):

Keep tender notices whose submission deadline is still in the future.

## `deadlineWithinDays` (type: `integer`):

Keep notices whose tender or expression of interest deadline falls between now and N days from now.

## `deadlineFrom` (type: `string`):

Keep notices whose deadline is on or after this date (YYYY-MM-DD, UTC).

## `deadlineTo` (type: `string`):

Keep notices whose deadline is on or before this date (YYYY-MM-DD, whole day, UTC).

## `monitorName` (type: `string`):

Give a schedule a name, for example it-tenders-london, and every run returns only notices that are new or changed since the last run with that name. The scan continues where the last complete run stopped. Known notices are not delivered or charged again.

## `resetMonitor` (type: `boolean`):

Forget what the monitor has seen, so this run treats every notice in the window as new.

## `includeProcessHistory` (type: `boolean`):

Look up the whole procurement process of each delivered notice and add processNotices, originalNoticeId and previousNoticeId (links an amendment or award to the original tender). One extra API call per procurement, so runs are slower. No extra charge.

## `includeOcdsRelease` (type: `boolean`):

Attach the complete official OCDS release (every field Find a Tender publishes) as ocdsRelease next to the flat fields.

## `maxItems` (type: `integer`):

Stop after delivering this many notices. Each delivered notice is one paid result.

## `maxPagesToScan` (type: `integer`):

Safety cap on API pages of 100 notices each (about 11 seconds per page, the service's rate rule). 300 pages is about 30,000 notices, roughly 10 weeks.

## `useApifyProxy` (type: `boolean`):

Send this run's requests from one Apify datacenter IP held for the whole run (recommended), falling back to the container IP if the proxy fails.

## Actor input object example

```json
{
  "daysBack": 3,
  "noticeTypes": [
    "UK4"
  ],
  "includeUpdates": true,
  "includeNationwide": true,
  "smeSuitableOnly": false,
  "vcseSuitableOnly": false,
  "aboveThresholdOnly": false,
  "openForBidsOnly": false,
  "resetMonitor": false,
  "includeProcessHistory": false,
  "includeOcdsRelease": true,
  "maxItems": 10,
  "maxPagesToScan": 300,
  "useApifyProxy": true
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "daysBack": 3,
    "noticeTypes": [
        "UK4"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/uk-find-a-tender-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "daysBack": 3,
    "noticeTypes": ["UK4"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/uk-find-a-tender-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "daysBack": 3,
  "noticeTypes": [
    "UK4"
  ],
  "maxItems": 10
}' |
apify call automation_craft/uk-find-a-tender-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/uk-find-a-tender-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/GMdHaQSd2ovK0ercx/builds/J4EzWw65qIp3tf3PP/openapi.json
