# UK Contracts Finder Scraper: Tenders & Awards (`automation_craft/uk-contracts-finder-scraper`) Actor

Scrape UK Contracts Finder, no login: live tenders, early engagement, future opportunities and contract awards from the official API. Get buyer contacts, CPV codes, values, deadlines, winning suppliers with Companies House numbers and documents. Monitor new or changed notices, pay per notice.

- **URL**: https://apify.com/automation\_craft/uk-contracts-finder-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (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 $0.24 / 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 Contracts Finder Scraper: Tenders & Awards

This **UK Contracts Finder scraper** reads the official Contracts Finder API (contractsfinder.service.gov.uk, the UK government's register of public sector contracts) with no login, no API key and no proxy to configure. It returns every notice type Contracts Finder publishes: **live opportunities (tenders), early engagement, future opportunities and awarded contracts**, as flat, spreadsheet ready rows plus the complete Open Contracting (OCDS) release for developers.

What makes it different from a thin API wrapper:

- **Buyer contacts and winning suppliers in columns**: buyer contact name, email, phone and address as published; suppliers with **Companies House numbers**, SME and VCSE flags and award values.
- **Opportunity to award links**: an award is a separate notice on Contracts Finder. Every row carries the procurement's `ocid` and links to the other notices of the same procurement, so an award points to its original opportunity (`opportunityNoticeId`).
- **Filters Contracts Finder's feed does not have**: CPV codes and prefixes, keywords, regions, postcodes and postcode radius, value range, buyer and supplier names, Companies House numbers, SME and VCSE suitability, closing within N days, deadline and award dates, framework call-offs excluded.
- **A monitor that only returns what is new or changed** since the previous run, and never bills an unchanged notice twice.
- **Past the API's silent caps**: the OCDS feed stops after 2,100 releases and the search after 1,000 hits; this Actor continues past both and tells you in the run summary.
- **Polite by design**: Contracts Finder allows 12 calls per 2 minutes per IP. The Actor stays under that, so runs do not fail on rate limits.

### Quick start

1. Leave everything empty and press **Start**: you get the notices published in the last 7 days (the Console prefill asks for 3 days and 10 notices).
2. Narrow it down: pick **Notice types** (for example Opportunity), tick **Open notices only**, add **CPV codes** such as `72000000` for IT services or **Keywords** such as `cleaning`.
3. For bid alerts, add a **Monitoring memory name** such as `it-tenders-daily` and schedule the Actor daily: each run returns only new or changed notices.
4. Export the dataset as CSV, Excel or JSON, or call the Actor from the API, Make, Zapier, n8n or an AI agent (MCP).

Ready made example: [Open UK IT and software tenders](https://apify.com/automation_craft/uk-contracts-finder-scraper/examples/uk-contracts-finder-open-it-tenders) (open opportunities in CPV 72 and 48, with buyer, contact email, deadline and value).

### What you get

One row per notice (`type: "notice"`), one free `run-summary` row per run, and free `status` rows for anything the Actor could not do. Fill rates below were measured on 1,000 real rows (922 awards, 73 opportunities, 5 early engagement notices) from a platform run on 2026-09-29.

| field | what it is | filled |
|---|---|---|
| `noticeId`, `noticeUrl`, `releaseId`, `ocid` | Contracts Finder notice id and page, OCDS release and procurement id | 100% |
| `noticeType`, `status`, `isOpen` | early\_engagement, future\_opportunity, opportunity or award; OCDS status; still open | 100% |
| `title`, `description` | as published | 100% |
| `buyerName`, `buyerContactEmail`, `buyerPostcode` | buying organisation and contact | 100% |
| `buyerContactName` | contact person | 61% |
| `buyerContactPhone` | contact phone | 41% (more with notice details) |
| `cpvCode`, `cpvCodes`, `cpvDescription` | Common Procurement Vocabulary | 100% |
| `deadline`, `daysUntilDeadline` | tender or engagement deadline (awards keep the original tender deadline) | 100% |
| `contractStart`, `contractEnd`, `contractDurationDays` | contract period | 100% of opportunities and awards |
| `valueAmount`, `valueMin`, `currency`, `valueIsPlaceholder` | estimated value; 0 or 1 pound placeholders flagged | 85% (63% of opportunities) |
| `procurementMethodDetails` | for example Open procedure, Call-off from a framework agreement | 99% |
| `suitableForSme`, `suitableForVcse` | the buyer's suitability flags | 100% |
| `deliveryRegions`, `deliveryPostcodes`, `isNationwide` | where the work is delivered | regions 50%, postcodes 36% |
| `supplierNames`, `awardedValue`, `awardedAt`, `awards` | winning suppliers, value and date | 100% of awards |
| `supplierCompanyNumbers` | winners' Companies House numbers | 42% of awards |
| `documents`, `documentCount` | attachments and links (ITT, specifications, pricing schedules) | 68% of opportunities have at least one |
| `linkedNotices`, `opportunityNoticeId`, `awardNoticeIds` | other notices of the same procurement | depends on what this run and the memory saw |
| `changeType`, `firstSeenAt`, `previousReleaseId` | new, updated or unchanged against your memory | with a memory |
| `ocdsRelease` | the complete OCDS release as published | 100% (switch off with Include the full OCDS release) |

Example (shortened):

```json
{
    "type": "notice",
    "noticeId": "8c4ed675-8d90-4220-924c-8846c8f86df6",
    "noticeUrl": "https://www.contractsfinder.service.gov.uk/Notice/8c4ed675-8d90-4220-924c-8846c8f86df6",
    "ocid": "ocds-b5fd17-6699a7aa-1904-4ff9-9056-a40618fb86bd",
    "noticeType": "opportunity",
    "status": "active",
    "isOpen": true,
    "title": "Taxi and MPV (1-8 seats) Passenger Assistant",
    "buyerName": "East Sussex County Council",
    "buyerContactEmail": "procurement@eastsussex.gov.uk",
    "buyerPostcode": "BN7 1UE",
    "deadline": "2026-10-01T10:00:00.000Z",
    "daysUntilDeadline": 3,
    "cpvCode": "60000000",
    "cpvDescription": "Transport services (excl. Waste transport)",
    "procurementMethodDetails": "Restricted procedure (above threshold)",
    "suitableForSme": true,
    "suitableForVcse": false,
    "linkedNotices": [],
    "changeType": "new"
}
```

#### Notice details (optional)

Tick **Add notice details** to add what only the notice record carries: the buyer's phone and website, every attachment with its file name, supplier DUNS numbers and references, the version history and the view count. It is one extra call per notice and Contracts Finder allows about 5 calls a minute, so it is capped by **Maximum notices with details** (25 by default).

#### How monitoring works

With a **Monitoring memory name**, the Actor remembers every notice version it delivered. The next run reads from where the previous run ended (with a 6 hour overlap), skips unchanged notices free, and returns new notices and notices Contracts Finder republished with different content (`changeType: "updated"`). The memory also remembers every procurement it saw, so an award published weeks later is linked to its opportunity. A memory name belongs to this Actor and your account.

### How much does it cost to scrape Contracts Finder?

You pay per notice delivered, and nothing for filtered, duplicate or unchanged notices, status rows or the run summary.

| event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| Notice | $0.30 per 1,000 | $0.30 per 1,000 | $0.27 per 1,000 (10% off) | $0.24 per 1,000 (20% off) |
| Notice detail (optional) | $0.30 per 1,000 | $0.30 per 1,000 | $0.28 per 1,000 | $0.26 per 1,000 |
| Actor start | $0.001 per run | $0.001 per run | $0.001 per run | $0.001 per run |

Examples: a daily alert that finds 12 new opportunities costs about $0.0046 (start plus 12 notices); an export of 1,000 notices costs $0.30 plus $0.001. The Store pricing card shows "from $0.24 / 1,000 notices", the GOLD price; the FREE price is "$0.30 / 1,000", so one notice costs three hundredths of a cent.

### Input

All fields are optional. The most useful ones:

| field | example | meaning |
|---|---|---|
| `publishedWithinDays` | `7` | rolling window (default 7) |
| `publishedFrom`, `publishedTo` | `2026-09-01` | fixed window instead |
| `noticeTypes` | `["opportunity"]` | early\_engagement, future\_opportunity, opportunity, award |
| `openOnly` | `true` | deadline not passed |
| `keywords`, `excludeKeywords` | `["cleaning"]` | whole words in title or description |
| `cpvCodes` | `["72000000", "48"]` | CPV codes or prefixes |
| `regions`, `postcodes` | `["London"]`, `["LS"]` | delivery location |
| `nearPostcode`, `radiusMiles` | `"LS1 4AP"`, `10` | radius search |
| `minValue`, `maxValue` | `100000` | value range in GBP |
| `buyerNames`, `supplierNames`, `supplierCompanyNumbers` | `["NHS"]` | who buys, who won |
| `smeSuitableOnly`, `vcseSuitableOnly`, `excludeCallOffs` | `true` | suitability and procedure |
| `closingWithinDays` | `14` | deadline in the next N days |
| `noticeIds` | notice ids or URLs | direct lookup |
| `memoryName` | `"it-tenders-daily"` | new or changed since the last run |
| `maxResults` | `100` | notice rows per run |

**Search method.** `auto` (default) picks the path with fewer API calls: the OCDS feed for recent windows (every field, newest first), or Contracts Finder's own search for long windows with a keyword, buyer, supplier, CPV, region or radius filter, after which every hit is matched to its full OCDS release. A hit that has no matching release is delivered from the search summary and flagged `hydrated: false`.

#### API example

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~uk-contracts-finder-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"noticeTypes":["opportunity"],"openOnly":true,"cpvCodes":["72000000"],"maxResults":50}'
```

### What this Actor does NOT do

- It does not cover Find a Tender (the UK's above threshold service since the Procurement Act 2023), Public Contracts Scotland, Sell2Wales or eTendersNI. Contracts Finder is mostly below threshold opportunities and award transparency notices (about 45 opportunities and 700 awards a week in September 2026).
- It does not download attachment files; it returns their links and file names.
- It does not return bid counts: Contracts Finder does not publish them.
- An award is linked to its opportunity only when this run or your memory saw that opportunity.
- Contract values are what the buyer published; about a third of opportunities publish none.

### FAQ

#### What is Contracts Finder?

Contracts Finder is the UK government service where public bodies in England (and some UK wide bodies) publish contract opportunities and awarded contracts, typically for contracts above about 12,000 to 30,000 pounds. This Actor reads its official open API, published under the Open Government Licence.

#### Is there an official Contracts Finder API, and why use this Actor instead?

Yes, and this Actor uses it. The official OCDS feed has only date and stage filters, stops after 2,100 releases, and blocks callers who send more than 12 requests in 2 minutes. The Actor adds the filters, the paging past the caps, the rate limit handling, the flat columns, the award links and the monitoring memory.

#### Can I get Contracts Finder data in OCDS JSON format?

Yes: every row carries the complete OCDS release in `ocdsRelease`, next to the flattened fields.

#### How do I get alerts for new UK public sector tenders?

Set Notice types to Opportunity, tick Open notices only, add your CPV codes or keywords, give it a Monitoring memory name and schedule it daily. Each run returns only new or changed notices.

#### How can I see which companies win public contracts?

Choose the Awarded contract type and use Winning supplier names or Companies House numbers; every award row lists the suppliers, their Companies House numbers where published, SME flags and the awarded value.

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

It follows least privilege: it can only read and write its own storages. The monitoring memory is a named store the Actor creates for you on its first run with that name.

### More data tools by Automation Craft

- [UK EPC Register Scraper - Energy Certificates](https://apify.com/automation_craft/uk-energy-certificate-scraper)
- [UK Food Hygiene Ratings Scraper - FSA Register](https://apify.com/automation_craft/uk-food-hygiene-ratings-scraper)
- [US Building Permits Scraper - 38 City Sources](https://apify.com/automation_craft/us-building-permits-scraper)
- [Google News Scraper: Search, Topics, Decoded URLs](https://apify.com/automation_craft/google-news-scraper)
- [Workday Jobs Scraper & API - Whole Career Site](https://apify.com/automation_craft/workday-jobs-scraper)
- [Bulk WHOIS & RDAP Domain Lookup: DNS, SSL](https://apify.com/automation_craft/domain-whois-rdap-lookup)

### Changelog

- 0.1 (2026-09-29): first release.

# Changelog

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

# Actor input Schema

## `publishedWithinDays` (type: `integer`):

Rolling window of notices published or updated in the last N days. Ignored when Published from is set. With a monitoring memory, later runs start where the previous run ended instead. Example: 7.

## `publishedFrom` (type: `string`):

Start of the window, as YYYY-MM-DD or an ISO date and time (UK dates, BST aware). Leave empty to use Published in the last N days. An impossible date stops the run with a warning and no charge.

## `publishedTo` (type: `string`):

End of the window, as YYYY-MM-DD or an ISO date and time. Leave empty for now.

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

Contracts Finder's four notice types. Leave empty for all of them. API values: early\_engagement, future\_opportunity, opportunity, award.

## `openOnly` (type: `boolean`):

Only opportunities and engagement notices whose deadline has not passed. Awards are never open, so combine this with the opportunity type.

## `maxResults` (type: `integer`):

Stop after this many notice rows (new, changed and, with Also return unchanged known notices, the free unchanged ones together). Status and summary rows do not count and are free.

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

A notice matches when its title or description contains any of these words or phrases as whole words, case insensitive. Example: cleaning, facilities management. Use CPV codes to search by category.

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

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

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

Common Procurement Vocabulary codes. A padded code like 72000000 or a prefix like 722 matches that whole branch. Example: 72000000 for IT services, 45 for construction work.

## `excludeCpvCodes` (type: `array`):

Drop notices classified under any of these CPV codes or prefixes.

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

Keep notices delivered in any of these regions. Notices open to all of the UK are kept too unless you untick Include nationwide notices.

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

With a region filter, also keep notices that are open to every region or name no location.

## `postcodes` (type: `array`):

Match the delivery or buyer postcode. LS matches the whole Leeds area, LS1 one district, a full postcode one address.

## `nearPostcode` (type: `string`):

Keep notices within Radius miles of this postcode, using Contracts Finder's own search. Example: LS1 4AP.

## `radiusMiles` (type: `integer`):

Radius for Within a radius of postcode, 1 to 100 miles.

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

Keep notices whose value range reaches at least this amount. Awards are judged by the awarded value. Notices with no value are dropped unless Include notices with no value is ticked.

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

Keep notices whose value range starts at or below this amount.

## `includeUnknownValue` (type: `boolean`):

With a value filter, also keep notices that publish no value or a placeholder of 0 or 1 pound.

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

Keep notices whose buying organisation name contains any of these words or phrases as whole words, case insensitive. Example: NHS, Leeds City Council.

## `excludeBuyerNames` (type: `array`):

Drop notices whose buyer name contains any of these words or phrases as whole words.

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

Awards only: keep notices won by a supplier whose name contains any of these words or phrases as whole words (Capita does not match Capital). Useful for competitor and incumbent tracking.

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

Awards only: keep notices won by these Companies House numbers (leading zeros optional). Example: 02203474.

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

Keep only notices the buyer marked as suitable for small and medium enterprises.

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

Keep only notices the buyer marked as suitable for voluntary, community and social enterprises.

## `excludeCallOffs` (type: `boolean`):

Drop call-offs from framework agreements and dynamic purchasing systems (about 60 percent of awards), keeping competed contracts.

## `closingWithinDays` (type: `integer`):

Keep notices whose deadline is between now and N days from now. Example: 14.

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

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

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

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

## `awardedFrom` (type: `string`):

Awards only: keep contracts awarded on or after this date (YYYY-MM-DD).

## `awardedTo` (type: `string`):

Awards only: keep contracts awarded on or before this date (YYYY-MM-DD).

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

Fetch these notices directly (notice GUIDs or contractsfinder.service.gov.uk/Notice/... links). When set, the window and filters are not used.

## `includeNoticeDetails` (type: `boolean`):

One extra call per notice for what only the notice record carries: buyer phone and website, every attachment with its file name, supplier DUNS and reference, version history and view count. Billed per notice that returned details. Contracts Finder allows about 5 calls a minute, so this is capped by Maximum notices with details.

## `maxDetailNotices` (type: `integer`):

Upper limit for Add notice details, because each detail call takes about 12 seconds under Contracts Finder's rate limit.

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

Attach the complete Open Contracting release as published (ocdsRelease) next to the flattened fields. No extra cost.

## `linkRelatedNotices` (type: `boolean`):

Link every notice to the other notices of the same procurement (same OCDS ocid) seen in this run or remembered by the monitoring memory, so an award points to its original opportunity.

## `memoryName` (type: `string`):

Name a memory to turn the run into a monitor: each run returns only notices that are new or changed since the previous run with the same name, and unchanged ones are skipped free. Example: it-tenders-daily.

## `resetMemory` (type: `boolean`):

Forget everything stored under the memory name before this run.

## `emitUnchanged` (type: `boolean`):

With a memory, also return notices already delivered and unchanged, flagged changeType unchanged and never charged. They count toward Maximum notices.

## `searchMethod` (type: `string`):

auto picks the path with fewer API calls. feed reads the official OCDS feed (every field, best for recent windows). search uses Contracts Finder's own search first (best for long windows and postcode radius), then fetches the full release of each hit.

## `maxApiCalls` (type: `integer`):

Safety cap on calls to Contracts Finder in one run. Contracts Finder allows about 5 calls a minute, so 150 calls is about 30 minutes.

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

Not needed: Contracts Finder is an open government API. By default the run uses its own IP and switches to an Apify proxy session only if the IP is rate limited by someone else.

## Actor input object example

```json
{
  "publishedWithinDays": 3,
  "openOnly": false,
  "maxResults": 10,
  "includeNationwide": true,
  "radiusMiles": 10,
  "includeUnknownValue": false,
  "smeSuitableOnly": false,
  "vcseSuitableOnly": false,
  "excludeCallOffs": false,
  "includeNoticeDetails": false,
  "maxDetailNotices": 25,
  "includeOcdsRelease": true,
  "linkRelatedNotices": true,
  "resetMemory": false,
  "emitUnchanged": false,
  "searchMethod": "auto",
  "maxApiCalls": 150
}
```

# 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 = {
    "publishedWithinDays": 3,
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/uk-contracts-finder-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 = {
    "publishedWithinDays": 3,
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/uk-contracts-finder-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 '{
  "publishedWithinDays": 3,
  "maxResults": 10
}' |
apify call automation_craft/uk-contracts-finder-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/uk-contracts-finder-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/uxeI2eDKc25eGLgic/builds/9OQJX00Q9bpaKucae/openapi.json
