# Public Tenders Scraper - EU TED & SAM.gov Government Contracts (`offgrid-labs/public-tenders-eu-us`) Actor

Public tenders scraper for government contracts and procurement: TED tenders (Tenders Electronic Daily, all EU countries) and SAM.gov notices in one unified format - buyer, CPV/NAICS codes, value, deadline, winning supplier, document links. Official APIs only. $3.50 per 1,000 notices.

- **URL**: https://apify.com/offgrid-labs/public-tenders-eu-us.md
- **Developed by:** [OFFGRID LABS](https://apify.com/offgrid-labs) (community)
- **Categories:** Business, 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 $3.50 / 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.

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 and US SAM.gov government contracts in one feed

**TL;DR:** Public Tenders Scraper finds government tenders, RFPs, contract notices and contract awards in the **European Union (TED)** and the **United States (SAM.gov)** and returns them in one unified format: title, buyer, country, CPV / NAICS codes, estimated or awarded value, deadline, winning supplier and links to the official notice and documents. It is built for bid and sales teams, consultants, market-intelligence analysts and AI agents. You pay **$3.50 per 1,000 notices** saved.

It uses only the official public APIs, with no browser, login or proxy:

- **TED - Tenders Electronic Daily** (Publications Office of the EU, TED Search API v3): the online Supplement to the Official Journal of the EU, which carries around 800,000 public procurement notices a year worth more than €815 billion ([European Commission](https://single-market-economy.ec.europa.eu/single-market/public-procurement/digital-procurement/tenders-electronic-daily_en)). No key needed.
- **SAM.gov Get Opportunities API v2** (US General Services Administration): US federal contract opportunities and awards. Needs **your own free SAM.gov public API key**.

### What data you get

One dataset row per notice, with the same fields whatever the source.

| Field | What it is | Example |
|---|---|---|
| `source`, `noticeId`, `noticeNumber` | `ted` or `sam`, notice identifiers | `ted`, `760549-2026` |
| `title`, `description` | Notice title and description | `Germany – System and support services – ...` |
| `noticeType`, `procedureType`, `contractNature` | Notice stage, procedure, works/supplies/services | `can-standard`, `open`, `services` |
| `buyerName`, `buyerCountry`, `buyerCity` | Contracting authority | `Informationstechnikzentrum Bund (ITZBund)`, `DEU`, `Bonn` |
| `cpvCodes`, `naicsCodes`, `classificationCode` | CPV (TED), NAICS and PSC (SAM.gov) codes | `["72250000"]` |
| `setAside` | US small-business set-aside (SAM.gov) | `SBA` |
| `estimatedValue`, `awardedValue`, `currency` | Values where the buyer publishes them | number or `null`, `EUR` |
| `awardee` | Winning supplier (award notices) | `SVA System Vertrieb Alexander GmbH` |
| `publishedAt`, `deadlineAt` | Publication date and submission deadline | `2026-11-03` |
| `placeOfPerformance` | Where the contract is performed | `DEU` |
| `contacts[]` | Official points of contact (SAM.gov) | |
| `url`, `descriptionUrl`, `documentUrls[]` | Official notice page, description link, PDF/XML | `https://ted.europa.eu/en/notice/-/detail/760549-2026` |
| `sourceUrl`, `scrapedAt` | API endpoint used and scrape time | |

A run summary (query used, matches, API calls) is saved in the key-value store record `RUN_SUMMARY`.

| | TED (EU) | SAM.gov (US) |
|---|---|---|
| Coverage | EU/EEA above-threshold procurement + other countries publishing on TED | US federal contract opportunities and awards |
| Key | None | Your free SAM.gov public API key |
| Filters | Keywords (full text), buyer countries, CPV codes, notice type, value | Keywords (titles), NAICS codes, US states, notice type, value |
| Max per query | 15,000 notices | Daily quota of your key |

### Use cases

- **Bid and sales teams**: a daily list of new tenders for your keywords, CPV or NAICS codes.
- **Market intelligence**: see who buys what, for how much, and who wins (award notices with winner and value).
- **Consultants and bid writers**: monitor several countries in one feed instead of many national portals.
- **Data and AI**: build procurement datasets with consistent fields across the EU and US.

### How to scrape public tenders

1. Choose **Sources**: `ted` (EU, no key) and/or `sam` (US, needs your free key).
2. Add **Keywords** (for example `cybersecurity`, `road maintenance`). TED searches the full notice text; SAM.gov searches titles.
3. Set the date range: **Published within last N days** (default 7) or **Published on or after**.
4. Optional filters: **Notice type** (open tenders / awards / planning), **Buyer countries** and **CPV codes** for TED, **NAICS codes** and **US states** for SAM.gov, **Minimum value**.
5. Click **Start**. Schedule it daily with **Published within last N days** = 1 to get only new notices.

#### How to get a SAM.gov API key (free)

Sign in at sam.gov, open **Account Details**, and request a **Public API Key**. Paste it into **SAM.gov API key** (stored encrypted, never written to the dataset). Public keys have small daily quotas, so the scraper asks for 1,000 records per call and filters locally to use as few calls as possible.

### Input example

```json
{
  "sources": ["ted", "sam"],
  "keywords": ["cloud services", "cybersecurity"],
  "postedWithinDays": 7,
  "noticeCategory": "competition",
  "countries": ["DE", "FR", "NL"],
  "cpvCodes": ["72", "48000000"],
  "naicsCodes": ["5415"],
  "usStates": ["VA", "DC"],
  "samApiKey": "<your SAM.gov key>",
  "maxItemsPerSource": 500
}
```

### Output example

```json
{
  "source": "ted",
  "noticeId": "760549-2026",
  "noticeNumber": "760549-2026",
  "title": "Germany – System and support services – Rahmenvertrag für Dienstleistungen Systemmanagement pServer/AIX",
  "description": "Das ITZBund möchte einen Rahmenvertrag schließen und benötigt externe Unterstützung im Bereich Systemmanagement ...",
  "noticeType": "can-standard",
  "procedureType": "open",
  "contractNature": "services",
  "buyerName": "Informationstechnikzentrum Bund (ITZBund)",
  "buyerCountry": "DEU",
  "buyerCity": "Bonn",
  "cpvCodes": ["72250000", "72200000", "72220000", "72514000"],
  "naicsCodes": [],
  "classificationCode": null,
  "setAside": null,
  "estimatedValue": null,
  "awardedValue": null,
  "currency": null,
  "awardee": "SVA System Vertrieb Alexander GmbH",
  "publishedAt": "2026-11-03",
  "deadlineAt": null,
  "placeOfPerformance": "DEU",
  "contacts": [],
  "url": "https://ted.europa.eu/en/notice/-/detail/760549-2026",
  "descriptionUrl": null,
  "documentUrls": ["https://ted.europa.eu/en/notice/760549-2026/pdf", "https://ted.europa.eu/en/notice/760549-2026/xml"],
  "sourceUrl": "https://api.ted.europa.eu/v3/notices/search#page=1",
  "scrapedAt": "2026-11-03T01:19:09.552Z"
}
```

SAM.gov records also fill `naicsCodes`, `classificationCode` (PSC), `setAside`, `contacts`, `awardee`/`awardedValue` for award notices, and `descriptionUrl`. The dataset has two views: **Overview - one row per notice** and **All fields - tenders and awards**.

### How much does it cost to scrape tenders?

Pay per event: you pay only for notices saved. Compute and proxy costs are included. The price is the same on every Apify plan.

| Event | Charged when | Price |
|---|---|---|
| `result` | One tender or award notice saved | **$3.50 per 1,000** ($0.0035 each) |
| `apify-actor-start` | Once per run (Apify's standard start fee) | $0.00005 |

**Worked examples**

- **1,000 notices** = 1,000 × $0.0035 = **$3.50** (+ $0.00005 start fee).
- A daily alert for one market with 20-50 new notices a day: 600-1,500 notices a month = **about $2.10-$5.25 per month**.
- A one-off award-notice study of 10,000 notices: **$35.00**.

Set **Maximum cost per run** in the run options; the scraper stops cleanly at the limit.

### How it compares

| | This actor | Official portals (TED, SAM.gov websites) | Commercial tender-alert services |
|---|---|---|---|
| EU + US in one schema | Yes | Separate sites and formats | Often, plus more national sources |
| Automation | API, schedules, webhooks, integrations | Manual search / saved alerts | Email alerts, platform |
| Award winners and values | Yes, where published | Yes | Yes |
| National below-threshold portals | Not included | Separate national sites | Often included |
| Cost | $3.50 per 1,000 notices, pay as you go | Free | Subscription |

### FAQ

#### How do I find government tenders for my industry?

Use **CPV codes** (TED, for example `72` for IT services or `45` for construction) or **NAICS codes** (SAM.gov, for example `5415`), plus **Keywords**. Set **Notice type** to `competition` for tenders you can still bid on.

#### Which countries does TED cover?

All EU member states plus EEA and other countries that publish on TED (Norway, Iceland, Switzerland, North Macedonia, Serbia, Montenegro, Albania, Ukraine and others). National below-threshold tenders that are not published on TED are not included.

#### How do I see who won a public contract?

Set **Notice type** to `award`. Award notices fill `awardee` and, where published, `awardedValue` and `currency`.

#### Do I need an API key?

Not for TED. For SAM.gov you need your own free public API key from sam.gov (Account Details > Public API Key).

#### Why are some values empty?

Buyers are not required to publish every field. Many contract notices have no estimated value, and SAM.gov opportunities have no estimated value field at all.

#### Can I get the full SAM.gov description?

The API returns a description link (`descriptionUrl`); add `&api_key=<your key>` to read it. The scraper does not fetch it automatically, to save your daily quota.

#### Is it legal to scrape public tenders?

TED data is published by the EU Publications Office for free reuse (Commission Decision 2011/833/EU), and the TED API is the official machine access. SAM.gov data is US federal public information accessed through GSA's official API with your own key. Contacts are official business contacts published on the notices; use them in line with applicable law (for example GDPR, CAN-SPAM).

#### Can an AI agent search tenders with this actor?

Yes. Through the Apify MCP server an agent can find it with `search-actors`, read the input schema and run it, for example "open IT-services tenders in Germany published this week". See **Integrations**.

#### Something wrong?

Open an issue on the Issues tab; we aim to respond within 24 hours.

### Integrations

- **API**: `POST https://api.apify.com/v2/acts/offgrid-labs~public-tenders-eu-us/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>` with the input JSON as the body returns the notices directly (runs under 5 minutes; otherwise start a run and read its dataset).
- **Python / JavaScript**: `pip install apify-client` / `npm install apify-client`, then `client.actor("offgrid-labs/public-tenders-eu-us").call(run_input={...})`.
- **No-code**: Apify's integrations for **Make**, **Zapier** and **n8n**, plus Google Sheets, Slack, email, webhooks and Schedules (for example a daily tender alert in Slack).
- **MCP / AI agents**: add `https://mcp.apify.com?tools=offgrid-labs/public-tenders-eu-us` to your MCP client to expose this actor as a tool.

### Changelog

- **2026-11-03** · README restructured (source table, cost examples, comparison, FAQ, integrations); input field descriptions rewritten with formats, defaults and examples for AI agents; output schema and dataset views described; Store title "Public Tenders Scraper - EU TED & SAM.gov Government Contracts". Removed an incorrect line about plan discounts: the price is a flat $3.50 per 1,000 notices on every plan.
- **2026-11-03** · Output schema with Overview and All fields views; Store title aligned with search intent.
- **2026-11-03** · First release: TED Search API v3 (no key) and SAM.gov Get Opportunities API v2 (your key), unified schema, keyword/country/CPV/NAICS/state/value/notice-type filters, `RUN_SUMMARY`.

### Related actors

| Actor | What it does |
|---|---|
| US Building Permits Scraper | Issued building permits from 12 US city open-data portals |
| Company Registry Lookup (KYB) | Company records from official business registers (UK, France, Norway, Finland) for buyers and winners |
| SEC EDGAR Scraper | Filings, Form 4 insider transactions and XBRL financials from the SEC |

***

```
// OFFGRID LABS ─────────────────────────────────────────────
// status: monitored 24/7 by a self-hosted agent swarm
// health checks: every 6h · auto-repair + rollback on failure
// sources: official public APIs and open data only
// support: open an issue — human-reviewed response within 24h
// ───────────────────────────────────────────────────────────
```

# Actor input Schema

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

Which procurement databases to search. ted = EU TED (Tenders Electronic Daily): EU/EEA public tenders and awards, no key needed. sam = US SAM.gov federal contract opportunities: needs your own free SAM.gov public API key (field below). Default \["ted"]. Example: \["ted", "sam"]

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

Optional. Keep notices matching ANY of these keywords. TED searches the full notice text; SAM.gov searches titles. Leave empty for all notices in the date range. Examples: cloud services, road maintenance, cybersecurity

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

Only notices published in the last N days. Default 7. 0 = no date limit for TED, last 30 days for SAM.gov. Ignored when 'Published on or after' is set. Example: 1 for a daily alert

## `postedAfter` (type: `string`):

Optional fixed start date in YYYY-MM-DD format; overrides 'Published within last N days'. SAM.gov allows at most a 1-year window. Example: 2026-10-01

## `noticeCategory` (type: `string`):

Filter by procurement stage: all (default), competition = open tenders / contract notices you can bid on, award = contract award notices with winner and value, planning = prior information notices.

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

Optional, TED only. ISO country codes (2- or 3-letter) of the buying organisation. Leave empty for all countries. Examples: DE, FR, ES, PL, NL

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

Optional, TED only. Common Procurement Vocabulary codes; a prefix matches the whole branch. Examples: 72 (IT services), 45 (construction work), 48000000 (software packages)

## `language` (type: `string`):

Language for TED notice titles (available in all EU languages). Buyer names and descriptions are usually only in the original language. Default en.

## `samApiKey` (type: `string`):

Required only for the sam source. Your own free SAM.gov public API key (sign in at sam.gov > Account Details > Public API Key). Stored encrypted; never written to the dataset.

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

Optional, SAM.gov only. NAICS industry codes or prefixes. Examples: 541512 (computer systems design), 5415, 236220

## `usStates` (type: `array`):

Optional, SAM.gov only. Two-letter US state codes for the place of performance. Examples: VA, MD, DC, TX

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

Optional. Keep only notices with an estimated or awarded value of at least this amount, in the notice's own currency (EUR for most TED notices). Notices without a value are excluded when set. Default 0 = no value filter. Example: 100000

## `maxItemsPerSource` (type: `integer`):

Maximum notices saved per source; one notice = one dataset row = one charged result. Default 100. 0 = no limit (TED stops at 15,000 per query). Example: 500

## Actor input object example

```json
{
  "sources": [
    "ted"
  ],
  "keywords": [
    "software"
  ],
  "postedWithinDays": 3,
  "noticeCategory": "all",
  "language": "en",
  "minValue": 0,
  "maxItemsPerSource": 20
}
```

# Actor output Schema

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

All tender and award notice rows with every field.

## `overview` (type: `string`):

Compact table: source, title, buyer, buyer country, notice type, estimated value, currency, published date, deadline and link.

# 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"
    ],
    "keywords": [
        "software"
    ],
    "postedWithinDays": 3,
    "maxItemsPerSource": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("offgrid-labs/public-tenders-eu-us").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"],
    "keywords": ["software"],
    "postedWithinDays": 3,
    "maxItemsPerSource": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("offgrid-labs/public-tenders-eu-us").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"
  ],
  "keywords": [
    "software"
  ],
  "postedWithinDays": 3,
  "maxItemsPerSource": 20
}' |
apify call offgrid-labs/public-tenders-eu-us --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,offgrid-labs/public-tenders-eu-us"
        }
    }
}
```

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/602LFHFfxsUfFrcaN/builds/hFJ9eFIjUvAyapfy3/openapi.json
