# UK Public Tenders & Awards (Contracts Finder, Find a Tender) (`velveteen_driver/uk-public-tenders`) Actor

Search new UK public-sector tenders and contract awards from Contracts Finder and Find a Tender in one run. Filter by keyword, CPV code, buyer, value, deadline and SME suitability. Official open OCDS APIs, Open Government Licence, personal contact details removed.

- **URL**: https://apify.com/velveteen_driver/uk-public-tenders.md
- **Developed by:** [Elliott](https://apify.com/velveteen_driver) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 notice saveds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Public Tenders & Awards (Contracts Finder, Find a Tender)

Find new UK public-sector opportunities and contract awards in one run. The actor reads both official UK notice services
through their open OCDS APIs and gives you one clean table:

- **Contracts Finder**: England's lower-value and below-threshold tenders and awards
- **Find a Tender**: UK-wide higher-value notices (Procurement Act 2023 and older regimes)

Filter by keyword, CPV code, buyer name, value, open deadline and SME suitability. Schedule it daily with **Days back = 1**
to get a daily digest of new opportunities in your sector.

### Use it for

- **Bid teams and SMEs**: a daily list of new tenders that match your services, with deadline, value and a link to the notice.
- **Market research**: which councils, trusts and departments buy what, and at what value.
- **Competitor tracking**: recent contract awards in your sector and the organisations that won them.

### Example input

```json
{
  "keywords": ["cleaning", "facilities management"],
  "cpvCodes": ["9091"],
  "stage": "tender",
  "openOnly": true,
  "daysBack": 7,
  "maxResults": 200
}
```

### Output fields

`source`, `noticeId`, `ocid`, `stage` (tender, tenderUpdate, award, contract, planning...), `title`, `description`, `buyerName`,
`buyerId`, `buyerTown`, `buyerPostcode`, `buyerRegion`, `buyerCountry`, `buyerWebsite`, `deliveryRegions`, `cpvCodes`,
`cpvDescriptions`, `mainCategory`, `procurementMethod`, `status`, `valueAmount`, `valueCurrency`, `awardValue`, `awardCurrency`,
`awardDate`, `suppliers`, `suppliersNotShown`, `tenderDeadline`, `contractStart`, `contractEnd`, `suitableForSme`,
`suitableForVcse`, `publishedAt`, `noticeUrl`, `licence`, `licenceUrl`.

Each saved notice is one charged event (`notice`). Notices that don't match your filters are read but not saved or charged.

### How filtering works

- The APIs return every notice in the date window; the actor applies your filters and saves only the matches.
- **Keywords** match the title, description and buyer name (any keyword, not case sensitive).
- **CPV codes** are prefixes: `72` matches every IT services code, `90919` matches office and school cleaning.
- **Value** filters use the estimated value, or the awarded value when there is no estimate. Notices without a value are
  dropped when a value filter is set.
- **Days back** covers notices published (Contracts Finder) or published or updated (Find a Tender) in the window, up to 31 days.
  The same tender can appear more than once if it was updated (each update is its own notice with its own `noticeId`).

### Limits

- Up to 31 days back per run. Requests are made one at a time with a pause between them, so a long window with no filters
  takes a few minutes.
- Values, CPV codes and deadlines are only as complete as the buyer made them. Some notices have no value or deadline.
- The bid documents themselves are not downloaded; follow `noticeUrl` to the official notice.

### Data source and licence

- Contracts Finder OCDS search API (https://www.contractsfinder.service.gov.uk/apidocumentation/home) and the
  Find a Tender OCDS API (https://www.find-tender.service.gov.uk/Developer/Documentation). Both are public, documented
  and need no key. Their terms say content can be reproduced under the Open Government Licence and that they make content
  available "through feeds for other websites and applications to use".
- **Contains public sector information licensed under the Open Government Licence v3.0**
  (https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). Every row carries this attribution in the
  `licence` field, and each run saves a `LICENCE` record in its key-value store.
- This is an unofficial tool. It is not affiliated with or endorsed by the Cabinet Office, Crown Commercial Service,
  Contracts Finder or Find a Tender. Data is reformatted and filtered, provided as is, with no warranty: check the official
  notice before you rely on it or bid.

### Personal data and responsible use

- Personal data is not covered by the Open Government Licence, so the actor removes it:
  - buyer and supplier contact points (names, emails, phone numbers) are never output
  - titles and descriptions are cleaned: email addresses (also `name @ domain`, `name(at)domain` and `name at domain dot com` forms) become
    `[email removed]`; phone numbers (after a label such as Tel or Phone, `+44` style international numbers, and national
    numbers starting with 0, 7 digits or more, and labelled mobiles such as "Mob.") become `[phone removed]`; names after a contact label ("Contact:",
    "contact person", "please contact", "enquiries to") or a title (Mr, Mrs, Ms, Dr), with or without initials, become `[name removed]`. Names that start with a common first name
    and are followed by a surname ("Sarah Jones", "Gracie-Lee Bullock"), and a first name alone in brackets, also become
    `[name removed]` (this also hides people in place names, such as "\[name removed] Hospital"). House-number street
    addresses ("30 Essington Way", with a following UK postcode) become `[address removed]`. CPV codes, OJ references and dates are left intact.
    This is pattern matching, so an unusual format can slip through, and it errs on the side of removing a little too much.
  - a supplier name is only shown when it clearly names an organisation: a legal suffix (Ltd, Limited, PLC, LLP, CIC,
    GmbH, AG ...), a public-body word (Council, NHS, Trust, University, School ...) or a company or charity register
    number on the notice. Names with a title (Mr, Mrs, Dr) or "t/a" / "trading as" are never shown. Other winners are
    counted in `suppliersNotShown`, so sole traders are not named.
- The actor is polite to the services: one request at a time, a pause of over a second between requests, and it waits when
  the API asks it to (429 Retry-After, or 5 minutes after a Contracts Finder 403 rate limit); if asked to wait more than
  10 minutes it stops instead. It only follows paging links on the two official API hosts and stops when your spending
  limit is reached. It never works around limits.
- Use it to find and research opportunities. Don't use it to build contact lists of public officials or for unsolicited
  marketing.

# Actor input Schema

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

Keep notices whose title, description or buyer name contains any of these words (not case sensitive). Leave empty for all notices.

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

Keep notices with a CPV code starting with any of these, for example 9091 (cleaning services) or 72 (IT services). Leave empty for all.

## `stage` (type: `string`):

Which kind of notice to keep.

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

Keep only notices whose tender deadline is in the future.

## `smeOnly` (type: `boolean`):

Keep only notices the buyer marked as suitable for small and medium-sized businesses (mostly set on Contracts Finder notices).

## `buyerContains` (type: `string`):

Keep notices whose buyer name contains this text, for example 'council' or 'NHS'.

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

Keep notices with an estimated or awarded value at or above this. Notices without a value are dropped when this is set.

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

Keep notices with a value at or below this. Notices without a value are dropped when this is set.

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

Read notices published or updated in the last N days (max 31). Ignored when 'Published from' is set. Schedule a daily run with 1 for a daily digest.

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

Start date (YYYY-MM-DD). At most 31 days ago; older dates are moved forward to 31 days ago.

## `contractsFinder` (type: `boolean`):

England's lower-value and below-threshold notices.

## `findATender` (type: `boolean`):

UK-wide higher-value notices (Procurement Act 2023 and older regimes).

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

Stop after saving this many matching notices. You only pay for saved notices.

## Actor input object example

```json
{
  "keywords": [
    "cleaning",
    "facilities management"
  ],
  "stage": "all",
  "openOnly": false,
  "smeOnly": false,
  "daysBack": 3,
  "contractsFinder": true,
  "findATender": true,
  "maxResults": 500
}
```

# Actor output Schema

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

All results in the default dataset, shown in the overview table.

# 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 = {
    "keywords": [
        "cleaning",
        "facilities management"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("velveteen_driver/uk-public-tenders").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 = { "keywords": [
        "cleaning",
        "facilities management",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("velveteen_driver/uk-public-tenders").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 '{
  "keywords": [
    "cleaning",
    "facilities management"
  ]
}' |
apify call velveteen_driver/uk-public-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,velveteen_driver/uk-public-tenders"
        }
    }
}
```

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/Lg1gIKyJKYzeeeDL1/builds/i1fbadVJOftEbU6HW/openapi.json
