# Public Tenders Scraper — EU TED, SAM.gov, UK & France (`cleandata/public-tenders-scraper`) Actor

Government tenders, RFPs and contract awards from official procurement sources: EU TED (all EU/EEA), UK Find a Tender and Contracts Finder, US SAM.gov, France BOAMP. Search by keyword, country, CPV or NAICS: deadlines, values, buyers, winners. No API keys.

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

## Pricing

from $4.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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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, US SAM.gov, France

Find **government tenders and contract awards** from the main official sources in **one consistent format**:

| Source | Coverage |
|---|---|
| 🇪🇺 **TED** (Tenders Electronic Daily) | Every EU and EEA country, all notices above the EU thresholds |
| 🇬🇧 **Find a Tender + Contracts Finder** | United Kingdom, including lower-value contracts |
| 🇺🇸 **SAM.gov** | US federal contract opportunities and awards |
| 🇫🇷 **BOAMP** | France, including the contracts *below* the EU thresholds that never reach TED |

Search by keyword, buyer country, CPV or NAICS code and get, for every notice: title, description, buyer, country and city, CPV/NAICS codes, estimated value and currency, **deadline for bids**, procedure, documents link and, for awards, **who won and for how much**.

**Reliable by design:** the data comes from the official publication platforms and open-data APIs, so there is nothing to block and no proxy cost. **No API keys** are needed.

### What can you use it for?

- **Bid monitoring:** schedule a daily run with *Published since = 1 day* and get the new tenders in your field into Slack, email or your CRM.
- **Sales pipeline for B2B companies:** find public buyers that need what you sell, in the countries you serve.
- **Competitor and market intelligence:** see who wins which contracts, at what value, and which authorities buy what.
- **Planned procurements:** catch prior information notices and US pre-solicitations / sources sought before the tender is out.
- **Research and journalism:** build datasets of public spending by sector and country.

### Sample results

A few of the notices from a real run for *software* and *cybersecurity* (the full description, CPV codes, buyer city, procedure and documents link are in the output too):

| Source | Title | Buyer | Country | Deadline | Estimated value |
|---|---|---|---|---|---|
| TED | Održavanje i nadogradnja sustava za upravljanje dokumentima | APIS IT d.o.o. | HR | 2026-11-19 | 811,000 EUR |
| TED | Predĺženie technickej podpory RIS SED Monarch | Slovenská elektrizačná prenosová sústava, a.s | SK | 2026-11-16 | 712,712 EUR |
| UK Find a Tender | Theatre Event Management Software | Surrey Heath Borough Council | GB | 2026-11-11 | 38,000 GBP |
| UK Find a Tender | Archive Activity Management System | British Film Institute | GB | 2026-11-09 | 170,000 GBP |
| SAM.gov | Navy Electronic Chart Display and Information System (ECDIS) Hardware and Software Production | Dept of Defense / Dept of the Navy / NAVSEA | US | 2027-01-13 | – |
| BOAMP | Organisation de formations à destination des habitants | Etablissement Public Foncier IDF | FR | 2026-11-20 | – |

For awards you also get the winner, e.g. *D A LANGUAGES LIMITED* for Sussex Police's translation services (UK) or *Carahsoft Technology Corp*, 9,000,000 USD, on SAM.gov.

### How much does it cost?

You pay per notice, with no monthly rental: **$5 per 1,000 notices** ($0.005 each). Notices removed by your filters (closed deadlines, other notice types, duplicates across keywords) are never charged. Apify's free plan includes $5 of monthly credit, which covers about 1,000 notices a month — plenty for daily monitoring of a few keywords. You can also set a maximum cost per run in the run options.

### How to use it

1. Click **Try for free** and sign in to Apify (no credit card needed).
2. Type a few keywords (e.g. `software`, `cleaning services`, `solar`), and optionally pick sources, buyer countries and CPV or NAICS codes.
3. Choose the notice types: open tenders (default), planned procurements and/or contract awards.
4. Click **Start**. Download the notices as JSON, CSV or Excel, or send them to Google Sheets, Slack, email or your own system. For monitoring, create a schedule with *Published since* = `1 day`.

### Input

| Field | Description |
|---|---|
| **Keywords** | Words to find in the notice title and description. Each keyword is a separate search; leave empty to get everything matching the other filters. TED translates titles into all EU languages, so English works across the EU; for BOAMP use French terms (`logiciel`, `nettoyage`). |
| **Sources** | `ted`, `uk`, `sam`, `boamp`. All by default. |
| **Notice types** | `tender` (open calls for bids), `planning` (prior information, pre-solicitations, sources sought), `award` (contract awards). |
| **Published since** | Absolute (`2026-10-01`) or relative (`1 day`, `7 days`, `2 weeks`). Default: 3 days. |
| **Only tenders still open** | Skip tenders whose deadline has passed (on by default). |
| **Buyer countries** | 2-letter codes such as `DE`, `FR`, `IT`, `PL`, `GB`, `US`. Sources that don't cover them are skipped. |
| **CPV codes** | EU procurement codes for TED, the UK and BOAMP. A code covers its branch: `72000000` = all IT services, `45000000` = all construction work. |
| **NAICS codes** | US industry codes for SAM.gov, e.g. `541511`. |
| **Max notices** | Limit for the whole run (0 = no limit). With a limit, you get the **newest** notices across all sources, so one busy source can't crowd out the others. |

```json
{
    "keywords": ["software", "cybersecurity"],
    "sources": ["ted", "uk", "sam"],
    "noticeTypes": ["tender"],
    "publishedSince": "1 day",
    "onlyOpen": true,
    "countries": ["DE", "FR", "NL", "GB", "US"],
    "maxResults": 500
}
```

### Output

```json
{
    "source": "UK Find a Tender",
    "noticeId": "097082-2026",
    "url": "https://www.find-tender.service.gov.uk/Notice/097082-2026",
    "noticeType": "tender",
    "noticeTypeDetail": "tender",
    "title": "NHS Tayside Laundry Replacement",
    "titleEnglish": null,
    "description": "The product for replacement under this procurement is the existing Wash Line within the NHS Tayside...",
    "buyerName": "NHS Tayside",
    "buyerCountry": "GB",
    "buyerCity": "Dundee",
    "cpvCodes": ["42716000", "51543400"],
    "naicsCodes": [],
    "contractType": "goods",
    "procedureType": "Open procedure",
    "estimatedValue": 1750000,
    "currency": "GBP",
    "publishedAt": "2026-10-14",
    "deadline": "2026-11-13T10:00:00.000Z",
    "awardedTo": [],
    "awardValue": null,
    "awardCurrency": null,
    "documentsUrl": "https://...",
    "buyerWebsite": null,
    "placeOfPerformance": null,
    "setAside": null,
    "searchKeyword": "laundry"
}
```

- `noticeType` is always `tender`, `planning` or `award`; `noticeTypeDetail` keeps the source's own type (e.g. TED `cn-standard`, SAM.gov `Combined Synopsis/Solicitation`).
- `title` is in the notice's own language. For TED, `titleEnglish` adds TED's English heading ("Germany – Software package and information systems – …").
- `deadline` is a date (TED) or a date and time in UTC (other sources).
- SAM.gov notices also get `naicsCodes`, `setAside` (small-business, 8(a), HUBZone, veteran- or women-owned programmes) and `placeOfPerformance`; award notices carry the award amount.

### Privacy

This Actor outputs procurement data only. Sources also publish the names, emails and phone numbers of contact officers; those fields are never output, and email addresses found inside descriptions are replaced with `[email removed]`. Award winners are companies (occasionally sole traders, as published by the authority).

### Limits

- **UK Find a Tender** has no search and allows only about a dozen requests before a 2-minute pause, so the Actor reads its feed slowly and for at most the last 31 days (about 10 seconds per 100 notices; a daily run takes under a minute). Contracts Finder is searched for the whole range.
- **BOAMP** keyword search works on the French subject and descriptors: use French keywords. When TED is also selected, BOAMP's EU-level notices are skipped because TED already has them.
- Keyword searches look at the title and description (and, for TED, the translated titles); notices that only mention a word in their legal boilerplate are left out on purpose.
- Values are the buyer's estimates as published, in the notice's currency. Many notices don't publish one.

### FAQ

**Do I need API keys or accounts?** No. All sources are public.

**Is it legal to use this data?** Yes. Public procurement notices are published so that anyone can bid, and these sources release them as open data (US federal data is in the public domain). Contact persons' details are left out.

**Which other countries are coming?** National portals below the EU thresholds (Spain, Italy, Germany...) are next. Want one first? Open an issue.

**Can I run it from my own code?** Yes, through the Apify API. In Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("cleandata/public-tenders-scraper").call(
    run_input={"keywords": ["software"], "countries": ["DE", "FR"], "publishedSince": "1 day"}
)
for tender in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(tender["deadline"], tender["buyerName"], tender["title"])
```

**Something broke or you need a field?** Open an issue on the Actor's Issues tab. Feature requests are welcome.

**Found it useful?** A short review on the Reviews tab helps other people find this Actor and tells me what to improve next.

# Actor input Schema

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

Words to look for in the notice title and description, e.g. "software", "cleaning services", "solar". Each keyword is a separate search; leave empty to get every notice that matches the other filters. TED translates titles into all EU languages, so English works there; for BOAMP use French ("logiciel", "nettoyage").

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

Official sources to search. TED covers every EU/EEA country above the EU thresholds; BOAMP adds French notices below them.

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

Open tenders (calls for bids), planned procurements (prior information, pre-solicitations, sources sought) and/or contract awards (who won and for how much).

## `publishedSince` (type: `string`):

Only notices published on or after this date. Absolute (2026-10-01) or relative (1 day, 7 days, 2 weeks). For daily monitoring, schedule the Actor with "1 day".

## `onlyOpen` (type: `boolean`):

Skip tenders whose deadline for bids has already passed. Doesn't affect planned procurements or awards.

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

2-letter codes of the buying authority's country, e.g. DE, FR, IT, ES, PL, GB, US. Leave empty for all. Sources that don't cover any of these countries are skipped.

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

Common Procurement Vocabulary codes. A code covers its whole branch: 72000000 = all IT services, 45000000 = all construction work. Not used by SAM.gov.

## `naicsCodes` (type: `array`):

US industry codes for SAM.gov, e.g. 541511 (custom computer programming) or 236220 (commercial building construction).

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

Maximum number of notices for the whole run. 0 = no limit.

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

Not needed: all sources are official open-data APIs.

## Actor input object example

```json
{
  "keywords": [
    "software"
  ],
  "sources": [
    "ted",
    "uk",
    "sam",
    "boamp"
  ],
  "noticeTypes": [
    "tender"
  ],
  "publishedSince": "3 days",
  "onlyOpen": true,
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

# 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"
    ],
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleandata/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"],
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("cleandata/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"
  ],
  "maxResults": 100
}' |
apify call cleandata/public-tenders-scraper --silent --output-dataset

```

## MCP server setup

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