# UK Tenders: Find a Tender + Contracts Finder Notices (`studded_lantana/uk-tenders`) Actor

UK public procurement notices from the official Find a Tender and Contracts Finder OCDS APIs in one clean schema. Filter by keyword, CPV code, value, date and open deadline.

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

## Pricing

from $2.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: Find a Tender + Contracts Finder Notices

**What it does:** returns UK public-sector procurement notices and contract awards (including the winning companies) from the two official UK government sources, **Find a Tender** (UK-wide, mostly higher-value contracts) and **Contracts Finder** (England, lower-value contracts). Both come from their documented OCDS APIs and share one flat schema: title, buyer, CPV codes, estimated value, tender deadline, contract dates, status, award value and a link to the official notice. Filter by keyword, CPV code, value range, date range and "still open".

Why use it instead of scraping the websites: it reads the official open-data APIs (Open Government Licence), so there is no HTML parsing to break. Both sources share one schema, so you don't need two tools. It also handles the sources' rate limit: when Find a Tender or Contracts Finder asks callers to pause (usually 2 minutes), the run waits and resumes instead of failing.

### Use cases

- **Find UK government contracts to bid on.** Get a daily or weekly list of open tenders in your sector by CPV code and keyword, with deadline, estimated value and buyer.
- **See who won.** Pull award notices to track which suppliers win contracts from which buyers, and for how much.
- **Watch the pipeline.** Planning notices show what buyers intend to procure before the tender opens.
- **Feed other tools.** Results are plain JSON records, so they drop into a spreadsheet, a CRM, a Slack alert or an AI agent.

**Tutorial:** [How to get new UK government tenders in your inbox every morning](https://dev.to/kim_kelsi_b2078fa69a/how-to-get-new-uk-government-tenders-in-your-inbox-every-morning-jbm)

### Input

```json
{
  "sources": ["find-a-tender", "contracts-finder"],
  "stages": ["tender"],
  "daysBack": 7,
  "keywords": ["software", "cloud"],
  "cpvCodes": ["72000000"],
  "minValue": 50000,
  "openOnly": true,
  "maxItems": 200
}
```

- `sources`: `find-a-tender` and/or `contracts-finder` (default both).
- `stages`: `tender` (opportunities, default), `planning` (pipeline and market engagement notices), `award` (contract awards).
- `daysBack` (1–31, default 7), or `dateFrom` / `dateTo` (`YYYY-MM-DD`, inclusive, at most 31 days apart). Find a Tender filters by the date a notice was last **updated**; Contracts Finder filters by the date it was **published**.
- `keywords`: keeps a notice if its title or description contains any of them (case-insensitive).
- `cpvCodes`: keeps a notice if any of its CPV codes falls under one of these. Trailing zeros widen the match: `72000000` matches all of 72xxxxxx (IT services) and `45` matches all construction work.
- `minValue` / `maxValue` (GBP): compared with the estimated value, or with the awarded value for award notices. Notices with no value are dropped when you set either one.
- `openOnly`: keeps only notices whose tender deadline is still in the future.
- `maxItems` (default 200), `maxPagesPerSource` (default 20; each page scans up to 100 notices).

### Output

One record per notice. A real example (Find a Tender, fetched 2026-10-09; description shortened here):

```json
{
  "source": "find-a-tender",
  "notice_id": "095775-2026",
  "ocid": "ocds-h6vhtk-0784ff",
  "tags": [
    "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 mandate for the delivery of the Scottish Universities Ignition Fund Strategy (\"the Mandate\").\nThe successful bidder will be expected to esta...",
  "status": "active",
  "published_at": "2026-10-09T15:37:16+01:00",
  "buyer_name": "Scottish National Investment Bank",
  "buyer_id": "GB-FTS-12628",
  "buyer_type": "Body governed by public law",
  "buyer_locality": "Edinburgh",
  "buyer_region": "UKM75",
  "buyer_country": "United Kingdom",
  "cpv_codes": [
    "66100000"
  ],
  "cpv_descriptions": [
    "Banking and investment services"
  ],
  "main_category": "services",
  "procurement_method": "Open procedure",
  "value_amount": 6500000.0,
  "value_amount_gross": null,
  "currency": "GBP",
  "tender_deadline": "2026-11-10T12:00:00Z",
  "is_open": true,
  "enquiry_deadline": null,
  "contract_start": null,
  "contract_end": null,
  "lots_count": 1,
  "suitable_for_sme": null,
  "suitable_for_vcse": null,
  "delivery_regions": [
    "UK"
  ],
  "award_value_total": null,
  "award_date": null,
  "award_supplier_count": 0,
  "url": "https://www.find-tender.service.gov.uk/Notice/095775-2026",
  "fetched_at": "2026-10-09T17:58:40Z"
}
```

| Field | Meaning |
|---|---|
| `source` | `find-a-tender` or `contracts-finder` |
| `notice_id`, `ocid` | Source notice id and the Open Contracting id (the same procurement keeps its `ocid` across notices) |
| `tags` | OCDS release tags, e.g. `tender`, `planning`, `award`, `contract` |
| `title`, `description` | Notice text. Descriptions are cut at 3,000 characters; email addresses and phone numbers in them are replaced with `[email removed]` / `[phone removed]` |
| `status` | OCDS tender status as published, e.g. `active` or `complete` |
| `published_at` | Notice publication time |
| `buyer_*` | The contracting authority: name, id, type, locality, NUTS/ITL region, country |
| `cpv_codes`, `cpv_descriptions` | All CPV codes on the notice and its items |
| `value_amount`, `value_amount_gross`, `currency` | Estimated value net and gross of VAT, when the buyer published it |
| `tender_deadline`, `is_open`, `enquiry_deadline` | Submission deadline, whether it is still in the future at fetch time, and the clarification deadline |
| `contract_start`, `contract_end` | Contract period (from the first lot when the notice has lots) |
| `lots_count`, `main_category`, `procurement_method` | Procurement details |
| `suitable_for_sme`, `suitable_for_vcse` | Contracts Finder suitability flags (`null` on Find a Tender) |
| `delivery_regions` | Where the work is delivered |
| `award_value_total`, `award_date`, `award_supplier_count` | For award notices: total awarded value, latest award date, number of suppliers |
| `suppliers` | Award notices: the winning suppliers that are clearly organisations, each with `name`, `companies_house_number` (when the notice gives one) and `scale` (`sme` / `large` when given) |
| `suppliers_withheld` | Award notices: how many winning suppliers were not named, because they may be individuals (see Limits) |
| `url` | The official notice page |

### FAQ

**How do I get UK government tenders as JSON or CSV?**
Run the Actor with the filters you want. Results land in an Apify dataset, which you can download as JSON, CSV or Excel, or read through the Apify API.

**What is the difference between Find a Tender and Contracts Finder?**
Find a Tender is the UK-wide service and carries mostly higher-value notices. Contracts Finder covers England and carries lower-value ones. This Actor reads both and returns them in one schema; the `source` field says where each record came from.

**How do I get only IT or software tenders?**
Set `cpvCodes` to `["72000000", "48000000"]` (IT services and software packages), or use `keywords`, or both. A notice must then match the CPV filter and the keyword filter.

**Can I see which company won a contract?**
Yes. Set `stages` to `["award"]`. Each record has `award_value_total`, `award_date` and a `suppliers` list. Suppliers that may be individuals are counted but not named (see Limits).

**How do I get new tenders every day?**
Create an Apify schedule that runs the Actor daily with `daysBack: 2`. `daysBack` counts calendar days in UTC including today, so `1` means today only and a morning run would miss most of yesterday. With `2` each notice appears on two consecutive runs; use `source` plus `notice_id` to skip the ones you have already seen. Find a Tender also filters by the date a notice was last updated, so an amended notice can come back later.

**Does it cover Scotland, Wales and Northern Ireland?**
Find a Tender is UK-wide, so their higher-value notices are included. The devolved portals (Public Contracts Scotland, Sell2Wales, eTendersNI) are not sources of this Actor.

**Does it return contact details?**
No. Contact names, emails, phone numbers and addresses are never returned. Each record links to the official notice.

### Pricing

Pay per event:

- **$0.005 per run** (start).
- **$0.002 per notice** returned, so $2 per 1,000 notices.

You only pay for notices that match your filters. Notices scanned and filtered out are free. Set a maximum charge per run in Apify to cap spend.

### Limits

- Date range: at most 31 days per run. For longer histories, run once per month.
- Each source/stage pair stops after `maxPagesPerSource` pages (100 notices each, default 20). The log tells you when that happens.
- Both sources rate-limit callers and ask for a pause of about 2 minutes when the limit is hit. The run waits up to 4 times per page and then moves on with what it has, so wide date ranges can take several minutes.
- Values, deadlines, CPV codes and regions are only present when the buyer published them.
- The same procurement can appear on both sources and at several stages. Records are de-duplicated per source and notice id, not across sources (use `ocid` to group).
- No contact names, emails, phone numbers or addresses are returned.
- Supplier names are returned only when the supplier is clearly an organisation: it has a Companies House or registered-charity number on the notice, the notice marks it as a large enterprise, its name carries a legal-entity suffix (Ltd, Limited, PLC, LLP, CIC, GmbH, AG, Oy, Inc and similar), or it is a public body (council, NHS, university, college, police...). Other suppliers may be sole traders, i.e. people, so they are counted in `suppliers_withheld` but not named. Their names are on the official notice (`url`). In award notices from 1–3 and 7–9 October 2026, 93 of 469 suppliers (20%) were withheld. The share varies by day and source (8%–42%) and is highest for local care and taxi frameworks.
- Contains public sector information licensed under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). This Actor is not affiliated with or endorsed by the Cabinet Office, Find a Tender or Contracts Finder.

# Actor input Schema

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

Which official UK source to read: find-a-tender (UK-wide, mostly higher-value notices) and/or contracts-finder (England, lower-value notices). Leave as both to cover the widest set of notices; results from both share one schema.

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

Which kind of notice to return. tender = opportunities to bid on (default). planning = early market engagement and pipeline notices, before a tender opens. award = contracts already awarded, including the winning suppliers and the awarded value; use this to see who won.

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

How far back to look: notices published (Contracts Finder) or last updated (Find a Tender) in the last N days, including today (UTC). Days are calendar days, so 1 means today only: for a daily check use 2 and skip notices already seen; use 7 for a weekly one. Maximum 31. Ignored if Date from is set.

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

Optional start of a fixed period, as YYYY-MM-DD (e.g. "2026-09-01"). Use it with Date to instead of Days back. The period can be at most 31 days; for a longer history, run once per month.

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

Optional. YYYY-MM-DD, inclusive. Defaults to today (UTC).

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

Keep notices whose title or description contains any of these words or phrases (case-insensitive), e.g. \["software", "cloud hosting"]. A notice matches if at least one appears, so add synonyms as separate entries. Leave empty to return all notices.

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

Keep notices in these procurement categories (CPV codes). Trailing zeros widen the match, so a division code covers everything under it: "72000000" IT services, "48000000" software packages, "45000000" construction work, "79000000" business services, "85000000" health and social work. A short prefix such as "45" works too. Leave empty for all categories.

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

Keep notices whose estimated value (awarded value for award notices) is at least this many pounds, e.g. 50000. Many buyers publish no value, and those notices are dropped when this is set, so leave it empty for the fullest list.

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

Keep notices whose estimated value (awarded value for award notices) is at most this many pounds, e.g. 1000000. Notices without a published value are dropped when this is set.

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

Set to true to keep only notices whose tender deadline is still in the future, i.e. opportunities that can still be bid on. Use it with the tender stage.

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

Stop after this many matching notices. You are charged per notice returned, so this also caps the cost of the run. A week of tender notices from both sources is usually under 100.

## `maxPagesPerSource` (type: `integer`):

Advanced; the default is fine for most runs. How many pages (up to 100 notices each) to scan per source and stage before stopping. Lower it to bound run time on wide date ranges.

## Actor input object example

```json
{
  "sources": [
    "find-a-tender",
    "contracts-finder"
  ],
  "stages": [
    "tender"
  ],
  "daysBack": 7,
  "keywords": [
    "software"
  ],
  "openOnly": false,
  "maxItems": 200,
  "maxPagesPerSource": 20
}
```

# Actor output Schema

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

One record per notice: buyer, CPV codes, value, deadline, status and notice URL, harmonised across Find a Tender and Contracts Finder.

# 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("studded_lantana/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("studded_lantana/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 studded_lantana/uk-tenders --silent --output-dataset

```

## MCP server setup

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