# UK Tenders Scraper — Contracts Finder & Find a Tender (`quenched_zythum/uk-tenders`) Actor

Scrape UK tenders from Contracts Finder and Find a Tender. Filter by CPV, NUTS region and value. Alert on new notices. No buyer contact details collected.

- **URL**: https://apify.com/quenched_zythum/uk-tenders.md
- **Developed by:** [sofiane dubai](https://apify.com/quenched_zythum) (community)
- **Categories:** Business, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 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.

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 Tenders Scraper — Contracts Finder & Find a Tender

Scrape UK public procurement notices from **Contracts Finder** and **Find a Tender** in one Actor. Filter by CPV code, region and contract value. Run once for a bulk extract, or use monitor mode to alert on **new notices since the last run**. Optionally pull award and incumbent data and flag contracts nearing expiry for recompete planning.

**No contact names or emails are collected.** Buyer organisation details and notice metadata are returned; personal contact fields on notices are omitted by design.

Contains public sector information licensed under the Open Government Licence v3.0.

***

### What it does

- Combines **Contracts Finder** (OCDS API and daily CSV feeds) and **Find a Tender** (OCDS API) into a single dataset.
- Searches and filters public notices by keywords, CPV codes, region/location, notice type, and value band.
- **Date filters differ by source:** Contracts Finder uses **published date**; Find a Tender uses **last-updated date** (not published date).
- Find a Tender **regions** are UK **NUTS/ITL codes** (e.g. `UKF22`), not region names.
- Every result includes the official **notice ID** from the source portal.
- **Monitor / alerts mode:** keep only notices that are new since the previous run (ideal for scheduled Apify runs + webhooks or email integrations).
- Optional **award and incumbent** enrichment where the source publishes it.
- Optional **recompete** signals: surface contracts approaching end date so bid teams can plan ahead.
- Structured JSON/CSV output ready for CRM, BI, or bid-management tools.
- Uses official public OCDS endpoints — no proxy required for normal API reads.

***

### Who it's for

Built for **UK bid teams** and **bid consultants**.

- **UK bid teams** inside SMEs and mid-market suppliers chasing public contracts
- **Bid consultants** (and bid-writing agencies) monitoring multiple buyers or sectors — primary audiences with UK bid teams
- B2B sales teams selling into UK central government, local authorities, NHS, and other public bodies
- Procurement-intelligence and market-research workflows that need clean, repeatable UK tender data

***

### Input fields

| Field | Type | Required | Description |
|---|---|---|---|
| `sources` | array of strings | No (default: both) | Which portals to query: `contractsFinder`, `findATender`, or both |
| `keywords` | string / array | No | Free-text search against title and description |
| `cpvCodes` | array of strings | No | CPV codes to include (exact or prefix match, depending on mode) |
| `regions` | array of strings | No | Region filters. **Find a Tender:** UK NUTS/ITL codes only (e.g. `UKF22`), not names. **Contracts Finder:** location / region filters as supported by that API |
| `minValue` / `maxValue` | number | No | Contract value band (GBP where published) |
| `noticeTypes` | array of strings | No | e.g. tender, award, PIN / prior information, as exposed by each source |
| `publishedAfter` / `publishedBefore` | date (ISO) | No | **Contracts Finder only:** publication date window for bulk extract |
| `updatedAfter` / `updatedBefore` | date (ISO) | No | **Find a Tender only:** last-updated date window (Find a Tender does **not** filter by published date) |
| `monitorMode` | boolean | No (default: `false`) | If `true`, return only notices new since the last successful run for this Actor configuration |
| `includeAwards` | boolean | No (default: `false`) | Include award / incumbent fields when available |
| `includeRecompete` | boolean | No (default: `false`) | Flag notices or contracts near expiry for recompete watchlists |
| `maxItems` | integer | No | Cap on notices returned per run |
| `proxyConfiguration` | object | No | Unused for standard OCDS API reads; reserved for edge cases |

> **Date filters:** Contracts Finder filters by **published date** (`publishedAfter` / `publishedBefore`). Find a Tender filters by **last-updated date** (`updatedAfter` / `updatedBefore`), not published date.
>
> **Regions:** For Find a Tender, pass UK NUTS/ITL codes such as `UKF22` — region names are not accepted by that source.
>
> **Privacy:** The Actor does **not** collect or store buyer contact **names** or **emails**, even when those fields exist on the source notice. Do not request them via input — they are not available as output.

***

### Output fields (example)

Each dataset item is one notice (or award-enriched notice). Every item includes the official **notice ID**. Example shape:

# Actor input Schema

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

Notice is kept if title or description contains ANY keyword (case-insensitive). Empty = all.

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

YYYY-MM-DD. Default: 7 days ago.

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

YYYY-MM-DD. Default: now.

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

Drops notices without a value.

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

Drops notices without a value.

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

Substring match on region, e.g. "London", "South East" (Contracts Finder) or NUTS/ITL codes like "UKI" (Find a Tender).

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

CPV code prefixes, e.g. "72" (IT services) or "72000000".

## `sources` (type: `array`):

Which services to query.

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

Stop after this many notices are saved.

## `onlyNewSinceLastRun` (type: `boolean`):

Skip notices already returned by a previous run (IDs kept in the named key-value store 'uk-tenders-state'). Useful for scheduled alerts.

## Actor input object example

```json
{
  "keywords": [
    "software"
  ],
  "sources": [
    "contractsFinder"
  ],
  "maxItems": 100,
  "onlyNewSinceLastRun": false
}
```

# Actor output Schema

## `notices` (type: `string`):

Dataset items: one notice per row from Contracts Finder and/or Find a Tender.

# 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": [
        "software"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("quenched_zythum/uk-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": ["software"] }

# Run the Actor and wait for it to finish
run = client.actor("quenched_zythum/uk-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": [
    "software"
  ]
}' |
apify call quenched_zythum/uk-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,quenched_zythum/uk-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/EMoMe18Nci96yxnJE/builds/smvOhund3bPs43MLz/openapi.json
