# TED Tenders Scraper - EU Public Procurement Notices (`sweet_stickball/ted-tenders-scraper`) Actor

TED tenders scraper: search EU public procurement notices (Tenders Electronic Daily) by keywords or expert query, buyer country, CPV code, publication date and notice type. Title, buyer, CPV codes, procedure, deadline, estimated value, lots, TED and PDF links. Official TED API, no API key.

- **URL**: https://apify.com/sweet_stickball/ted-tenders-scraper.md
- **Developed by:** [CrawlKit](https://apify.com/sweet_stickball) (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 $1.70 / 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

## TED Tenders Scraper - EU Public Procurement Notices

Search EU public tenders published on TED (Tenders Electronic Daily, the online Supplement to the Official Journal of the European Union) by keywords, buyer country, CPV code, publication date and notice type. The Actor returns one flat JSON record per notice: title, buyer, country, CPV codes, notice and procedure type, deadline, estimated value, number of lots, and links to the TED page, PDF and XML.

### What it does

- Queries the official **TED Search API v3** (`POST https://api.ted.europa.eu/v3/notices/search`), which is public and needs no API key. No web page is scraped.
- Accepts plain keywords (full-text search) or a **TED expert-search query** (`classification-cpv=72000000 AND buyer-country=FRA`), combined with optional filters.
- Returns the newest notices first and pages through the results until `maxItems` is reached (40 notices per request).
- Covers every notice type published on TED: prior information notices, contract notices, contract award notices, modifications, corrigenda, for all countries that publish on TED.
- Gives titles, buyer names and PDF links in the language you choose (24 EU languages), with fallback to English, then to the original language.

### Input

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `query` | string | No | — | Keywords (`cloud computing`) or a TED expert query (`classification-cpv=72000000 AND buyer-country=FRA`). Expert syntax is detected automatically. |
| `countries` | array | No | — | Buyer countries as ISO codes, 2 or 3 letters (`FR`, `DEU`). |
| `cpvCodes` | array | No | — | CPV codes, 8 digits (`72000000` or `72000000-5`). A parent code also matches its sub-codes. |
| `publishedFrom` | string | No | — | Earliest publication date (`YYYY-MM-DD`). |
| `publishedTo` | string | No | — | Latest publication date (`YYYY-MM-DD`). |
| `noticeTypes` | array | No | all | TED notice-type codes: `cn-standard` (contract notice), `can-standard` (award), `pin-only`, `can-modif`, `veat`, `corr`... |
| `language` | string | No | `en` | Language of titles, buyer names and PDF links. |
| `maxItems` | integer | No | 20 | Maximum number of notices to return. |

All criteria are combined with AND. With no criterion at all, the notices published during the last 7 days are returned.

Example input:

```json
{
    "query": "software",
    "countries": ["FR", "DE"],
    "cpvCodes": ["72000000"],
    "publishedFrom": "2026-10-01",
    "noticeTypes": ["cn-standard"],
    "maxItems": 50
}
```

### Output

One dataset item per notice (real example):

```json
{
    "publicationNumber": "760147-2026",
    "title": "France – IT services: consulting, software development, Internet and support – Accord-cadre relatif à la mise à disposition de solutions en mode SaaS pour le système d’information métier de l’Inrap, à leurs mises en œuvre et aux prestations associées",
    "titleOriginal": "Accord-cadre relatif à la mise à disposition de solutions en mode SaaS pour le système d’information métier de l’Inrap, à leurs mises en œuvre et aux prestations associées",
    "buyerName": "Inrap",
    "buyerCountry": "FRA",
    "cpvCodes": ["72000000"],
    "noticeType": "cn-standard",
    "procedureType": "neg-w-call",
    "contractNature": "services",
    "publicationDate": "2026-11-02",
    "deadline": "2026-11-30",
    "estimatedValue": 750000.0,
    "currency": "EUR",
    "lotsCount": 4,
    "url": "https://ted.europa.eu/en/notice/-/detail/760147-2026",
    "pdfUrl": "https://ted.europa.eu/en/notice/760147-2026/pdf",
    "xmlUrl": "https://ted.europa.eu/en/notice/760147-2026/xml",
    "scrapedAt": "2026-11-02T22:24:22+00:00"
}
```

| Field | Description |
|-------|-------------|
| `publicationNumber` | TED notice number (number-year) |
| `title` | TED title in the chosen language: country – subject – procedure title |
| `titleOriginal` | Procedure title as written by the buyer |
| `buyerName` | Contracting authority (the first one for joint procurement) |
| `buyerCountry` | ISO 3166-1 alpha-3 country code of the buyer |
| `cpvCodes` | Distinct CPV codes of the notice, all lots included |
| `noticeType` / `procedureType` / `contractNature` | TED codes (`cn-standard`, `open`, `services`...) |
| `publicationDate` | Publication date in the OJ S |
| `deadline` | Earliest deadline for tenders or requests to participate (date or date-time) |
| `estimatedValue` / `currency` | Estimated value of the procedure, or the sum of the lots when they share one currency |
| `lotsCount` | Number of lots |
| `url` / `pdfUrl` / `xmlUrl` | TED notice page, PDF and original XML |

### Pricing

Pay-per-event, no start fee: **$2.80 per 1,000 notices** (event `NOTICE`) on the Apify Free plan, lower on paid plans. You only pay for results pushed to the dataset.

| Apify plan | Price per 1,000 notices |
|---|---|
| Free | $2.80 |
| Starter | $2.40 |
| Scale | $2.10 |
| Business | $1.70 |

Set a maximum cost per run in the run options: the Actor stops cleanly when it is reached.

### Data source and reuse

Data comes from TED, operated by the Publications Office of the European Union, through its public Search API, which does not require authentication. The TED legal notice states that the procurement notices published in the Supplement to the Official Journal of the European Union can be freely reused, for commercial or non-commercial purposes. This Actor is not affiliated with or endorsed by the Publications Office or the European Union, and does not use the TED logo.

### Limitations

- `estimatedValue` is often empty: many buyers do not publish an estimate, and award notices carry the awarded value instead (not returned). On a sample of 50 IT contract notices, 12 had an estimated value.
- `deadline` is empty for notices without a submission phase (award notices, modifications, most prior information notices).
- `buyerName` and `buyerCountry` give the first buyer only; joint procurement notices (EU institutions) can list dozens of buyers.
- When lots have different estimated values in different currencies, `estimatedValue` is left empty rather than summed.
- `title` follows TED's format (country – subject – procedure title); TED translates the first two parts, the procedure title stays in the original language.
- Keyword search is TED's full-text search (`FT~`) over all languages of the notice. Quotes and brackets are removed from plain keywords; use expert syntax for phrase or field searches.
- The output covers the fields listed above; lot-level details (per-lot values, award winners) are not returned. Use `xmlUrl` for the complete notice.

### Related Actors

- [Contact Details Scraper - Emails, Phones and Social Links](https://apify.com/sweet_stickball/contact-details-scraper) — Contact details scraper and email extractor for any list of websites: emails, phones in E.164, LinkedIn, X, Facebook, Instagram, YouTube, TikTok and GitHub profiles, address and company name from contact, Impressum and legal pages.
- [Google News Scraper API - Articles by Keyword, No Login](https://apify.com/sweet_stickball/google-news-scraper) — Scrape Google News articles for any keyword: headlines, sources, dates and URLs by country and language. News monitoring API, no API key or login.
- [SEC EDGAR Filings & Yahoo Finance Scraper](https://apify.com/sweet_stickball/sec-edgar-yahoo-finance) — Scrape SEC EDGAR filings (10-K, 10-Q, 8-K) by ticker or CIK, plus stock quotes and annual financial statements from Yahoo Finance.

# Actor input Schema

## `query` (type: `string`):

Plain keywords (full-text search, e.g. 'cloud computing') or a TED expert-search query (e.g. 'classification-cpv=72000000 AND buyer-country=FRA'). Expert syntax is detected automatically (=, ~, IN (...), SORT BY). Leave empty to use only the filters below; with no criterion at all, the notices of the last 7 days are returned.

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

Country of the contracting authority, as ISO codes: 2 letters (FR, DE, PL) or 3 letters (FRA, DEU, POL). Several values = any of them.

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

Common Procurement Vocabulary codes (8 digits, check digit optional: 72000000 or 72000000-5). A parent code also matches its sub-codes (72000000 = all IT services).

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

Earliest publication date on TED (YYYY-MM-DD), inclusive.

## `publishedTo` (type: `string`):

Latest publication date on TED (YYYY-MM-DD), inclusive.

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

TED notice-type codes. Common values: cn-standard (contract notice), cn-social, pin-only (prior information), pin-cfc-standard, can-standard (contract award notice), can-modif (modification), veat (voluntary ex-ante transparency), corr (corrigendum, older notices). Empty = all types.

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

Language of the title, buyer name and PDF link when TED has it (falls back to English, then to the original language).

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

Maximum number of notices to return (one billed event per notice).

## Actor input object example

```json
{
  "query": "cloud computing",
  "countries": [
    "FR",
    "DE"
  ],
  "cpvCodes": [
    "72000000"
  ],
  "publishedFrom": "2026-10-01",
  "publishedTo": "2026-10-31",
  "noticeTypes": [
    "cn-standard"
  ],
  "language": "en",
  "maxItems": 10
}
```

# Actor output Schema

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

TED procurement notices shown with the 'notices' view.

# 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 = {
    "query": "cloud computing",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("sweet_stickball/ted-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 = {
    "query": "cloud computing",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("sweet_stickball/ted-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 '{
  "query": "cloud computing",
  "maxItems": 10
}' |
apify call sweet_stickball/ted-tenders-scraper --silent --output-dataset

```

## MCP server setup

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