# UK & EU Tenders API: Find a Tender, Contracts Finder, TED (`crawlwren/uk-eu-tenders`) Actor

Daily UK and EU government tenders from the official Find a Tender, Contracts Finder and TED APIs, in one clean schema with deadline countdowns. Filter by keyword, CPV, stage, value and country. No API key, no personal contact data. $2 per 1,000 notices.

- **URL**: https://apify.com/crawlwren/uk-eu-tenders.md
- **Developed by:** [Chordio, Inc.](https://apify.com/crawlwren) (community)
- **Categories:** Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 tender 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

**Find every new UK and EU government tender that matches what you sell, in one clean feed.** This actor searches the three official procurement sources, **UK Contracts Finder**, **UK Find a Tender (FTS)** and the **EU's TED (Tenders Electronic Daily)**. It merges the results into one consistent table with a deadline countdown, and leaves out personal contact data.

Use it to:

- **Win more public-sector work.** Get a daily list of open tenders that match your keywords or CPV codes, then send it to Google Sheets, Slack or your CRM.
- **Track the competition and the market.** See awarded contracts, who won and for how much, and which buyers are spending in your category.
- **Feed AI agents and bid tools.** Every notice uses the same JSON schema, so your agent doesn't need three separate parsers.

### Why this tender scraper

| | This actor | Typical tender scrapers |
|---|---|---|
| Sources | Contracts Finder **+** Find a Tender **+** TED, in one run | Usually one portal per actor |
| Data access | **Official open-data APIs only** (OCDS + TED Search API), so no HTML breakage | Often HTML scraping |
| Schema | One normalised schema across UK and EU | Raw, source-specific fields |
| Deadline | `deadlineAt` + `daysToDeadline` on every notice | Rarely |
| Personal data | Buyer contact names, emails and phones are **never** output. Emails in free text are redacted. | Usually included |
| Failure handling | Empty or blocked runs **fail loudly** with a reason, not a silent empty dataset | Often silent |
| Price | **$2.00 per 1,000 notices**, and you only pay for notices that pass your filters | Up to $8–$47 per 1,000 |

### How to use it

1. Pick the sources (all three by default).
2. Add **keywords** (e.g. `software`, `cloud`, `cleaning services`) and/or **CPV codes** (prefix match: `72` = all IT services, `45` = construction).
3. Choose a **stage**: open tenders (default), awarded contracts, or planning/prior-information notices.
4. Set the time window (**last N days**, default 3) and click **Start**.

#### Daily "new tenders" alert

Create a **Schedule** in Apify that runs every morning with `daysBack: 1`, then connect an integration:

- **Google Sheets:** append each run's dataset to a sheet.
- **Slack or email:** use Apify's Slack/email integrations or Zapier/Make on the "run succeeded" webhook.
- **AI agents:** call the actor as a tool through Apify's MCP server. Example prompt: *"Find open UK and EU tenders for cybersecurity services closing in the next 30 days."*

#### Input example

```json
{
  "sources": ["contracts_finder", "find_a_tender", "ted"],
  "keywords": ["software", "cloud"],
  "cpvCodes": ["72000000"],
  "noticeStage": "open",
  "daysBack": 3,
  "tedCountries": ["IRL", "NLD", "DEU"],
  "minValue": 50000,
  "maxResults": 200
}
```

| Field | What it does |
|---|---|
| `sources` | `contracts_finder`, `find_a_tender`, `ted` |
| `keywords` | Matches ANY word or phrase in the title or description (case-insensitive) |
| `strictKeywordMatch` | Default on. Also re-checks TED results against the title and description, because TED's own full-text search matches URLs and attachments too. |
| `cpvCodes` | CPV prefix match. `72000000` and `72` behave the same. |
| `noticeStage` | `open` · `awarded` · `planning` · `all` |
| `daysBack` / `publishedFrom` / `publishedTo` | The publication window |
| `onlyOpenDeadlines` | Drops open tenders whose deadline has passed (default on) |
| `minValue` / `maxValue` | In the notice's own currency |
| `tedCountries` | ISO alpha-3 buyer countries for TED, e.g. `FRA`, `DEU`, `IRL` |
| `maxResults` | Cap per source (0 = unlimited) |

### Output

Each notice has the same fields whatever its source. Here's a sample from a real run:

```json
[
  {
    "source": "find_a_tender",
    "sourceLabel": "UK Find a Tender",
    "noticeId": "098228-2026",
    "ocid": "ocds-h6vhtk-069848",
    "url": "https://www.find-tender.service.gov.uk/Notice/098228-2026",
    "title": "Freeze Dryer Services ;Parts, Service and Maintenance Contract",
    "description": "This service contract is for annual servicing, calibration and emergency breakdown cover for three (3) Serail Freeze Dryers (CS150, CS100 and CS15) and refrigeration system servicing associated with the infectious filling isolator",
    "stage": "award,contract",
    "status": "complete",
    "buyerName": "MHRA",
    "buyerId": "GB-PPON-PJLJ-9824-VXPG",
    "buyerCountry": "United Kingdom",
    "buyerCity": "London",
    "buyerPostcode": "E14 4PU",
    "buyerWebsite": "https://www.gov.uk/government/organisations/medicines-and-healthcare-products-regulatory-agency",
    "cpvCodes": [],
    "mainCategory": null,
    "procedure": "Competitive flexible procedure",
    "valueAmount": null,
    "valueCurrency": null,
    "publishedAt": "2026-10-17T10:41:39+01:00",
    "deadlineAt": null,
    "daysToDeadline": null,
    "contractStart": null,
    "contractEnd": null,
    "regions": [],
    "suitableForSme": null,
    "awards": [
      {
        "status": "active",
        "date": null,
        "valueAmount": null,
        "valueCurrency": null,
        "suppliers": [
          "Freeze Drying Services Ltd"
        ]
      }
    ],
    "buyer": {
      "name": "MHRA",
      "partyId": "GB-PPON-PJLJ-9824-VXPG",
      "companiesHouseNumber": null,
      "scheme": "GB-PPON",
      "otherIds": [
        {
          "scheme": "GB-PPON",
          "id": "PJLJ-9824-VXPG"
        }
      ],
      "scale": null
    },
    "suppliers": [
      {
        "name": "Freeze Drying Services Ltd",
        "partyId": "GB-COH-02639022",
        "companiesHouseNumber": "02639022",
        "scheme": "GB-COH",
        "otherIds": [],
        "scale": "sme"
      }
    ],
    "documents": [],
    "licence": "Open Government Licence v3.0",
    "scrapedAt": "2026-10-17T20:51:02.091393+00:00"
  },
  {
    "source": "find_a_tender",
    "sourceLabel": "UK Find a Tender",
    "noticeId": "097901-2026",
    "ocid": "ocds-h6vhtk-077803",
    "url": "https://www.find-tender.service.gov.uk/Notice/097901-2026",
    "title": "Website redesign and redevelopment",
    "description": "Capital City College (CCC) wishes to procure the services of a website redevelopment contractor to research, design, build and launch a new college website that becomes the college’s most effective recruitment, information and self-service channel. It is intended that the new ...",
    "stage": "tenderUpdate",
    "status": "active",
    "buyerName": "Capital City College",
    "buyerId": "GB-PPON-PBXT-5983-JZRH",
    "buyerCountry": "United Kingdom",
    "buyerCity": "London",
    "buyerPostcode": "SW1P 2PD",
    "buyerWebsite": "https://www.capitalccg.ac.uk/",
    "cpvCodes": [
      "72212224",
      "72212480",
      "72413000"
    ],
    "mainCategory": "services",
    "procedure": "Competitive flexible procedure",
    "valueAmount": null,
    "valueCurrency": "GBP",
    "publishedAt": "2026-10-16T12:18:25+01:00",
    "deadlineAt": "2026-10-27T12:00:00+00:00",
    "daysToDeadline": 9,
    "contractStart": "2027-03-01T00:00:00+00:00",
    "contractEnd": "2028-09-30T23:59:59+01:00",
    "regions": [
      "UKI"
    ],
    "suitableForSme": null,
    "awards": [],
    "buyer": {
      "name": "Capital City College",
      "partyId": "GB-PPON-PBXT-5983-JZRH",
      "companiesHouseNumber": null,
      "scheme": "GB-PPON",
      "otherIds": [
        {
          "scheme": "GB-PPON",
          "id": "PBXT-5983-JZRH"
        }
      ],
      "scale": null
    },
    "suppliers": [],
    "documents": [
      {
        "description": null,
        "url": "https://supplier.in-tend.co.uk/educationportal/home"
      },
      {
        "description": "Tender notice on Find a Tender",
        "url": "https://www.find-tender.service.gov.uk/Notice/097901-2026"
      }
    ],
    "licence": "Open Government Licence v3.0",
    "scrapedAt": "2026-10-17T20:51:10.106895+00:00"
  },
  {
    "source": "ted",
    "sourceLabel": "EU TED",
    "noticeId": "707513-2026",
    "ocid": null,
    "url": "https://ted.europa.eu/en/notice/-/detail/707513-2026",
    "title": "Ireland – Software implementation services – Dock Door Management, Picking and Final Mile Delivery",
    "description": "Children's Health Ireland (CHI) is seeking a single supplier for the supply, implementation and support of a Dock Door Management, Messaging and Final Mile Delivery System. The solution will support the complete inbound and outbound logistics process within the New Children's ...",
    "stage": "competition",
    "status": "cn-standard",
    "buyerName": "Children's Health Ireland (CHI)",
    "buyerId": null,
    "buyerCountry": "IRL",
    "buyerCity": "Dublin",
    "buyerPostcode": "D12 N512",
    "buyerWebsite": null,
    "cpvCodes": [
      "72263000",
      "72267100",
      "51611100"
    ],
    "mainCategory": "services",
    "procedure": "open",
    "valueAmount": 1.0,
    "valueCurrency": "EUR",
    "publishedAt": "2026-10-14T00:00:00+02:00",
    "deadlineAt": "2026-11-12T17:00:00+01:00",
    "daysToDeadline": 25,
    "contractStart": null,
    "contractEnd": null,
    "regions": [
      "IE061",
      "IRL"
    ],
    "suitableForSme": null,
    "awards": [],
    "buyer": {
      "name": "Children's Health Ireland (CHI)",
      "partyId": null,
      "companiesHouseNumber": null,
      "scheme": null,
      "otherIds": [],
      "scale": null
    },
    "suppliers": [],
    "documents": [
      {
        "description": "Procurement documents",
        "url": "https://www.etenders.gov.ie/epps/cft/listContractDocuments.do?resourceId=9279658"
      }
    ],
    "licence": "Source: TED - Tenders Electronic Daily, (c) European Union, https://ted.europa.eu. Reuse authorised (Commission Decision 2011/833/EU).",
    "scrapedAt": "2026-10-17T20:51:10.106895+00:00"
  }
]
```

Key fields: `source`, `title`, `description`, `buyerName`, `buyerCountry`, `cpvCodes`, `valueAmount`/`valueCurrency`, `publishedAt`, `deadlineAt`, `daysToDeadline`, `procedure`, `regions`, `suitableForSme` (UK), `awards` (suppliers and award values for awarded notices), `documents`, `url`, `licence`.

**Supplier and buyer identifiers (UK sources).** Every UK notice also has `buyer` and `suppliers[]`, one object per organisation:

| Field | What it is |
|---|---|
| `name` | Organisation name as published |
| `partyId` | The notice's party ID, e.g. `GB-COH-02773548` or `GB-PPON-PQXT-9361-JDRJ` |
| `companiesHouseNumber` | Normalised 8-character UK company number (e.g. `02773548`, `SC123456`) taken from `GB-COH` identifiers, or `null` if the notice gives none or an invalid one |
| `scheme` | Scheme of the main identifier (`GB-COH`, `GB-PPON`, `GB-CHC`, ...) |
| `otherIds` | Every other identifier as `{scheme, id}`, e.g. the Central Digital Platform PPON |
| `scale` | `sme` or `large`, when the buyer declared it |

Use `companiesHouseNumber` to join awards straight to Companies House or GLEIF (registration authority RA000585) without name matching. `suppliers[]` lists every organisation with the `supplier` role or named in an award. These fields are company-level only: no contact names, emails, phone numbers or supplier addresses. TED notices have `buyer` with the name only and an empty `suppliers` list. The existing `awards[].suppliers` (names) is unchanged.

**Coverage (measured on 14 days of real award notices, Oct 3–17, 2026):** 57% of Find a Tender supplier records (2,841 of 4,983) and 42% of Contracts Finder supplier records (719 of 1,706) carry a valid Companies House number. Most of the others carry a PPON (Find a Tender) or no identifier at all (Contracts Finder).

You can download the dataset as JSON, CSV, Excel or HTML, or read it through the Apify API.

### Pricing

Pay-per-event: you pay only for notices delivered after your filters.

| Event | Price | What it is |
|---|---|---|
| Run start | $0.0005 | Charged once per run (covers start-up compute). |
| Tender notice | $0.002 ($2.00 per 1,000) | One normalised tender/award notice delivered to the dataset (after your filters). |

**Examples:**

- A daily UK + EU alert with about 30 matching notices a day costs about **$0.06/day (≈ $2/month)**.
- A one-off export of 5,000 awarded contracts costs about **$10**.

Set a **maximum cost per run** in Apify, and the actor stops cleanly when it reaches it.

### Data sources and licences

- **Contracts Finder** and **Find a Tender**: UK Cabinet Office OCDS APIs. The data is available under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).
- **TED**: Publications Office of the EU, TED Search API v3. Reuse, including commercial reuse, is authorised under Commission Decision 2011/833/EU, with the attribution "Source: TED – Tenders Electronic Daily, © European Union, https://ted.europa.eu".
- Every record has a `licence` field so you can attribute correctly downstream.

### FAQ

**Do I need an API key?** No. All three sources are public, keyless APIs.

**How many suppliers come with a Companies House number?** Roughly half: 57% on Find a Tender and 42% on Contracts Finder in our October 2026 sample (see Output). Suppliers without one (sole traders, charities, overseas firms, or simply not provided) keep their other identifiers.

**Why don't I see buyer contact names and emails?** On purpose. They're personal data, and we don't redistribute them. Each notice links to the official page (`url`), where you'll find the contact route.

**Why are there fewer UK Contracts Finder tenders than I expected?** Since the Procurement Act 2023 took effect (Feb 2025), most new UK tenders go to Find a Tender. Contracts Finder now carries mainly lower-value notices and award notices.

**What happens if a source is down or rate-limits us?** We honour `Retry-After` and retry. If a source still fails, the run reports exactly which one and why in the `RUN_STATS` record. A run that ends with no results fails visibly instead of looking successful.

**Can I get notices from other countries?** TED covers the EU/EEA and some other countries. US federal opportunities are in our sibling actor: [SAM.gov Contract Opportunities Scraper](https://apify.com/crawlwren/sam-gov-opportunities).

### Support

Found a bug or need a field? Open an issue on the actor's **Issues** tab or email hello@crawlwren.com. Built and maintained by **Crawlwren**.

# Actor input Schema

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

Which official sources to search.

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

Keep notices whose title or description contains ANY of these words or phrases (case-insensitive). Leave empty for everything. TED searches all notice languages server-side.

## `strictKeywordMatch` (type: `boolean`):

Also require the keyword in the notice title/description for TED (TED's own full-text search also matches URLs and attachments, which adds noise). Turn off for broader TED results.

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

Common Procurement Vocabulary codes. Prefix match: 72000000 (or just 72) = all IT services. Leave empty for all.

## `noticeStage` (type: `string`):

Open tenders you can still bid on, awarded contracts (who won, for how much), or early-market planning notices.

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

Used when 'Published from' is empty. Use 1 with a daily schedule to get each day's new notices.

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

YYYY-MM-DD. Overrides 'last N days'.

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

YYYY-MM-DD, inclusive. Defaults to now.

## `onlyOpenDeadlines` (type: `boolean`):

Applies to the 'Open tenders' stage.

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

In the notice's own currency (GBP for UK, mostly EUR for TED). Notices without a published value are excluded when set.

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

In the notice's own currency.

## `tedCountries` (type: `array`):

ISO 3166 alpha-3 codes, e.g. DEU, FRA, IRL, NLD. Empty = all countries.

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

Stop each source after this many notices (0 = no limit). You are only charged for notices delivered.

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

Safety cap on API pages fetched per source (100 notices per page for UK sources, 250 for TED).

## Actor input object example

```json
{
  "sources": [
    "contracts_finder",
    "find_a_tender",
    "ted"
  ],
  "keywords": [
    "software",
    "cloud"
  ],
  "strictKeywordMatch": true,
  "noticeStage": "open",
  "daysBack": 3,
  "onlyOpenDeadlines": true,
  "maxResults": 200,
  "maxPagesPerSource": 50
}
```

# Actor output Schema

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

Normalised tender, award and planning notices from Find a Tender, Contracts Finder and TED, one row per notice, each with its licence.

## `runStats` (type: `string`):

JSON summary of the run: results delivered, items filtered, request success per source, skipped sources and any errors.

# 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 = {
    "sources": [
        "contracts_finder",
        "find_a_tender",
        "ted"
    ],
    "keywords": [
        "software",
        "cloud"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlwren/uk-eu-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 = {
    "sources": [
        "contracts_finder",
        "find_a_tender",
        "ted",
    ],
    "keywords": [
        "software",
        "cloud",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("crawlwren/uk-eu-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 '{
  "sources": [
    "contracts_finder",
    "find_a_tender",
    "ted"
  ],
  "keywords": [
    "software",
    "cloud"
  ]
}' |
apify call crawlwren/uk-eu-tenders --silent --output-dataset

```

## MCP server setup

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