# Government Tenders Scraper — EU TED, UK, SAM.gov Procurement (`chorelet/government-tenders-scraper`) Actor

Public procurement notices from EU TED, UK Find a Tender, UK Contracts Finder, SAM.gov and grants.gov in one schema — title, buyer, country, CPV/NAICS, deadline and days left, value, documents and awardee. No API key, filter by keyword, code, country or date.

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

## Pricing

from $0.70 / 1,000 tenders

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

## Government Tenders Scraper — EU TED, UK, SAM.gov Procurement

Public procurement notices from five official registers — **EU TED**, **UK Find a Tender**, **UK Contracts Finder**, **US SAM.gov** and **grants.gov** — normalised into one row shape. Same fields, same date format, same country codes, whichever register a notice came from, so a bid team can watch four jurisdictions in one spreadsheet instead of four portals.

No API key anywhere: every source is read through the register's own public API. Point `publishedSince` at `24 hours`, run it on a schedule, and each run returns only what was published since yesterday.

### Why this Actor

- **Four registers, one schema.** EU TED, UK Find a Tender, UK Contracts Finder and SAM.gov normalised into the same fields — most competitors cover a single country.
- **A deadline you can sort by.** TED publishes deadlines per lot and multi-lot values lot by lot; this Actor resolves one `deadline`, computes `daysUntilDeadline` and sums lot values instead of reporting the first one.
- **Built for a daily bid desk.** `publishedSince: "1 day"` plus keyword, CPV, NAICS, country and value filters returns only what is new, and one failing register never fails the run.
- **No key to request.** Every source is read through a public endpoint, including SAM.gov's own site API — no registration, no waiting for approval.

### Sample output

One item of the dataset (long values shortened):

```json
{
  "source": "ted",
  "title": "Spain – Museum services – Servicio de desarrollo de las actividades socioculturales y educativas en los museos estatales",
  "buyerName": "Junta de Contratación del Ministerio de Cultura",
  "buyerCountry": "ES",
  "publishedDate": "2026-09-24T22:00:00.000Z",
  "deadline": "2026-11-04T18:00:00.000Z",
  "daysUntilDeadline": 38,
  "valueAmount": 2202395.07,
  "url": "https://ted.europa.eu/en/notice/-/detail/663556-2026"
}
```

### What you get

- **One schema across five registers** — title, description, buyer, buyer country and region, published and updated dates, deadline, notice type, status, value and currency, CPV and NAICS codes, place of performance, procedure, awardee and links to the tender documents.
- **A single usable deadline.** TED publishes a deadline per lot; the row carries the earliest one still open, plus `daysUntilDeadline` as a plain integer so you can sort by urgency or alert on "closes in 7 days".
- **Filters that behave the same everywhere** — keywords, CPV codes, NAICS codes, buyer countries, notice type, value floor, deadline window. Where a register can apply a filter itself it is pushed upstream; where it cannot, the Actor applies it on the way out.
- **Open opportunities by default.** `activeOnly` drops awards, cancellations and anything whose deadline has passed. Turn it off to collect award notices, winners and contract values instead.
- **Per-source reporting.** Every run writes a `SUMMARY` record with notices kept, pages scanned and the error per source — so a scheduled run can tell you *which* register broke, not just that something did.
- **A failing register never fails the run.** The other four keep going.

### Input

- **Sources** — `ted` (EU TED, all 27 member states plus the EEA), `uk-fts` (Find a Tender, above-threshold UK), `uk-cf` (Contracts Finder, below-threshold UK and awards), `us-sam` (SAM.gov federal contract opportunities), `us-grants` (grants.gov federal funding, opt-in).
- **Keywords** — `software`, `cloud`, `catering`. On TED, SAM.gov and grants.gov these go into the register's own full-text index, which searches the whole notice; on the two UK registers they are matched against the title, summary, buyer and classification.
- **CPV codes** — full or truncated: `72000000`, or just `72` for all IT services, `45` for construction. European registers only.
- **NAICS codes** — `541511`, or `5415` for all computer services. SAM.gov only.
- **Buyer countries** — `DE`, `FRA`, `Poland`, `United Kingdom`; two letters, three letters or the plain name all work.
- **Published since** — `24 hours`, `7 days`, `1 month` or an absolute `2026-01-31`. This is the daily-run setting.
- **Deadline from / to**, **Open opportunities only**, **Notice types** (`planning`, `tender`, `award`, `amendment`), **Minimum contract value** + currency, **Max results per source**.
- **Fetch full notice text and attachments** — one extra request per notice on TED, SAM.gov and grants.gov: the complete notice body instead of the summary, plus links to the tender documents. Charged separately.

### Limits and notes

- **TED caps a page at 250 notices** and rejects anything larger outright. Paging is handled for you; `maxResultsPerSource` is the only knob you need.
- **TED notices are filed in the buyer's own language.** TED translates the standard title header into all 24 EU languages — the Actor keeps the English one — but `description` stays in the language the buyer filed in, usually not English. `language` tells you which.
- **Both UK registers rate-limit hard**: about a dozen requests and they answer `429` with a two-minute lockout, however slowly the requests are spaced. The Actor paces itself to stay inside that and stops after 800 notices scanned per register per run; `SUMMARY` sets `pageLimitHit` when a source stopped early, so narrow the date window if you need to go deeper.
- **SAM.gov is read through the public search API sam.gov itself uses.** The documented `api.sam.gov/opportunities/v2/search` endpoint needs a registered key and returns `404` without one, so it is not used. The public endpoint has no server-side date filter and sorts only by last modification, so on SAM.gov `publishedSince` means "published *or updated* since". NAICS codes and the place of performance only reach the row when "fetch full notice text" is on.
- **SAM.gov publishes no contract value** on opportunity notices, so `valueAmount` is null there. grants.gov reports the award ceiling instead of a contract value.
- **Values are never converted.** Each notice carries the currency its buyer published; set the currency alongside a minimum value or you will be comparing euros with pounds.
- **CPV exists only on the European registers, NAICS only on SAM.gov.** A CPV filter does not silently empty out the US sources, and a NAICS filter does not empty out the European ones.
- **grants.gov searches the whole announcement**, so a keyword can match text far from the title — expect results that look off-topic until you open them. Its own date window counts whole days, so `publishedSince` is rounded up by one day there rather than cutting a notice off by a few hours.
- **The two UK registers already publish the full description and document list in the list response**, so "fetch full notice text" does nothing extra there and is not charged for them.

### Input example

```json
{
  "sources": [
    "ted",
    "uk-fts"
  ],
  "publishedSince": "3 days",
  "activeOnly": true,
  "minValue": 0,
  "maxResultsPerSource": 25,
  "fetchDetails": false
}
```

### How much does it cost?

Pay per tender — no subscription, no minimum, no charge for platform usage.

| Volume | Price |
|---|---|
| 1,000 tenders | $1.00 (+ $2.00 with `detail`) |
| 10,000 tenders | $10.00 (+ $20.00 with `detail`) |
| 100,000 tenders | $100.00 (+ $200.00 with `detail`) |

The Apify **free plan includes $5 of usage every month** — about 5,000 tenders with this Actor, no card needed. Nothing else is charged: platform usage is included in the price, and Apify Bronze, Silver and Gold subscribers get 10%, 20% and 30% off these prices.

### Use it from code, n8n, Make, Zapier or an AI agent

Run the Actor and download the dataset in one call (JSON by default; add `&format=csv` or `xlsx`):

```bash
curl -X POST "https://api.apify.com/v2/acts/chorelet~government-tenders-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sources": ["ted", "uk-fts"], "publishedSince": "3 days", "activeOnly": true, "minValue": 0, "maxResultsPerSource": 25, "fetchDetails": false}'
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("chorelet/government-tenders-scraper").call(run_input={"sources": ["ted", "uk-fts"], "publishedSince": "3 days", "activeOnly": true, "minValue": 0, "maxResultsPerSource": 25, "fetchDetails": false})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

- **n8n, Make, Zapier** — use the Apify node/module: run the Actor, then "get dataset items".
- **Google Sheets, Slack, webhooks** — add an integration on the run's *Integrations* tab.
- **AI agents** — the Actor is available as a tool through the Apify MCP server; the dataset schema describes every field for the model.
- **Schedules** — run it hourly, daily or weekly from the *Schedules* tab.

### FAQ

**Which registers are covered?**

EU TED (every EU member state plus the EEA), UK Find a Tender and Contracts Finder, and US SAM.gov federal opportunities. grants.gov is available as an opt-in source for US federal grants.

**Do I need an API key for SAM.gov?**

No. The documented api.sam.gov endpoint needs a registered key, so this Actor reads the public search API that sam.gov's own website calls, which needs none.

**How do I watch for new tenders every day?**

Set *Published since* to `1 day`, add your keywords, CPV or NAICS codes, and schedule the Actor daily. Each run returns only notices published since the last one.

**Why is the value empty on some notices?**

Because the register does not publish one. SAM.gov opportunity notices carry no value at all, and many UK notices omit it; the field is null rather than guessed.

**What does *Fetch details* add?**

The full notice text and the list of attachments, one extra request per notice, charged separately. The search results alone already carry title, buyer, dates, deadline, value and CPV/NAICS codes.

### Support

Questions, missing fields or a source that changed? Open an issue on the *Issues* tab or write to support@chorelet.app — problems are usually fixed within a day, and the Actor is checked every morning by an automated test run. If the Actor saved you time, a short review on its Store page helps other people find it.

# Actor input Schema

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

Which official registers to read. `ted` = EU Tenders Electronic Daily (all 27 EU states + EEA), `uk-fts` = UK Find a Tender (above-threshold), `uk-cf` = UK Contracts Finder (below-threshold and awards), `us-sam` = SAM.gov federal contract opportunities, `us-grants` = grants.gov federal funding. All of them are read without an API key.

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

Keep only notices whose title, description, buyer or classification contains any of these, e.g. `software`, `cloud`, `catering`. On TED the words are pushed into the full-text index; everywhere else they are matched on the way out. Empty = every notice in the window.

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

EU Common Procurement Vocabulary codes, full or truncated: `72000000` or just `72` for all IT services, `45` for construction. Applies to TED and the two UK registers.

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

US industry codes for SAM.gov, full or truncated: `541511` (custom programming) or `5415` for all computer services.

## `buyerCountries` (type: `array`):

Two- or three-letter codes or plain names: `DE`, `FRA`, `Poland`, `United Kingdom`. A notice is kept when either the buyer or the place of performance is in the list.

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

Absolute `2026-01-31` or relative `24 hours`, `7 days`, `1 month`. This is the daily-run setting: point it at `24 hours` and every run returns only what appeared since yesterday.

## `deadlineFrom` (type: `string`):

Keep only notices closing on or after this point: `2026-11-01` or relative `7 days`. Useful to skip anything you could not realistically bid on.

## `deadlineTo` (type: `string`):

Keep only notices closing on or before this point: `2026-12-31` or relative `60 days`.

## `activeOnly` (type: `boolean`):

Drop awards, cancellations and anything whose deadline has already passed. Turn it off to collect award notices and contract history.

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

`planning` = prior information / forecast, `tender` = live call for bids, `award` = contract awarded, `amendment` = correction or update. Empty = all of them.

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

Drop notices below this amount. `0` = no minimum. Values are published in the buyer's own currency and are never converted, so set the currency below when you use this.

## `valueCurrency` (type: `string`):

Only compare the minimum against notices published in this currency, e.g. `EUR`, `GBP`. Empty = compare against whatever currency the notice uses.

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

Newest first per source. Five sources at 100 each is 500 rows.

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

One extra request per notice on TED, SAM.gov and grants.gov: the complete notice body instead of the summary, plus links to the tender documents. Charged separately. The two UK registers already publish the full text in the list, so nothing extra is fetched or charged for them.

## Actor input object example

```json
{
  "sources": [
    "ted",
    "uk-fts"
  ],
  "keywords": [],
  "cpvCodes": [],
  "naicsCodes": [],
  "buyerCountries": [],
  "publishedSince": "3 days",
  "activeOnly": true,
  "noticeTypes": [],
  "minValue": 0,
  "maxResultsPerSource": 25,
  "fetchDetails": false
}
```

# Actor output Schema

## `tenders` (type: `string`):

All notices — items of the default dataset. Use ?format=csv or xlsx on this URL for spreadsheets.

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

Notices kept, pages scanned and errors per source, plus the filters the run used.

# 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": [
        "ted",
        "uk-fts"
    ],
    "keywords": [],
    "cpvCodes": [],
    "naicsCodes": [],
    "buyerCountries": [],
    "publishedSince": "3 days",
    "deadlineFrom": "",
    "deadlineTo": "",
    "activeOnly": true,
    "noticeTypes": [],
    "minValue": 0,
    "valueCurrency": "",
    "maxResultsPerSource": 25,
    "fetchDetails": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("chorelet/government-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 = {
    "sources": [
        "ted",
        "uk-fts",
    ],
    "keywords": [],
    "cpvCodes": [],
    "naicsCodes": [],
    "buyerCountries": [],
    "publishedSince": "3 days",
    "deadlineFrom": "",
    "deadlineTo": "",
    "activeOnly": True,
    "noticeTypes": [],
    "minValue": 0,
    "valueCurrency": "",
    "maxResultsPerSource": 25,
    "fetchDetails": False,
}

# Run the Actor and wait for it to finish
run = client.actor("chorelet/government-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 '{
  "sources": [
    "ted",
    "uk-fts"
  ],
  "keywords": [],
  "cpvCodes": [],
  "naicsCodes": [],
  "buyerCountries": [],
  "publishedSince": "3 days",
  "deadlineFrom": "",
  "deadlineTo": "",
  "activeOnly": true,
  "noticeTypes": [],
  "minValue": 0,
  "valueCurrency": "",
  "maxResultsPerSource": 25,
  "fetchDetails": false
}' |
apify call chorelet/government-tenders-scraper --silent --output-dataset

```

## MCP server setup

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