# UK Find a Tender Scraper: High-Value Public Contracts (`bogdiehard/uk-find-a-tender-scraper`) Actor

Pulls UK high-value public tenders, contract awards and planning notices from the official Find a Tender API, with lots, buyer contacts, CPV codes, values, deadlines and winning suppliers.

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

## Pricing

from $1.96 / 1,000 results

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: High-Value Public Contracts

Returns UK high-value public tenders, contract awards and planning notices from the official Find a Tender API as flat JSON, with lots, buyer contacts, CPV codes, values, deadlines and winning suppliers, for bid teams, B2B sales and analysts who track large public contracts.

### Use cases

- **Bid teams:** get a daily list of new above-threshold tenders that match your services by keyword, CPV code and value band, with lot counts and deadlines.
- **B2B sales:** find public buyers that spend in your category, using buyer name, locality and CPV code, then contact them through the procurement contact published on the notice.
- **Competitor intelligence:** track which suppliers win large contracts in your sector, with award dates and, where published, award values.
- **Merged public-contract feeds:** load this Actor together with the UK Contracts Finder Scraper into one table, since the two use the same field names.
- **Market analysts:** count lots and legal basis (`lotCount`, `legalBasis`) to see how large contracts are split and under which procurement rules.

### Sample output

| Title | Buyer | Value (GBP) | CPV code | Lots | Deadline |
| --- | --- | --- | --- | --- | --- |
| The Provision of Investment Management Services for the Scottish Universities Fund Ignition Strategy | Scottish National Investment Bank | 6500000 | 66100000 | 1 | 2026-11-10 |
| Experts at Hand: Occupational Therapy, Inclusion and Participation Services | Norfolk County Council | not published | 85323000 | 1 | 2026-11-13 |
| Out of Home Advertising for Bus Stations and Shelters | Strathclyde Partnership for Transport | 10000000 | 79340000 | 1 | 2026-11-13 |

One item as JSON, from a live run (the description is shortened here):

```json
{
    "id": "ocds-h6vhtk-0784ff",
    "noticeId": "095775-2026",
    "releaseId": "095775-2026",
    "stage": "tender",
    "title": "The Provision of Investment Management Services for the Scottish Universities Fund Ignition Strategy",
    "description": "The Bank is seeking proposals from suitably qualified and authorised investment management firms to establish and manage a 15 million GBP segregated investment …",
    "status": "active",
    "buyerName": "Scottish National Investment Bank",
    "buyerId": "GB-FTS-12628",
    "buyerLocality": "Edinburgh",
    "buyerPostalCode": "EH1 3EG",
    "buyerCountry": "United Kingdom",
    "contactName": null,
    "contactEmail": "procurement@thebank.scot",
    "contactPhone": null,
    "procurementMethod": "Open procedure",
    "mainCategory": "services",
    "cpvCode": "66100000",
    "cpvDescription": "Banking and investment services",
    "additionalCpvCodes": ["66100000"],
    "valueAmount": 6500000,
    "valueCurrency": "GBP",
    "publishedAt": "2026-10-09T14:37:16.000Z",
    "deadline": "2026-11-10T12:00:00.000Z",
    "contractStart": null,
    "contractEnd": null,
    "smeSuitable": null,
    "vcseSuitable": null,
    "deliveryPostalCode": null,
    "awardedSuppliers": [],
    "awardValue": null,
    "awardDate": null,
    "noticeUrl": "https://www.find-tender.service.gov.uk/Notice/095775-2026",
    "sourceUrl": "https://www.find-tender.service.gov.uk/Notice/095775-2026",
    "scrapedAt": "2026-10-11T01:08:23.742Z",
    "lotCount": 1,
    "legalBasis": "32014L0024",
    "submissionUrl": "http://www.publiccontractsscotland.gov.uk/"
}
```

### Pricing

**$2.80 per 1,000 results.** A 500-result run costs about $1.40. You pay only for results saved to your dataset, plus Apify's standard start fee of $0.00005 per run. Apify Silver and Gold plan users get lower per-result prices automatically.

Set **Max results** to cap what a run can cost. The Actor stops cleanly when it reaches your spending limit.

### Input

See the input tab for the full configuration. The fields are:

| Field | Type | Description |
| --- | --- | --- |
| `stages` | array | Notice stages: `tender` (open opportunities, default), `award` (contract awards) or `planning` (early market engagement). |
| `updatedFrom` | string | First update date, `YYYY-MM-DD`. The API filters on when a notice was last updated. Dates are interpreted in UTC. Empty means 7 days before the run. |
| `updatedTo` | string | Last update date, `YYYY-MM-DD`, included in full. Dates are interpreted in UTC. Empty means the time of the run. |
| `keywords` | array | Keep notices whose title or description contains any of these words, case-insensitive. |
| `cpvPrefixes` | array | Keep notices whose main or additional CPV code starts with any of these digits, for example `72` for IT services. |
| `minValue` | integer | Keep notices worth at least this many pounds. Notices with no published value are dropped when a value filter is set. |
| `maxValue` | integer | Keep notices worth at most this many pounds. Notices with no published value are dropped when a value filter is set. |
| `onlyOpen` | boolean | Tender notices only: keep status `active` with a deadline in the future. |
| `maxItems` | integer | Maximum number of results to return, from 1 to 100,000. Default 100. |
| `proxyConfiguration` | object | Off by default. The API is open, so you normally do not need a proxy. |

Filters run after the data is read. Notices that a filter removes are not saved and not charged.

Example input (the daily test):

```json
{
    "stages": ["tender"],
    "maxItems": 20
}
```

Example input for open software tenders worth at least £50,000 updated since 1 September 2026:

```json
{
    "stages": ["tender"],
    "keywords": ["software"],
    "minValue": 50000,
    "onlyOpen": true,
    "updatedFrom": "2026-09-01",
    "maxItems": 100
}
```

### Integrations

- **API:** run the Actor and fetch results with the [Apify API](https://docs.apify.com/api/v2) or the JavaScript and Python clients.
- **AI agents:** call it as a tool through the [Apify MCP server](https://mcp.apify.com).
- **No-code:** connect it to Make, Zapier or n8n, or export results straight to Google Sheets.
- **Scheduling:** run it daily with Apify Schedules. Each run reads the last 7 days by default, so you get only recent notices.

### FAQ

**What are the limits?** Each API page holds up to 100 notices, and a run reads pages until it reaches **Max results** or runs out of notices. In a 1,000-result test the Actor made 10 requests with no failures. The Find a Tender developer page does not publish a rate limit. If the API returns HTTP 429, the Actor waits for the time the API gives and then retries. Filters are applied after the read, so a narrow filter over a long date range reads more pages and takes longer.

**Why does a procurement appear more than once?** One procurement (`id`, the OCDS ID) can have more than one notice, for example a tender and its later update. In a 1,000-result test there were 989 distinct procurements, and every `releaseId` was unique. Use `releaseId` or `noticeId` to count notices once each.

**Why are the SME and VCSE flags empty?** The Find a Tender feed in this Actor does not carry the buyer's SME or VCSE suitability flags. In a 1,000-result test none of the notices had them, so `smeSuitable` and `vcseSuitable` are `null`. They stay in the output so rows line up with our UK Contracts Finder Actor when you merge both feeds.

**Why is some value empty, and why might a value look low?** `valueAmount` comes from the notice, or from its first lot when the notice has no total. Many notices have no published value. For a multi-lot notice where only lot 1 has a value, `valueAmount` is that lot's value, not the total. Use `lotCount` to see whether this applies.

**How are award values and dates filled?** On the award stage, `awardedSuppliers` lists the suppliers from the award. `awardValue` comes from the award, or from the single contract that has a value. It stays `null` when several contracts carry values. `awardDate` is the award date when the feed gives one; otherwise it is the signing date of the first contract.

**Why does a planning-and-tender notice show stage "planning"?** The API tags some notices with two stages. `stage` is the first tag, so a notice tagged `planning+tender` shows `planning`. In a tender-stage 1,000-result test, 21 items came back with stage `planning`.

**Is this legal?** The Actor collects public data only, from the official Find a Tender open-data API. It needs no login, no account cookies and no CAPTCHA solving, and it crawls politely. It is not affiliated with, endorsed by or connected to Find a Tender, the Cabinet Office or the UK Government. Notice data is published under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). You are responsible for how you use it.

Buyer contact names, emails and phone numbers are personal data when they belong to a person. They come from what the buyer published on the notice, and the Actor does not look them up or enrich them. Check your UK GDPR and PECR obligations before you use them for outreach.

**Something broke or a field is missing?** Open an issue on the Actor's Issues tab. We answer within one business day and usually ship a fix within 48 hours.

### Related Actors

- [UK Contracts Finder Scraper: Public Tenders & Awards](https://apify.com/bogdiehard/uk-contracts-finder-scraper): the same field names for lower-value notices from Contracts Finder, so you can merge both feeds.

### Changelog

- **0.1** (2026-10-10): First release. Tender, award and planning stages; keyword, CPV, value and open-tender filters; lots, legal basis and submission link.

# Actor input Schema

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

Notice stages to collect: open opportunities (tender), contract awards (award) or early market engagement (planning). Each stage is one API request chain.

## `updatedFrom` (type: `string`):

First update date to include, as YYYY-MM-DD. The API filters on when a notice was last updated. Dates are interpreted in UTC. Leave empty for 7 days before the run.

## `updatedTo` (type: `string`):

Last update date to include, as YYYY-MM-DD (the whole day is included). Dates are interpreted in UTC. Leave empty for the time of the run.

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

Keep notices whose title or description contains ANY of these words (case-insensitive). Leave empty to keep all notices.

## `cpvPrefixes` (type: `array`):

Keep notices whose main or additional CPV code starts with ANY of these digits, for example 72 for IT services or 45 for construction.

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

Keep notices worth at least this many pounds. Notices with no published value are dropped when a value filter is set.

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

Keep notices worth at most this many pounds. Notices with no published value are dropped when a value filter is set.

## `onlyOpen` (type: `boolean`):

Tender notices only: keep those with status active and a deadline in the future. Award and planning notices are not affected.

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

Maximum number of results to return. You are charged per result, and the run stops at this number.

## `proxyConfiguration` (type: `object`):

Not needed for this official open-data API, so it is off by default. Turn it on only if the API blocks your requests.

## Actor input object example

```json
{
  "stages": [
    "tender"
  ],
  "onlyOpen": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `stats` (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 = {
    "stages": [
        "tender"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bogdiehard/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 = {
    "stages": ["tender"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("bogdiehard/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 '{
  "stages": [
    "tender"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call bogdiehard/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,bogdiehard/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/nhSs6Hc8aD366bYtA/builds/NcvIcgIc3B4uEVHhb/openapi.json
