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

Government tenders and public procurement in one table: EU TED (27 countries + EEA), UK Find a Tender & Contracts Finder, US SAM.gov federal contracts and Grants.gov. Keywords, CPV/NAICS, country, value, deadline, buyer contacts, award winners. Only-new mode for daily tender alerts.

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

## Pricing

from $2.40 / 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 & Procurement Scraper — EU TED, SAM.gov, UK Find a Tender

![A keyword search turned into public tenders and contract awards from EU TED, UK Find a Tender, Contracts Finder, SAM.gov and Grants.gov with buyer, deadline and value (real output)](https://raw.githubusercontent.com/tidydata-dev/tidydata-dev/main/assets/apify/public-tenders-scraper.png)

Find **government tenders, public procurement opportunities and contract awards** from the official sources of the EU, the UK and the US — in **one run and one table**, with the same columns for every source.

| Source | Coverage | What you get |
|---|---|---|
| **EU TED** (Tenders Electronic Daily) | 27 EU countries + EEA, all above-threshold tenders | Tenders, prior information, awards & winners |
| **UK Find a Tender** | UK above-threshold + Procurement Act 2023 notices | Tenders, pipeline notices, awards |
| **UK Contracts Finder** | UK below-threshold public contracts (mainly England) | Tenders, early engagement, awards |
| **US SAM.gov** | US federal contract opportunities | Solicitations, presolicitations, sources sought, award notices |
| **US Grants.gov** | US federal grants | Posted and forecasted grants |

Search by **keywords, CPV codes, NAICS codes, buyer country, contract value and publication date**, and get the **buyer, contact email and phone, deadline, estimated value, CPV/NAICS, procedure, documents and submission links** — or, for awards, **the winning companies and the awarded value**. Turn on **"Only new notices"** and schedule it daily to get tender alerts.

**$3 per 1,000 notices.** No login, no API key, no browser.

- ✅ **5 official sources, one schema** — `source`, `title`, `buyerName`, `deadline`, `estimatedValue`, `currency`, `url`… for every notice
- ✅ **Open tenders, planned procurements and contract awards** (winners + awarded value)
- ✅ **Buyer contacts**: email, phone, website, contracting officer (SAM.gov), grant contact (Grants.gov)
- ✅ **Filters**: keywords, exclude words, countries, CPV (children included), NAICS, min/max value, last N days, only open
- ✅ **Only new notices since the last run** — remembers what you already got, per search
- ✅ **EU TED in every language**: original title + TED's English heading (`titleEn`) with the CPV category
- ✅ Official open-data APIs → fast, reliable, no blocking, no proxies

### Who uses it

- **Companies that sell to governments** — a daily list of new tenders in your sector and countries, before your competitors see them.
- **Bid writers, tender consultants & agencies** — one alert per client with a memory name each.
- **Sales & business development** — awards show who just won a contract (= new budget, new supplier needs); buyers show who buys what.
- **Market & competitor research** — who wins which contracts, at what value, in which country.
- **Tender portals, newsletters & SaaS** — feed your platform with clean, structured notices.
- **NGOs, universities & researchers** — US federal grants and EU procurement data in one export.

### How to use it

1. **Keywords** — e.g. `software`, `cyber security`, `cleaning services`, `solar panels`, `translation`. Empty = everything (then use the filters).
2. **Sources** — EU TED, UK Find a Tender, UK Contracts Finder, SAM.gov (and Grants.gov for grants).
3. **Notice types** — open tenders, planned / upcoming, contract awards.
4. **Filters** (optional): buyer countries (`DE`, `FR`, `ES`, `GB`, `US`…), CPV codes (`72000000` = all IT services), NAICS codes (`541511`), minimum / maximum value, published in the last N days, only open.
5. **Run** → export to CSV, Excel, JSON or Google Sheets, or connect it to Slack, email, Make, Zapier or n8n.

#### Daily tender alerts in 2 minutes

1. Set your keywords / CPV / countries, **Published in the last N days = 2** and turn on **Only new notices**.
2. Save it as a **task** and add a **daily schedule**.
3. Add an integration: **email**, **Slack** or **Google Sheets** — you get only the notices you have not seen yet.

Use a different **Memory name** per client or project so each alert has its own memory.

### Output example

A real EU TED notice (Lithuania), shortened:

```json
{
  "source": "ted",
  "sourceName": "EU TED",
  "noticeId": "760367-2026",
  "noticeType": "tender",
  "title": "Daugiakanalės perspėjimo platformos informacinė sistema su garantine priežiūra",
  "titleEn": "Lithuania – Information systems and servers – Daugiakanalės perspėjimo platformos informacinė sistema…",
  "url": "https://ted.europa.eu/en/notice/-/detail/760367-2026",
  "language": "lit",
  "buyerName": "Priešgaisrinės apsaugos ir gelbėjimo departamentas prie Vidaus reikalų ministerijos",
  "buyerCountry": "LT",
  "buyerCity": "Vilnius",
  "buyerEmail": "pagd@vpgt.lt",
  "buyerWebsite": "https://pagd.lrv.lt/lt/",
  "publishedAt": "2026-11-02",
  "deadline": "2026-12-03T09:00:00+02:00",
  "estimatedValue": 4380165.29,
  "currency": "EUR",
  "category": "supplies",
  "cpvCodes": ["48800000", "72267000"],
  "cpvDescription": "Information systems and servers",
  "procedureType": "open",
  "isFramework": false,
  "documentsUrl": "https://viesiejipirkimai.lt/epps/cft/listContractDocuments.do?resourceId=10287151",
  "submissionUrl": "https://viesiejipirkimai.lt/epps/cft/viewTenders.do?resourceId=10287151",
  "pdfUrl": "https://ted.europa.eu/en/notice/760367-2026/pdf"
}
```

A real SAM.gov opportunity, with the contact details added:

```json
{
  "source": "sam-gov",
  "noticeType": "tender",
  "title": "6525--Circle Cardiovascular Software Base+2YR",
  "url": "https://sam.gov/opp/4bb1ce39f6dd4c1e806c5f8031076d5f/view",
  "buyerName": "VETERANS AFFAIRS, DEPARTMENT OF / 246-NETWORK CONTRACTING OFFICE 6 (36C246)",
  "buyerCountry": "US",
  "contactName": "Charlsi B Brooker",
  "buyerEmail": "Charlsi.Brooker@va.gov",
  "deadline": "2026-11-05T15:00:00+00:00",
  "naicsCodes": ["513210"],
  "pscCode": "6525",
  "solicitationNumber": "36C24627Q0110"
}
```

A contract award (UK Contracts Finder):

```json
{
  "source": "uk-contracts-finder",
  "noticeType": "award",
  "title": "Accounting Finance Software",
  "buyerName": "Housing Solutions",
  "buyerEmail": "procurement@housingsolutions.co.uk",
  "cpvDescription": "Software supply services",
  "winners": ["Xledger"],
  "awardValue": 157404.75,
  "awardCurrency": "GBP"
}
```

#### All fields

| Field | What it is |
|---|---|
| `source`, `sourceName` | `ted`, `uk-find-a-tender`, `uk-contracts-finder`, `sam-gov`, `grants-gov` |
| `noticeId`, `url`, `pdfUrl` | Notice ID and link to the official notice |
| `noticeType` | `tender` (open), `planned`, `award` or `grant`; `noticeTypeOriginal` keeps the source's own type |
| `title`, `titleEn`, `description`, `language` | Title in the original language, TED's English heading, scope as clean text |
| `buyerName`, `buyerCountry`, `buyerCity`, `buyerEmail`, `buyerPhone`, `buyerWebsite`, `contactName` | Who is buying and how to reach them |
| `publishedAt`, `deadline` | Publication date and submission deadline |
| `estimatedValue`, `currency` | Estimated value as published (no currency conversion) |
| `category`, `procedureType`, `isFramework`, `setAside` | Services / supplies / works, open / restricted / negotiated…, framework agreement, SAM.gov set-aside (SBA, 8(a), SDVOSB…) or UK "SME suitable" |
| `cpvCodes`, `cpvMain`, `cpvDescription`, `naicsCodes`, `pscCode` | Classification codes |
| `placeOfPerformance`, `documentsUrl`, `submissionUrl` | Where the work happens, tender documents, where to submit |
| `winners`, `awardValue`, `awardCurrency` | Awards: winning companies and awarded value |
| `awardCeiling`, `awardFloor`, `expectedAwards`, `eligibility` | Grants.gov details |
| `isNew`, `scrapedAt` | "Only new" mode marker and scrape time |

### Pricing

**$3 per 1,000 notices** (pay per event: you pay only for the notices saved, nothing for empty searches or errors). Example: a daily alert that finds 30 new notices costs about **$0.09 a day**. Set a maximum cost per run in Apify and the scraper stops right there.

### Tips

- **Too many results?** Add CPV codes or countries, raise the minimum value, or use more specific keywords (`"cloud migration"` instead of `cloud`).
- **CPV codes include their children**: `72000000` returns every IT services code (72200000, 72267000…). For the UK sources the check is done on every lot's codes.
- **Keywords on EU TED** also search the original-language text, so a notice written in German or Polish is found by its English CPV heading too. Add words in the local language for full coverage (`Software`, `logiciel`, `oprogramowanie`).
- **SAM.gov values**: federal opportunities rarely publish an estimated value; awards do (`awardValue`). Keep "Keep notices without a published value" on when you filter by value.
- **Planned / upcoming** notices (prior information notices, presolicitations, sources sought, UK pipeline notices) give you weeks of head start.

### FAQ

**Is this data legal to use?** Yes. All sources are official open data: EU TED is published by the Publications Office of the EU for free reuse, including commercial reuse; UK notices are under the Open Government Licence v3.0; SAM.gov and Grants.gov are US federal public data. The scraper only reads public notices — no login, no personal accounts.

**Do I need a SAM.gov API key?** No.

**How fresh is it?** Live: every run asks the sources directly. TED publishes on working days, the UK and US sources continuously.

**Can I get older notices?** Up to the last 365 days per run.

**Something missing or broken?** Open an issue in the Issues tab — I answer quickly and add sources on request.

### Related Actors

- [Merge, Filter, Deduplicate & Transform Datasets](https://apify.com/tidydata/merge-dedupe-datasets) — combine several tender searches into one deduplicated sheet.
- [Google Sheets Export & Import](https://apify.com/tidydata/google-sheets-export-import) — send your tender alerts straight to a Google Sheet.
- [Company Registry Lookup](https://apify.com/tidydata/company-registry-lookup) — look up the winners and buyers in official company registers.
- [Website Contact Extractor](https://apify.com/tidydata/website-contact-extractor) — get emails and phones from the buyers' websites.

# Actor input Schema

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

Find notices that mention ANY of these words or phrases, e.g. 'software', 'cleaning services', 'solar', 'translation'. EU TED also searches the original-language text and the English heading. Empty = every notice (use filters below to narrow).

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

Where to search. EU TED = all 27 EU countries + EEA (above-threshold tenders). UK Find a Tender = UK above-threshold and Procurement Act notices. UK Contracts Finder = English below-threshold contracts. SAM.gov = US federal contract opportunities. Grants.gov = US federal grants.

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

Open tenders you can bid on, planned / upcoming procurements (prior information, pre-solicitations, sources sought, forecasted grants), or contract awards with the winner and the awarded value.

## `postedWithinDays` (type: `integer`):

1 = today only. Use 1-2 with a daily schedule and 'Only new notices' for alerts. Max 365.

## `maxResultsPerSource` (type: `integer`):

Newest first. Each source stops at this number, so the total is at most this × number of sources.

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

2-letter codes (DE, FR, ES, IT, NL, PL, IE, GB, US…) or English names. Keeps notices from buyers in these countries. Sources that cannot match are skipped (e.g. only DE → just EU TED).

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

Common Procurement Vocabulary codes, children included: 72000000 = IT services, 48000000 = software packages, 79000000 = business services, 45000000 = construction, 90910000 = cleaning, 33000000 = medical equipment, 80000000 = education & training.

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

US industry codes for SAM.gov, e.g. 541511 (custom software), 541512 (computer systems design), 541611 (management consulting), 236220 (commercial construction), 561720 (janitorial).

## `excludeKeywords` (type: `array`):

Drop notices whose title contains any of these, e.g. 'construction', 'catering'.

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

Estimated (or awarded) contract value, in the notice's own currency (EUR, GBP, USD, SEK…). Empty = no minimum.

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

Upper limit for the estimated (or awarded) value, in the notice's currency. Empty = no maximum.

## `keepNoticesWithoutValue` (type: `boolean`):

Many notices do not publish a value (all SAM.gov opportunities, for example). When a minimum or maximum value is set, keep those notices anyway?

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

Skip tenders and grants whose submission deadline is already over. Awards are never affected.

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

Remember what you already got (per source and per search) and output only notices you have not seen. Add a daily schedule for tender alerts by email, Slack or Google Sheets.

## `memoryName` (type: `string`):

Runs that share this name share their memory. Use a different name per client or project.

## `includeDescription` (type: `boolean`):

The notice's scope as clean text. Turn off for lighter rows.

## `descriptionMaxLength` (type: `integer`):

Cut long descriptions to this many characters. 0 = full text.

## `fetchDetails` (type: `boolean`):

Open each SAM.gov and Grants.gov notice to add the contracting officer (name, email, phone), NAICS, set-aside, place of performance, full description, award amount and grant ceiling. A bit slower; same price.

## Actor input object example

```json
{
  "keywords": [
    "software"
  ],
  "sources": [
    "ted",
    "uk-find-a-tender",
    "uk-contracts-finder",
    "sam-gov"
  ],
  "noticeTypes": [
    "tender"
  ],
  "postedWithinDays": 3,
  "maxResultsPerSource": 10,
  "keepNoticesWithoutValue": true,
  "onlyOpen": true,
  "onlyNew": false,
  "memoryName": "default",
  "includeDescription": true,
  "descriptionMaxLength": 0,
  "fetchDetails": true
}
```

# Actor output Schema

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

One row per result.

# 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-find-a-tender",
        "uk-contracts-finder",
        "sam-gov"
    ],
    "postedWithinDays": 3,
    "maxResultsPerSource": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidydata/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-find-a-tender",
        "uk-contracts-finder",
        "sam-gov",
    ],
    "postedWithinDays": 3,
    "maxResultsPerSource": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("tidydata/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-find-a-tender",
    "uk-contracts-finder",
    "sam-gov"
  ],
  "postedWithinDays": 3,
  "maxResultsPerSource": 10
}' |
apify call tidydata/public-tenders-scraper --silent --output-dataset

```

## MCP server setup

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