# Public Tenders Scraper - EU TED & UK Find a Tender Notices (`rjmacarthy/public-tenders-scraper`) Actor

Search government tenders and contract awards on EU TED (all member states), UK Find a Tender and UK Contracts Finder in one normalised schema: buyer, CPV, value, deadline, winners. Keyword, CPV, country and date filters, daily 'only new' alerts.

- **URL**: https://apify.com/rjmacarthy/public-tenders-scraper.md
- **Developed by:** [rj](https://apify.com/rjmacarthy) (community)
- **Categories:** Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 procurement 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

## Public Tenders Scraper - EU TED & UK Find a Tender Notices

Search **government tenders, contract opportunities and contract awards** across the **EU (TED, all member states)** and the **UK (Find a Tender and Contracts Finder)** in one run, and get them back in **one clean schema**: buyer, country, CPV codes, estimated value, submission deadline, winners and award value. Most tender scrapers cover one portal and return each portal's own format. This Actor covers three official portals with one set of filters (keywords, CPV codes, countries, dates, notice type, minimum value) and has an **"only new notices" mode** for daily tender alerts. No start fee: you pay only per notice.

*Optional, beta:* US federal opportunities from **SAM.gov** via the official api.sam.gov API, if you add your own free API key. This source is not yet verified against live responses.

### What data can you get?

| Field | Example |
|---|---|
| `title`, `description` (max ~2,000 chars) | "Microsoft Lizenzen", scope text |
| `source`, `noticeId`, `url` | `ted`, `774310-2026`, public notice page |
| `noticeType` | `tender`, `award`, `planning`, `other` |
| `status` | `open`, `closed`, `awarded`, `planning`, `cancelled` |
| `procedureType` | "Open", "Restricted", "Below threshold - open competition" |
| `buyerName`, `buyerCountry`, `buyerCity` | "Dublin City Council", `IE`, "Dublin" |
| `cpvCodes`, `cpvMainDescription` | `["72000000"]`, "IT services: consulting, software development..." |
| `estimatedValue`, `currency` | `50000000`, `EUR` |
| `publishedAt`, `deadlineAt` | `2026-11-06`, `2026-12-08T10:30:00.000Z` |
| `awardedSuppliers`, `awardValue` | `["Gofore Finland Oy"]`, `664340` |
| `lotsCount`, `documentsUrl`, `language` | `2`, link to the e-tendering platform, `de` |
| `searchKeyword`, `scrapedAt` | which keyword found it, when |

Values are numbers, dates are ISO 8601, and every item has the same keys (`null` when a portal doesn't publish a value).

#### Sources

| Source | Coverage | Keyword search |
|---|---|---|
| `ted` - EU TED | All EU/EEA member states, above EU thresholds (~3,000 notices/day) | Full-text search on TED |
| `uk-fts` - UK Find a Tender | UK above-threshold and Procurement Act notices | Filtered locally (see Tips) |
| `uk-contracts-finder` - UK Contracts Finder | UK below-threshold contracts (mostly England) | Contracts Finder search |
| `sam-gov` - SAM.gov (**beta, optional**) | US federal contract opportunities | Title search; **needs your free api.sam.gov key**; not yet verified against live responses |

### Use cases

- **Daily tender alerts** for a bid team or a tender newsletter: schedule the Actor with `onlyNew` and send new notices to Slack, e-mail or a CRM.
- **B2B sales prospecting**: find public buyers that are about to buy software, cleaning, construction or consulting services.
- **Competitor tracking**: watch award notices to see who wins which contracts, for how much.
- **Market research**: size public demand per CPV code and country.

### How to use

1. Enter keywords (or leave empty and filter by CPV code / country).
2. Pick sources, notice types and a date window.
3. Run, then export to JSON, CSV or Excel, or connect via API.

**IT tenders in Germany published in the last 7 days**

```json
{
  "sources": ["ted"],
  "countries": ["DE"],
  "cpvCodes": ["72", "48"],
  "noticeTypes": ["tender"],
  "publishedWithinDays": 7,
  "maxItems": 100
}
```

**Cleaning contracts in the UK (both portals), daily alert**

```json
{
  "keywords": ["cleaning"],
  "sources": ["uk-fts", "uk-contracts-finder"],
  "noticeTypes": ["tender"],
  "publishedWithinDays": 30,
  "onlyNew": true,
  "monitorName": "uk-cleaning"
}
```

**Software contract awards across Europe and the UK, above 100k**

```json
{
  "keywords": ["software"],
  "sources": ["ted", "uk-fts", "uk-contracts-finder"],
  "noticeTypes": ["award"],
  "minValue": 100000,
  "publishedWithinDays": 30
}
```

### Output example

Real items from a local run (trimmed):

```json
[
  {
    "type": "notice",
    "id": "ted:775102-2026",
    "source": "ted",
    "noticeId": "775102-2026",
    "url": "https://ted.europa.eu/en/notice/-/detail/775102-2026",
    "title": "Kilpailu- ja kuluttajavirasto - IT-konsultointi 2023-2028 (DPS) - Verkkopalvelun ylläpito- ja jatkokehityspalvelujen hankinta",
    "description": "Kilpailu- ja kuluttajavirasto pyytää tarjoustanne Verkkopalvelun ylläpito- ja jatkokehityspalveluista ...",
    "noticeType": "award",
    "procedureType": "Restricted",
    "status": "awarded",
    "buyerName": "Kilpailu-ja kuluttajavirasto",
    "buyerCountry": "FI",
    "buyerCity": "Helsinki",
    "cpvCodes": ["72000000", "48000000"],
    "cpvMainDescription": "IT services: consulting, software development, Internet and support",
    "estimatedValue": null,
    "currency": "EUR",
    "publishedAt": "2026-11-06",
    "deadlineAt": null,
    "awardedSuppliers": ["Gofore Finland Oy"],
    "awardValue": 664340,
    "lotsCount": 1,
    "documentsUrl": null,
    "language": "fi",
    "searchKeyword": "software",
    "scrapedAt": "2026-11-08T12:33:57.142Z"
  },
  {
    "type": "notice",
    "id": "uk-fts:105944-2026",
    "source": "uk-fts",
    "noticeId": "105944-2026",
    "url": "https://www.find-tender.service.gov.uk/Notice/105944-2026",
    "title": "Secure Connection Portal",
    "description": "Telford & Wrekin Council wishes to establish a contract for the provision, hosting, support and maintenance of a secure software solution ...",
    "noticeType": "tender",
    "procedureType": "Below threshold - open competition",
    "status": "open",
    "buyerName": "Borough of Telford & Wrekin",
    "buyerCountry": "GB",
    "...": "..."
  }
]
```

More in [`samples/sample-output.json`](samples/sample-output.json). A `RUN_SUMMARY` record in the default key-value store lists per-source counts, warnings and request statistics.

### Pricing

Pay per event, no start fee:

| Event | Price |
|---|---|
| `notice` - one procurement notice in the dataset | **$0.003** |

Example: 1,000 notices = **$3.00**. A daily alert that finds 30 new notices costs about $0.09 per day. Set "Maximum cost per run" in Apify Console and the Actor stops cleanly when the budget is reached. Platform usage is minimal (256 MB, plain API calls, no browser).

### Tips and limits

- **Max notices is split across sources.** With `maxItems: 100` and two sources, each source gets up to 50. Use `0` for no limit.
- **Keywords are phrase searches.** Each keyword is a separate search; a notice found by two keywords appears once. TED searches the full notice text in every language version (so English keywords also find notices in other languages via TED's translated titles). Contracts Finder uses its own relevance search.
- **UK Find a Tender has no keyword search in its API.** The Actor reads the notice feed newest-first (100 per page, about 4-6 hours of notices per page on a weekday) and keeps whole-word matches in the title/description. "UK Find a Tender: max pages" (default 20, about 4-5 days) limits how far back it looks; the run summary warns when the cap was hit.
- **Contracts Finder** returns at most 1,000 hits per keyword.
- **SAM.gov is an optional beta source** that needs your own free api.sam.gov API key (sam.gov, sign in, Account Details, Public API Key). It is not yet verified against live responses, so treat its output as beta. SAM.gov's terms forbid scraping its website, so the Actor uses only the official Get Opportunities API. Keyword search there covers titles only, there is no description text, and personal keys have a small daily quota (one request per keyword per run).
- **Countries** apply to TED only; the UK portals are UK-only and SAM.gov is US-only. **CPV codes** apply to TED and the UK portals (SAM.gov uses NAICS).
- **Minimum value** compares the estimated value (or the award value) in the notice's own currency. Notices that publish no value are kept.
- **Dates:** TED publishes date-only publication dates (`2026-11-06`); other timestamps are UTC.
- Titles and descriptions come in the notice's original language (TED: English when the buyer published one).

### FAQ

**Is it legal?** The Actor reads only public procurement notices from official government APIs (TED, Find a Tender, Contracts Finder, and for the optional SAM.gov source the official api.sam.gov API). No login, no captcha bypass. You are responsible for how you use the data and for complying with each portal's terms and with data-protection law.

**Does it collect personal data?** No contact data is output. Contact names, e-mails and phone numbers in the portals' contact fields are never read. E-mail addresses and phone numbers inside description text are masked (`[email removed]`, `[phone removed]`). Award winners that look like private individuals (e.g. freelancers on TED award notices) are shown as `(private individual)`.

**Do I need a proxy?** No. All sources are public APIs. Datacenter Apify Proxy works if you want it; residential proxies are not supported and fall back to the datacenter proxy automatically.

**How do I get only new tenders every day?** Turn on "Only new notices", give the search a monitor name and schedule the Actor daily. Notices already output (and paid for) are skipped on later runs for 90 days.

**Why did a source return fewer notices than expected?** Check `RUN_SUMMARY`: it shows per-source counts and warnings (e.g. the Find a Tender page cap, or a skipped SAM.gov source without an API key).

### Integrations

Use the results via the [Apify API](https://docs.apify.com/api/v2), the Apify JavaScript/Python clients, scheduled runs with webhooks, or no-code tools: **Make**, **Zapier**, **n8n**, Google Sheets, Slack and e-mail integrations. The Actor also works as a tool for AI agents through the **Apify MCP server**.

### Changelog

- **0.1** - First release: EU TED, UK Find a Tender and UK Contracts Finder in one schema, plus an optional beta SAM.gov source (official API, own key), with keyword, CPV, country, date, notice-type and minimum-value filters and an "only new" mode.

### More scrapers by the same developer

- [AI Visibility Tracker: ChatGPT, Perplexity, Gemini, Claude](https://apify.com/rjmacarthy/ai-search-visibility-tracker)
- [AliExpress Scraper - Product Search, Prices, Ratings & Details](https://apify.com/rjmacarthy/aliexpress-scraper)
- [Apple App Store Scraper: Apps, Search & Reviews](https://apify.com/rjmacarthy/app-store-scraper)
- [AutoScout24 Scraper - Used Car Listings & Prices (Europe)](https://apify.com/rjmacarthy/autoscout24-scraper)
- [Bilibili Scraper - Videos, Search, Popular & Uploader Stats](https://apify.com/rjmacarthy/bilibili-scraper)
- [Bing Search Scraper: Organic Results, Ads & Related Searches](https://apify.com/rjmacarthy/bing-search-scraper)

Browse all my Actors on [my Apify Store profile](https://apify.com/rjmacarthy).

### Support

Found a bug or need another procurement portal? Open an issue on the Actor's Issues tab.

# Actor input Schema

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

Words or phrases to look for in the notice title and description, e.g. "software", "cleaning services", "road maintenance". Each keyword is a separate search (phrase match). Leave empty for every notice in the date window.

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

Which procurement portals to search. EU TED = all EU/EEA member states (above-threshold). UK Find a Tender = UK above-threshold. UK Contracts Finder = UK below-threshold (England). SAM.gov (beta) = US federal opportunities via the official api.sam.gov API; needs your free API key below and is not yet verified against live responses.

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

Only these notice types. Tender = open calls for competition (with a deadline). Award = contract award results (with winners and values). Planning = prior information / pipeline / sources sought. Leave empty for all, including corrigenda and modifications.

## `countries` (type: `array`):

ISO country codes of the buyer, 2 or 3 letters, e.g. "DE", "FR", "IE" or "DEU". Applies to EU TED only (the UK sources are UK-only, SAM.gov is US-only). Leave empty for all countries.

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

Common Procurement Vocabulary code prefixes, e.g. "72" (IT services), "48" (software packages), "90910000" (cleaning services), "45" (construction work). A notice matches if any of its CPV codes starts with a prefix. Ignored for SAM.gov (which uses NAICS).

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

Only notices published in the last N days. 0 = no date limit. Ignored when "Published from" is set.

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

Only notices published on or after this date (YYYY-MM-DD). Overrides "Published within (days)".

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

Drop notices whose estimated value (or award value) is below this amount, in the notice's own currency (EUR, GBP, USD...). Notices that publish no value at all are kept.

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

Maximum number of notices in total. Split evenly across the selected sources, so every source gets a fair share. 0 = no limit.

## `onlyNew` (type: `boolean`):

Remember which notices were already output (per monitor name, kept 90 days) and output only new ones on later runs. Ideal for a scheduled daily tender alert.

## `monitorName` (type: `string`):

Name of the "only new" memory. Use a different name for each saved search/schedule so they don't share memory.

## `ftsMaxPages` (type: `integer`):

Find a Tender's API has no keyword search, so the Actor reads its notice feed (100 notices per page, newest first) and filters locally. Each page covers roughly 4-6 hours of notices on a weekday. Raise this to look further back.

## `samGovApiKey` (type: `string`):

Optional. Your free personal api.sam.gov public API key (sam.gov > sign in > Account Details > Public API Key). Only needed for the beta SAM.gov source, which uses the official Get Opportunities API (SAM.gov's terms forbid scraping its website) and is not yet verified against live responses. Personal keys have a small daily quota, so the Actor makes one request per keyword.

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

Not needed: all sources are official public APIs. Datacenter Apify Proxy is supported; residential proxies are not (they fall back to datacenter proxy automatically).

## Actor input object example

```json
{
  "keywords": [
    "software"
  ],
  "sources": [
    "ted",
    "uk-fts"
  ],
  "publishedWithinDays": 14,
  "maxItems": 15,
  "onlyNew": false,
  "monitorName": "default",
  "ftsMaxPages": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One item per notice: buyer, country, type, status, value, publication date, deadline and URL.

## `noticesFull` (type: `string`):

Every field, including description, CPV codes, winners and award values.

## `summary` (type: `string`):

Per-source counts, warnings, request statistics.

# 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"
    ],
    "sources": [
        "ted",
        "uk-fts"
    ],
    "publishedWithinDays": 14,
    "maxItems": 15,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rjmacarthy/public-tenders-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 = {
    "keywords": ["software"],
    "sources": [
        "ted",
        "uk-fts",
    ],
    "publishedWithinDays": 14,
    "maxItems": 15,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("rjmacarthy/public-tenders-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 '{
  "keywords": [
    "software"
  ],
  "sources": [
    "ted",
    "uk-fts"
  ],
  "publishedWithinDays": 14,
  "maxItems": 15,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call rjmacarthy/public-tenders-scraper --silent --output-dataset

```

## MCP server setup

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