# EU Tenders, TED notices: public procurement, no contact data (`autoaugeo/eu-tenders-ted-notices-b455`) Actor

EU tenders from TED (Tenders Electronic Daily): search EU public procurement notices by buyer country, CPV code, date and keyword. Buyer, deadline, estimated value and link as flat JSON, no contact data. $0.005 per result, no start fee. Unofficial, not affiliated with the EU Publications Office.

- **URL**: https://apify.com/autoaugeo/eu-tenders-ted-notices-b455.md
- **Developed by:** [Augeo auto](https://apify.com/autoaugeo) (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

$5.00 / 1,000 results

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

## EU Tenders (TED notices, no personal data)

EU tenders from TED (Tenders Electronic Daily, the online Supplement to the Official Journal of the European Union) with no contact data and no start fee: search public procurement notices by buyer country, CPV code, publication date and keyword, and get 12 flat fields per notice, never a buyer e-mail or phone number, one charge per delivered notice and nothing else, and a hard stop at 1,000 notices so a run cannot cost more than $5.00. This is how the Actor is built to behave; it has not yet been run against the live API (see "Not yet verified" below).

This Actor is **unofficial**. It is not affiliated with or endorsed by the data publisher, the Publications Office of the European Union.

### What it does

- Sends your filters (buyer country, CPV code, publication date range, keyword) to the official TED Search API, which its documentation describes as open and needing no key.
- Reads the results page by page: one request at a time, a one-second pause between pages. It stops when it has the number of notices you asked for, when TED returns an empty page, or when the pages read cover the total TED reports.
- Returns one flat record per notice with a fixed set of fields.
- Never requests contact persons, e-mail addresses, phone numbers or street addresses. See "Privacy" below.

It uses no proxy, no login and no API key, and it contacts no host other than the TED Search API.

### Use cases for EU tenders and TED notices

Three jobs this Actor is built for. Each one maps to a ready-to-run input further down this page. None of these inputs has been run against the live API; everything under "Not yet verified" applies.

#### Bid monitoring by CPV code

A bid team follows one category of contract and wants every new public procurement notice in it, whichever country the buyer is in. Put the CPV code in `cpvCodes`: a full 8-digit code matches that code, a prefix of 2 to 7 digits matches every code that starts with it. Each notice comes back with its `cpvCodes`, `buyerName`, `tenderDeadline` (when TED provides it) and `noticeUrl`, so the team can sort by deadline and open the notice on the TED website.

- Input to start from: example 1, "Notices by CPV code" (IT services and software packages, September 2026, at most 100 results x $0.005 = $0.50).
- To search a subject that no single CPV code covers, use example 4, "Notices by keyword".

#### EU tenders by buyer country

A sales or market-research team wants to see what public buyers in chosen countries published. Put the countries in `countries`; several countries are combined with OR, and any other filter you add is combined with AND. Each notice comes back with `buyerCountries` as 3-letter ISO codes.

- Input to start from: example 2, "Notices by buyer country" (buyers in Ireland or France over ten days, at most 50 results x $0.005 = $0.25).
- For every notice of a period whatever the country, use example 3, "Notices by publication date range". To look at the shape of the output first, use example 5, "Small sample run" (5 results, at most $0.025).

#### Daily feed of new TED notices

A team wants a feed of newly published notices without editing dates by hand. Leave `dateFrom` and `dateTo` empty and set `publishedWithinDays`: at each run the Actor counts back that many days from today's date in UTC. With a schedule on the Apify platform, the same input then searches the most recent days at every run.

- Input to start from: example 6, the input under "Monitor new tenders daily" (buyers in Germany, `publishedWithinDays` 1, at most 100 results x $0.005 = $0.50 per run).
- A notice can be returned by two consecutive daily runs and is charged in each run that returns it. "Monitor new tenders daily" explains why and how to keep one copy.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `countries` | array of strings | all countries | Buyer country. 2-letter codes (`IE`, `FR`, `DE`) for EU and EEA countries, Switzerland and the United Kingdom, or 3-letter ISO codes for any country. |
| `cpvCodes` | array of strings | all categories | CPV codes. A full 8-digit code (`72000000`) matches that code; a prefix of 2 to 7 digits (`72`) matches every code that starts with it. |
| `keyword` | string | none | A word or phrase searched as an exact phrase in the full text of the notice. At most 1000 characters; quotes, brackets and wildcards are removed. |
| `dateFrom` | string, `YYYY-MM-DD` | 7 days ago, when both dates and `publishedWithinDays` are empty | Earliest publication date. |
| `dateTo` | string, `YYYY-MM-DD` | none | Latest publication date. |
| `publishedWithinDays` | integer | none | From 1 to 30. Used only when both dates are empty: searches notices published on or after today's date (UTC) minus this many days. A date above wins. See "Monitor new tenders daily". |
| `onlyOpen` | boolean | `false` | When `true`, delivers only notices whose `tenderDeadline` is a date after the day the run starts (UTC). Notices without a deadline are left out. See "Only tenders still open". |
| `maxResults` | integer | `20` | Stop after this many notices. From 1 to 1000 (hard maximum per run). |

All filters are combined with AND. Several countries, or several CPV codes, are combined with OR inside their own filter. Each of the two lists accepts at most 200 entries.

Invalid input (a 2-letter country code outside the list above, a country written any other way than 2 or 3 letters, a CPV code that is not 2 to 8 digits, a date that is not a real `YYYY-MM-DD` date, `dateFrom` later than `dateTo`, `maxResults` outside 1 to 1000, `publishedWithinDays` that is not a whole number from 1 to 30, `onlyOpen` that is not `true` or `false`, a keyword over 1000 characters) fails the run at once with a message naming the field. No request is sent to TED and nothing is charged. A 3-letter code is passed to TED as written; one that TED does not know matches no notice.

The input form is prefilled with a small search that needs no edits: buyer country `DE`, no dates (so the last 7 days) and 20 results. At the listed price that run charges at most $0.10.

Example input (five more ready-to-run inputs are under "Examples" at the end of this page):

```json
{
    "countries": ["IE"],
    "cpvCodes": ["72"],
    "dateFrom": "2026-09-01",
    "maxResults": 20
}
```

The Actor's default and minimum memory is 256 MB (512 MB at most). It holds one page of at most 250 notices in memory at a time and writes each page to the dataset in one call.

### Output

One dataset item per notice. Fields the notice does not state are `null`.

| Field | Type | Description |
|---|---|---|
| `publicationNumber` | string | TED publication number, for example `188399-2024`. |
| `title` | string or null | Notice title, in English when TED provides it, otherwise the first available language. |
| `noticeType` | string or null | Notice type code as given by TED (for example a contract notice or a contract award notice). |
| `buyerName` | string or null | Official name of the buying organisation. |
| `buyerCountries` | array of strings | Buyer country codes, 3-letter ISO. |
| `cpvCodes` | array of strings | CPV classification codes of the notice. |
| `publicationDate` | string or null | Publication date, `YYYY-MM-DD`. |
| `tenderDeadline` | string or null | Deadline for receipt of tenders, `YYYY-MM-DD`. For notices with several lots this is the first lot's deadline. |
| `estimatedValue` | number or null | Estimated value of the whole procedure, when the notice states one. Many notices do not. |
| `estimatedValueCurrency` | string or null | Currency code of the estimated value. |
| `noticeUrl` | string | Link to the HTML version of the notice on the TED website, in English. |
| `source` | string | The attribution line shown below. |

Illustrative item showing the shape of the output. The publication number, date, country and CPV code are those of public notice 188399-2024; the title wording, buyer name spelling and the notice type code are format examples, not a captured run:

```json
{
    "publicationNumber": "188399-2024",
    "title": "Luxembourg-Luxembourg: Copyright and reproduction rights in the Luxembourg territory",
    "noticeType": "can-standard",
    "buyerName": "European Parliament",
    "buyerCountries": ["LUX"],
    "cpvCodes": ["79120000"],
    "publicationDate": "2024-03-29",
    "tenderDeadline": null,
    "estimatedValue": null,
    "estimatedValueCurrency": null,
    "noticeUrl": "https://ted.europa.eu/en/notice/188399-2024/html",
    "source": "Source: TED (Tenders Electronic Daily), ted.europa.eu. © European Union, 1998-2026. Notices reused under the TED legal notice; fields selected and renamed by this Actor."
}
```

Titles, buyer names and code values are passed through as TED returns them.

### Price

**$0.005 per result** (one result is one notice delivered to the dataset). `result` is the only event this Actor charges; it has no start fee. You are charged only for delivered items: one `result` event per item written to the dataset, and each publication number is delivered at most once per run. A run that finds nothing ends successfully with 0 items and 0 result charges. A run that fails before delivering anything charges nothing for results; a run that fails part-way charges only for the items already delivered. The default run of 20 notices costs $0.10; the hard cap of 1000 notices costs $5.00.

The notices themselves are free to read on the TED website. What you pay for here is the filtering, the pagination and the flat, contact-free output.

### Data source, licence and attribution

- Source: the TED Search API of the Publications Office of the European Union.
- Licence: the TED legal notice states: "Unless otherwise noted, 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." Legal notice: https://ted.europa.eu/legal-notice
- Attribution, also carried in every item's `source` field:

  Source: TED (Tenders Electronic Daily), ted.europa.eu. © European Union, 1998-2026. Notices reused under the TED legal notice; fields selected and renamed by this Actor.

This Actor does not use the TED logo or any European Union emblem. If you republish the data, keep the attribution and say that fields were selected and renamed.

### Coverage, freshness and limits

- Coverage: whatever the TED Search API returns for your filters in its `ACTIVE` scope, the scope used in TED's own examples. TED's documentation does not say what that scope leaves out; if it leaves out notices TED no longer counts as active, old date ranges return fewer notices than were published. TED publishes notices above the EU procurement thresholds from EU and EEA buyers and EU institutions, plus some notices below the thresholds. Tenders that are only published on national portals are not included.
- Freshness: every run queries TED live; nothing is cached. A notice appears here when TED has published it.
- Order: newest publication date first. If the API rejects the request and its message names no optional field, the Actor retries once without the sort clause; if that works, the run continues in the API's own order and logs a warning.
- TED warns that a new Official Journal issue released while a run is paging can make page-by-page results skip or repeat notices. Repeats are removed; a skipped notice is not recovered.
- Maximum 1000 notices per run. For more, split the date range across several runs.
- Fields are limited to the table above. There are no lot details, no award details, no winner names, no document downloads and no full notice text.
- `noticeType`, `tenderDeadline` and the estimated value are optional. If TED does not provide one of them for a notice, the value is `null`. If the API rejects one of these fields and its error message names that field, the run continues without it and the value is `null` for every notice. If the API rejects the request without naming such a field, and also rejects it without the sort clause, the run fails with the API's message.
- Titles are returned in English when available. Some older notices only have a title in the buyer's language.
- TED publishes no request-rate limit for this API, so the Actor limits itself: sequential requests, one second between pages, up to 250 notices per request (TED's documented maximum), and up to three attempts per request when the network fails or the API answers HTTP 429 or a server error, waiting 2 and then 4 seconds between attempts, or the time the API asks for in Retry-After (30 seconds at most). After the third attempt the run fails with a message that names the HTTP status code.
- If TED is down, rejects a query or answers in a format the Actor does not read, the run fails with a message and delivers no further items.

#### Not yet verified

As of 2026-10-05 this version has been compared with TED's published documentation and with public source code on GitHub that calls the same API (the Publications Office's own notice fetcher and one independent command-line client). It has not been run against the live API, so nothing on this page is a measured result. The points below are unverified until the first runs on Apify:

- That the API answers a request without a key in practice. The documentation says "The Search API does not require a key."; no request from this Actor has confirmed it.
- The layout of the API's answer. The names of the list of results and of the total count are the ones the Publications Office's fetcher reads. The shape of each value (titles keyed by language, dates with a time-zone suffix) is taken from the independent client only. The English title, the 3-letter form of `buyerCountries` and the `YYYY-MM-DD` dates depend on it.
- That the API accepts all ten requested field names when returning data. The independent client requests all ten; TED's own list of accepted names was not readable.
- That this Actor's query is accepted as written. Each part of it (the country list, the publication date comparison, the sort by publication date) appears in the public code named above, but no request from this Actor has been sent.
- What the `ACTIVE` scope covers. A second scope, `ALL`, appears in the public code; this Actor does not use it.
- Whether the API's error message names a rejected field, which the fallback for optional fields relies on.
- Any request-rate limit of the Search API, and whether it ever answers HTTP 429.
- The list of `noticeType` codes.
- Run time and memory use. The 256 MB default has not been measured.

If one of the first four points is wrong, the run fails with a message, or the affected fields come back `null`. This section will be replaced with observed behaviour after the first runs.

### Privacy: returns no personal data

This Actor returns no personal data. TED notices can contain contact details of named people; the Actor never asks the API for those fields, and it builds each item from its 12 listed fields only, so they never reach the dataset. Dropped for the buyer, tenderers, winners, review bodies and every other organisation:

- contact point or contact person name, and job title
- e-mail address
- telephone number
- fax number
- street address and postal code
- winner, tenderer and subcontractor names and identifiers
- names of signatories, beneficial owners or any other natural person
- free-text description fields

As a second guard, a script blanks anything in `title` and `buyerName` that matches an e-mail address or phone number pattern and writes `[removed]` in its place. The Actor does not download the notice XML or PDF.

`buyerName` is the official name of a public body or other buying organisation, not of a person.

### Takedown requests and problems

To report a problem or request that something is removed, open an issue in the **Issues** tab of this Actor's page in the Apify Store. That tab is the only contact channel for this Actor.

### How it was built

This Actor, including its code and this README, was built with AI assistance.

### Examples

Five inputs to paste into the JSON tab of the input form. Each uses only input fields listed under "Input". A sixth input, for scheduled runs, is under "Monitor new tenders daily". A seventh, for tenders whose deadline is still ahead, is under "Only tenders still open".

**None of these examples has been run.** They were checked by reading only: each input against the input schema (field names, types, the 1 to 1000 range of `maxResults`), and each query against TED's published search documentation. Nothing was executed and no request was sent to TED, so this section shows no output rows, no result counts and no run times. The query shown under each example is what the Actor's code builds from that input, worked out by reading the code. Everything under "Not yet verified" applies to these examples too.

Notes that hold for all five:

- Every example returns the same 12 output fields, the ones in the "Output" table: `publicationNumber`, `title`, `noticeType`, `buyerName`, `buyerCountries`, `cpvCodes`, `publicationDate`, `tenderDeadline`, `estimatedValue`, `estimatedValueCurrency`, `noticeUrl`, `source`.
- The charge is the number of notices delivered x $0.005. `maxResults` x $0.005 is therefore the most a run can charge; a search that matches fewer notices charges less, and one that matches none charges nothing.
- The dates are fixed days in September 2026. Change them to the period you need. Every example gives both dates, so the query uses the date range form that TED documents.
- The Actor adds ` SORT BY publication-date DESC` to the end of every query. It is left out of the query lines below.

#### 1. Notices by CPV code

For bid teams that follow one category of contract. This one asks for IT services (every code starting with `72`) and software packages (the exact code `48000000`) published in September 2026.

```json
{
    "cpvCodes": ["72", "48000000"],
    "dateFrom": "2026-09-01",
    "dateTo": "2026-09-30",
    "maxResults": 100
}
```

- Query built: `(classification-cpv=72* OR classification-cpv=48000000) AND (publication-date=(20260901 <> 20260930))`
- Output fields: `publicationNumber`, `title`, `noticeType`, `buyerName`, `buyerCountries`, `cpvCodes`, `publicationDate`, `tenderDeadline`, `estimatedValue`, `estimatedValueCurrency`, `noticeUrl`, `source`.
- Charge: at most 100 results x $0.005 = $0.50.

#### 2. Notices by buyer country

For procurement monitoring: a regular check of what public buyers in chosen countries published. This one asks for buyers in Ireland or France over ten days.

```json
{
    "countries": ["IE", "FR"],
    "dateFrom": "2026-09-21",
    "dateTo": "2026-09-30",
    "maxResults": 50
}
```

- Query built: `(buyer-country IN (IRL FRA)) AND (publication-date=(20260921 <> 20260930))`
- Output fields: `publicationNumber`, `title`, `noticeType`, `buyerName`, `buyerCountries`, `cpvCodes`, `publicationDate`, `tenderDeadline`, `estimatedValue`, `estimatedValueCurrency`, `noticeUrl`, `source`.
- Charge: at most 50 results x $0.005 = $0.25.
- TED's documentation lists the `buyer-country` search field and shows 3-letter country codes on another country field. An official example query that uses `buyer-country` itself was not found.

#### 3. Notices by publication date range

For market researchers who want every notice of a period, whatever the country or category. This one asks for three days with no other filter.

```json
{
    "dateFrom": "2026-09-28",
    "dateTo": "2026-09-30",
    "maxResults": 500
}
```

- Query built: `(publication-date=(20260928 <> 20260930))`
- Output fields: `publicationNumber`, `title`, `noticeType`, `buyerName`, `buyerCountries`, `cpvCodes`, `publicationDate`, `tenderDeadline`, `estimatedValue`, `estimatedValueCurrency`, `noticeUrl`, `source`.
- Charge: at most 500 results x $0.005 = $2.50.
- A run stops at `maxResults`, newest first. If the period holds more notices than that, the older ones are not delivered: use a shorter period per run, or raise `maxResults` up to 1000 (at most 1000 x $0.005 = $5.00).

#### 4. Notices by keyword

For bid teams and researchers looking for a subject that no single CPV code covers. This one searches the phrase "road maintenance" in notices published in September 2026.

```json
{
    "keyword": "road maintenance",
    "dateFrom": "2026-09-01",
    "dateTo": "2026-09-30",
    "maxResults": 200
}
```

- Query built: `(publication-date=(20260901 <> 20260930)) AND (FT~"road maintenance")`
- Output fields: `publicationNumber`, `title`, `noticeType`, `buyerName`, `buyerCountries`, `cpvCodes`, `publicationDate`, `tenderDeadline`, `estimatedValue`, `estimatedValueCurrency`, `noticeUrl`, `source`.
- Charge: at most 200 results x $0.005 = $1.00.
- The keyword is sent as an exact phrase, as you typed it. The Actor does not translate it and adds no wildcards.

#### 5. Small sample run

For anyone who wants to see the shape of the output before a larger run. Five notices from buyers in Germany over one week.

```json
{
    "countries": ["DE"],
    "dateFrom": "2026-09-24",
    "dateTo": "2026-09-30",
    "maxResults": 5
}
```

- Query built: `(buyer-country IN (DEU)) AND (publication-date=(20260924 <> 20260930))`
- Output fields: `publicationNumber`, `title`, `noticeType`, `buyerName`, `buyerCountries`, `cpvCodes`, `publicationDate`, `tenderDeadline`, `estimatedValue`, `estimatedValueCurrency`, `noticeUrl`, `source`.
- Charge: at most 5 results x $0.005 = $0.025.

### How to use

1. Open this Actor in Apify Console and go to its input form.
2. Keep the prefilled search (buyer country `DE`, the last 7 days, 20 results) or set your own filters: buyer countries, CPV codes, keyword, publication dates. Every filter is optional.
3. Set "Maximum results". It is also the cost ceiling of the run: the number you enter x $0.005.
4. Start the run.
5. When the run has finished, open its dataset. Each row is one notice with the 12 fields listed under "Output". Apify lets you view the dataset as a table and export it in formats such as JSON, CSV and Excel.

The same input can be sent through the Apify API or saved as a task and scheduled. Those are features of the Apify platform, not of this Actor.

### Monitor new tenders daily

A fixed `dateFrom` goes stale in a scheduled run. Use `publishedWithinDays` instead and leave `dateFrom` and `dateTo` empty: at each run the Actor works out today's date in UTC, goes back that many days and searches notices published on or after that date.

```json
{
    "countries": ["DE"],
    "publishedWithinDays": 1,
    "maxResults": 100
}
```

- Query built on a run made on 2026-10-05 (UTC): `(buyer-country IN (DEU)) AND (publication-date>=20261004)`, followed by the sort clause. The offline fixtures check builds this query with a fixed clock; it was not sent to TED.
- `publishedWithinDays` is a whole number from 1 to 30. Any other value fails the run before a request is sent, and nothing is charged.
- If `dateFrom` or `dateTo` is set, that date is used and `publishedWithinDays` has no effect on the query (it is still checked).
- Add `cpvCodes` or `keyword` to narrow the search; they combine with the date as in any other run.

To schedule it:

1. In Apify Console, open **Schedules** and create a schedule.
2. Set how often it runs, for example the cron expression `0 9 * * *` for once a day at 09:00, and pick the time zone.
3. Add this Actor to the schedule and paste the input above, or save the input as a task first and add the task.
4. Save and enable the schedule. Each run writes its own dataset.

Schedules are a feature of the Apify platform, not of this Actor; the steps are as Apify's documentation describes them and were not run for this page.

What a daily run costs and returns:

- Each returned notice is charged as one `result` at $0.005, as in any other run. There is no start fee and no charge for the schedule from this Actor. With `maxResults` 100 a run charges at most 100 x $0.005 = $0.50; a day with no matching notice charges nothing.
- The window counts whole calendar days in UTC and includes today. With `publishedWithinDays` 1 a run covers yesterday and today, so a notice published today can be returned again by tomorrow's run and is charged in each run that returns it. The Actor keeps nothing between runs: it removes repeats inside one run only. To keep one copy, drop rows whose `publicationNumber` you already have.
- A run stops at `maxResults`, newest first. If more notices match than that, the older ones in the window are not delivered: raise `maxResults` (up to 1000) or narrow the filters.
- If a run is skipped or fails, set a larger `publishedWithinDays` for the next run to cover the gap, up to 30 days.

Everything under "Not yet verified" applies to scheduled runs too.

### Only tenders still open

Not every TED notice is a call you can still answer: some notices state no deadline for tenders (for those `tenderDeadline` is `null`), and others have a deadline that has passed. Set `onlyOpen` to `true` to get only the notices whose `tenderDeadline` is still ahead. It is off by default, and a run without it behaves exactly as before.

```json
{
    "countries": ["DE"],
    "publishedWithinDays": 7,
    "onlyOpen": true,
    "maxResults": 20
}
```

What it does:

- The search sent to TED is the same as without `onlyOpen`: same query, same ten requested fields. For this input on a run made on 2026-10-05 (UTC) the query is `(buyer-country IN (DEU)) AND (publication-date>=20260928)`, followed by the sort clause. The Actor then looks at the `tenderDeadline` of each notice TED returns and delivers the notice only when that date is later than the day the run starts, in UTC.
- Notices without a deadline are left out: a notice whose `tenderDeadline` would be `null`, or is not a real date, is never delivered by a run with `onlyOpen`.
- The output keeps the day of the deadline and not its hour, so a notice whose deadline is the day of the run is left out too.
- For a notice with several lots, the deadline checked is the first lot's, the same value the `tenderDeadline` field shows. A notice whose first lot has closed is left out even if another lot is still open.
- `onlyOpen` combines with every other input: countries, CPV codes, keyword, dates and `publishedWithinDays`. It works in a scheduled run as in any other.

What it costs:

- The price is still $0.005 per result emitted. One `result` is charged for each notice written to the dataset; a notice that was read and left out is not written and not charged. `maxResults` counts delivered notices, so `maxResults` x $0.005 remains the most a run can charge: at most 20 x $0.005 = $0.10 for the input above.
- A filtered run may scan more pages than it returns. It asks TED for pages of 250 notices and keeps reading until `maxResults` open notices are delivered, the results end, or 10 pages (2,500 notices) have been read, whichever comes first. So it can take longer than a run without the filter, and it can end with fewer notices than `maxResults`, or with none, when few of the notices it read are still open. Narrow the filters or shorten the date window if that happens.
- The run log ends with one line that states how many notices were scanned, how many pages were read and how many notices were emitted, and says so when the run stopped at the 10-page limit.

Limits:

- If TED rejects the deadline field (see the note on optional fields under "Coverage, freshness and limits"), a run with `onlyOpen` fails with a message before delivering anything, and nothing is charged. Run it again without `onlyOpen`.
- The filter tells you the first lot's deadline date is ahead. It does not tell you that the procedure was not cancelled or changed after the notice was published; read the notice on the TED website before relying on it.
- The filter is covered by the offline fixtures check, with a fixed clock and written test notices. No run with `onlyOpen` has been made against TED, and everything under "Not yet verified" applies here too.

### Run it from the API or on a schedule

Everything in this section is a standard feature of the Apify platform, as described in Apify's documentation. None of it is specific to this Actor, and none of it was run for this page. The Actor's price does not change with the way a run is started: $0.005 per result, and nothing else from this Actor.

#### Run the EU tenders search through the Apify API

- Apify's API has a "Run Actor" endpoint that starts a run and returns at once, without waiting for the run to finish. The body of the POST request is passed to the Actor as its input, so you send the same JSON you would paste into the input form, for example any input under "Examples".
- The answer to that request names the run's default dataset. When the run has finished, read the notices from that dataset with the "Get dataset items" endpoint.
- A second endpoint runs the Actor and returns the dataset items in the same HTTP response. Apify documents a limit for it: a run that takes longer than 300 seconds is answered with HTTP 408. The run time of this Actor has not been measured, so use the first endpoint for anything but a small search.
- API requests are made with the API token of your own Apify account. This Actor needs no key of its own and none for TED.

#### Schedule a run

- Apify Schedules start Actors and tasks at set times. The times are written as a cron expression, and a schedule has a time zone setting.
- When you add an Actor to a schedule you can give it its input. You can also save an input as an Actor task, which is a reusable configuration of an Actor, and schedule the task.
- For a recurring search use `publishedWithinDays` and no fixed dates. The input and the steps are under "Monitor new tenders daily".

#### Export the dataset to CSV, JSON or Excel

- Each run writes its notices to its own dataset. Apify lets you export a dataset as JSON, CSV, XML, Excel, HTML table, RSS or JSONL. The "Get dataset items" endpoint takes a `format` parameter for the same formats.
- Every row has the same 12 fields, listed under "Output". Two of them, `buyerCountries` and `cpvCodes`, are lists; how a list is laid out in a CSV or Excel file is decided by Apify's export, not by this Actor.
- Apify's documentation says that unnamed datasets expire after 7 days unless otherwise specified. Export what you need to keep, or check the retention that applies to your account.

### FAQ

#### Is this an official EU or TED service?

No. This Actor is unofficial and is not affiliated with or endorsed by the Publications Office of the European Union. It reads the public TED Search API and keeps the attribution shown under "Data source, licence and attribution".

#### How much does a run cost?

$0.005 for each notice delivered, and nothing else from this Actor: no start fee and no other event. A run of 20 notices costs at most $0.10; the largest possible run, 1000 notices, costs at most $5.00. A run that delivers nothing charges nothing for results.

#### Does it return e-mail addresses, phone numbers or contact persons?

No. The Actor never asks TED for those fields and returns only the 12 fields listed under "Output". See "Privacy" for the full list of what is left out.

#### Why did I get fewer notices than I expected, or none?

All filters are combined with AND, so each one you add narrows the search. With both dates empty only the last 7 days are searched, or the number of days set in `publishedWithinDays`. The keyword is matched as an exact phrase. A 3-letter country code that TED does not know matches nothing. Notices published only on national portals are not in TED. A run with no matches ends successfully with 0 items.

#### Can I get more than 1000 notices?

Not in one run. Split the publication date range across several runs, each with up to 1000 results.

#### Has this Actor been tested against the live TED API?

Not yet. As of 2026-10-05 it has been compared with TED's documentation and with public code that calls the same API, and it has not been run. "Not yet verified" lists what is still open.

#### How do I report a problem or ask for something to be removed?

Open an issue in the **Issues** tab of this Actor's page in the Apify Store. That tab is the only contact channel for this Actor.

#### What is TED?

TED (Tenders Electronic Daily) is the online Supplement to the Official Journal of the European Union, where public procurement notices are published. Its publisher is the Publications Office of the European Union. This Actor reads TED's public Search API; it is not part of TED.

#### Which EU tenders are covered, and how fresh is the data?

- Coverage: what the TED Search API returns for your filters in its `ACTIVE` scope. TED publishes notices above the EU procurement thresholds from EU and EEA buyers and EU institutions, plus some notices below the thresholds. Tenders published only on national portals are not included. TED's documentation does not say what the `ACTIVE` scope leaves out.
- Freshness: every run queries TED live and nothing is cached, so a notice appears here when TED has published it.
- Limits: at most 1000 notices per run, and the 12 fields under "Output" only: no lot details, no award details, no winner names, no document downloads and no full notice text.

"Coverage, freshness and limits" has the full list.

#### Can I search TED notices by CPV code, country and date at the same time?

Yes. `cpvCodes`, `countries`, `keyword` and the publication dates are combined with AND; several CPV codes, or several countries, are combined with OR inside their own filter. See "Use cases for EU tenders and TED notices" for inputs to start from.

#### Can I run it from the API, on a schedule, or export to CSV or Excel?

Yes, with standard features of the Apify platform, not of this Actor. See "Run it from the API or on a schedule".

### Use from AI agents (MCP)

An AI agent connected to the Apify MCP server can run this Actor as a tool. The steps below are as Apify's documentation describes that server. None of them was run for this page, and no run of this Actor through the MCP server has been made. Everything under "Not yet verified" applies here too.

How an agent calls it:

1. Call the tool `call-actor` with the Actor name `autoaugeo/eu-tenders-ted-notices-b455` and one of the inputs below. To read the input schema, this README and the price first, call the tool `fetch-actor-details` with the same name.
2. `call-actor` answers with the status of the run and its storage IDs, not with the notices. Read the notices with the tool `get-dataset-items` and the `datasetId` of the run.
3. Each item has the 12 fields listed under "Output".

Three requests in plain language, each with the input it maps to.

Request A: "Find tenders from buyers in Germany that were published in the last 7 days and are still open." This is example 7, the input under "Only tenders still open":

```json
{
    "countries": ["DE"],
    "publishedWithinDays": 7,
    "onlyOpen": true,
    "maxResults": 20
}
```

Request B: "List IT services and software notices published in September 2026." This is example 1, "Notices by CPV code":

```json
{
    "cpvCodes": ["72", "48000000"],
    "dateFrom": "2026-09-01",
    "dateTo": "2026-09-30",
    "maxResults": 100
}
```

Request C: "Find notices that mention road maintenance, published in September 2026." This is example 4, "Notices by keyword":

```json
{
    "keyword": "road maintenance",
    "dateFrom": "2026-09-01",
    "dateTo": "2026-09-30",
    "maxResults": 200
}
```

Price and spend limit for an agent:

- The price is $0.005 per result with no start fee, whichever way the run is started. One result is one notice delivered to the dataset.
- Set `maxResults` in the input of every call. A run delivers no more than that many notices, so it charges no more than `maxResults` x $0.005. When the field is left out the default is 20, and the hard limit is 1000 per run.
- Apify's documentation says that `call-actor` takes run limits, `maxItems` and `maxTotalChargeUsd` among them, in `callOptions` and not in the Actor input. Set `maxItems` there to the same number as `maxResults`, so that the agent's spend is bounded in both places.
- The Actor is built to stop when the charge limit of a run is reached. No run with `maxItems` has been made, so `maxResults` is the limit to rely on.
- With `onlyOpen` a run can end with fewer notices than `maxResults`, or with none. Only delivered notices are charged.

# Actor input Schema

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

Accepts a list of buyer country codes, 2-letter for EU and EEA countries, Switzerland and the United Kingdom or 3-letter ISO for any country, for example \["DE"]; default: empty, which searches all countries.

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

Accepts a list of Common Procurement Vocabulary (CPV) codes of 2 to 8 digits each, where 8 digits match that code and a shorter prefix matches every code starting with it, for example \["72"]; default: empty, which searches all categories.

## `keyword` (type: `string`):

Accepts one word or phrase of up to 1000 characters, searched as an exact phrase in the full text of the notice after quotes, brackets and wildcards are removed, for example road maintenance; default: empty, which applies no keyword filter.

## `dateFrom` (type: `string`):

Accepts the earliest publication date as YYYY-MM-DD, for example 2026-09-01; default: empty, which searches the last 7 days when dateTo is empty too, or the number of days set in publishedWithinDays.

## `dateTo` (type: `string`):

Accepts the latest publication date as YYYY-MM-DD, for example 2026-09-30; default: empty, which sets no upper limit.

## `publishedWithinDays` (type: `integer`):

Accepts a whole number from 1 to 30 and searches notices published on or after today's date (UTC) minus that many days, used only when dateFrom and dateTo are both empty, for example 1 for yesterday and today; default: empty, which searches the last 7 days.

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

Accepts true or false, where true delivers only notices whose tender deadline is a date after the day the run starts (UTC), leaves out notices without a deadline and reads no more than 10 pages of 250 notices, for example true; default: false.

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

Accepts a whole number from 1 to 1000, the number of delivered notices after which the run stops, each delivered notice being one charged result, for example 20; default: 20.

## Actor input object example

```json
{
  "countries": [
    "DE"
  ],
  "onlyOpen": false,
  "maxResults": 20
}
```

# Actor output Schema

## `results` (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 = {
    "countries": [
        "DE"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("autoaugeo/eu-tenders-ted-notices-b455").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 = {
    "countries": ["DE"],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("autoaugeo/eu-tenders-ted-notices-b455").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 '{
  "countries": [
    "DE"
  ],
  "maxResults": 20
}' |
apify call autoaugeo/eu-tenders-ted-notices-b455 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,autoaugeo/eu-tenders-ted-notices-b455"
        }
    }
}
```

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/aaqXjce5lIUmiJC6g/builds/cG1EFaWVn5fGiLrbv/openapi.json
