# EU Tenders API — TED Procurement Deadlines (`ikoles/eu-ted-tender-deadline-radar`) Actor

Search active EU public procurement notices from the official TED API. Filter tenders by keyword, buyer country, CPV code, publication date, submission deadline, and minimum value. Export clean JSON/CSV rows for bid pipelines, sales teams, alerts, dashboards, and AI agents.

- **URL**: https://apify.com/ikoles/eu-ted-tender-deadline-radar.md
- **Developed by:** [Ilya Kalesnichenka](https://apify.com/ikoles) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 tender results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## EU Tender Shortlist — TED Opportunity Ranking

Turn the official TED procurement feed into a ranked sales shortlist. Filter active European tenders by keyword, country, CPV code, publication date, minimum value, and submission deadline; every result receives an explainable `fitScore`, concrete `fitReasons`, and actionable `riskFlags` before export to JSON or CSV.

### Agent Utility Shop

This repository also powers **Agent Utility Shop**, a public pay-per-call API catalogue for autonomous agents. Discovery requires no account or API key; paid routes use x402 with USDC on Base Mainnet.

- Catalogue: `https://api.ikoles.dev/catalog.json`
- Agent manifest: `https://api.ikoles.dev/.well-known/agent.json`
- OpenAPI: `https://api.ikoles.dev/openapi.json`

| Service | Route | Price | Delivery |
| --- | --- | ---: | --- |
| TenderSignal | `POST /v1/tender-shortlist` | $0.15 | synchronous |
| CSV/JSON Cleanup and QA | `POST /v1/csv-cleanup` | $2.00 | synchronous |
| Deterministic JSON Diff | `POST /v1/json-diff` | $0.01 | synchronous |
| Deterministic OpenAPI Contract Audit | `POST /v1/openapi-audit` | $0.05 | synchronous |
| Engineering Unit Conversion | `POST /v1/unit-convert` | $0.01 | synchronous |
| Humanoid Robot FMEA Query | `POST /v1/humanoid-fmea-query` | $0.05 | synchronous |
| ClinicalTrials Results Query | `POST /v1/clinical-trials-query` | $0.05 | synchronous |
| Evidence-backed Research Brief | `POST /v1/research-brief` | $5.00 | asynchronous |
| CSV/JSON Quality Toolkit | `GET /v1/products/csv-json-quality-toolkit` | $9.00 | ZIP download |
| Codex Safe Paid Work Kit | `GET /v1/products/codex-safe-paid-work-kit` | $15.00 | ZIP download |
| Automation Data Toolkit Bundle | `GET /v1/products/automation-data-toolkit-bundle` | $24.00 | ZIP download |
| Engineering Unit Conversion API | `GET /v1/products/engineering-unit-conversion-api` | $19.00 | ZIP download |
| Clinical Trial Outcomes — Post-2020 Snapshot | `GET /v1/products/clinical-trials-outcomes-post-2020` | $99.00 | ZIP download |

The research endpoint returns `202 Accepted` with an opaque `statusUrl`. An isolated Codex CLI worker processes the queue every minute and writes either a structured sourced result or a sanitized failure state. The availability gate runs before payment, so a disabled queue cannot charge a customer.

The engineering converter supports 92 canonical units and 496 directed compatible pairs across length, force and torque, pressure, temperature, electrical, flow, thermal, and mass and density domains. `GET /v1/unit-catalog` exposes the supported units for free; incompatible physical quantities are rejected.

The OpenAPI audit accepts one inline OpenAPI 3.0 or 3.1 JSON contract. It inventories paths, operations, schemas, methods, security schemes, servers, and tags; reports duplicate operation IDs, incomplete responses and path parameters, undefined security schemes, and unresolved local references; and returns a bounded machine-readable score. External references are reported but never fetched.

The Humanoid Robot FMEA Query filters 96 source-traceable evidence and preliminary design-review records by free text, layer, priority, evidence type, or minimum RPN. Each response returns at most 20 records with source URLs and controls under `CC BY 4.0`. The material supports research and design review; it is not certification, field reliability evidence, or professional safety approval. If the validated release is unavailable, the route returns `503` before payment.

The ClinicalTrials Results Query filters 38,638 trial-level summaries from a validated ClinicalTrials.gov results snapshot by free text, status, phase, condition, intervention, and results-posting date. It returns at most 20 canonical registry links and endpoint summaries, without exposing the full measurements/analyses bundle. Registry content is not medical advice, evidence grading, or a treatment recommendation. If the compact release is unavailable, the route returns `503` before payment.

The paid Clinical Trial Outcomes snapshot contains 38,638 studies, 326,638 endpoints, 2,602,129 measurements, and 149,059 analyses sourced from the public ClinicalTrials.gov API for studies with posted results from 2020 onward. The ZIP includes normalized CSV and JSONL tables, a data dictionary, provenance, quality checks, and a SHA-256 manifest. Use the $0.05 ClinicalTrials Results Query above as a bounded query preview before purchasing the full $99.00 release. Registry content may be corrected after extraction and is not medical advice, evidence grading, or a treatment recommendation; verify current records at ClinicalTrials.gov.

```bash
curl -i -X POST \
  -H 'content-type: application/json' \
  --data '{"rows":[{"email":" Alice@example.com "},{"email":"alice@example.com"}],"keyColumns":["email"]}' \
  https://api.ikoles.dev/v1/csv-cleanup
```

The unpaid request returns `402 Payment Required` with a machine-readable x402 challenge. An x402 client signs the payment and replays the same request.

```bash
curl -i -X POST \
  -H 'content-type: application/json' \
  --data '{"document":{"openapi":"3.1.0","info":{"title":"Example API","version":"1.0.0"},"servers":[{"url":"https://api.example.com"}],"paths":{"/health":{"get":{"operationId":"getHealth","summary":"Read health","responses":{"200":{"description":"Healthy"}}}}}}}' \
  https://api.ikoles.dev/v1/openapi-audit
```

```bash
curl -i -X POST \
  -H 'content-type: application/json' \
  --data '{"domain":"pressure","from":"bar","to":"psi","value":2.5}' \
  https://api.ikoles.dev/v1/unit-convert
```

```bash
curl -i -X POST \
  -H 'content-type: application/json' \
  --data '{"query":"battery fire","priority":"Critical","minRpn":30,"limit":5}' \
  https://api.ikoles.dev/v1/humanoid-fmea-query
```

```bash
curl -i -X POST \
  -H 'content-type: application/json' \
  --data '{"condition":"Parkinson","overallStatus":"COMPLETED","resultsFirstPostFrom":"2023-01-01","limit":5}' \
  https://api.ikoles.dev/v1/clinical-trials-query
```

```bash
curl -i \
  https://api.ikoles.dev/v1/products/clinical-trials-outcomes-post-2020
```

### Why use this Actor?

- Returns only notices with a tender deadline in the future when the run starts.
- Produces one normalized row per notice, using its nearest eligible tender deadline.
- Ranks by best fit, nearest deadline, or highest published value.
- Explains every score and flags short deadlines or missing estimated values.
- Requires no API key, proxy, or browser.

### Quick start

```json
{
  "keywords": ["software", "server"],
  "countries": ["DEU", "FRA"],
  "cpvCodes": ["72"],
  "minValue": 100000,
  "rankingMode": "bestFit",
  "maxResults": 100
}
```

### Input

All date defaults are calculated from the run start in UTC. Dynamic UTC dates are applied at runtime rather than stored in the input schema.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `keywords` | `string[]` | `[]` | Up to 10 terms. A notice can match any term through TED full-text search. |
| `countries` | `string[]` | `[]` | Up to 30 unique ISO 3166-1 alpha-3 buyer country codes, such as `DEU`, `FRA`, or `POL`. |
| `cpvCodes` | `string[]` | `[]` | Up to 20 unique CPV codes or prefixes, each containing 2–8 digits. |
| `publishedAfter` | `string` | UTC date 30 days before run start | Inclusive earliest publication date in `YYYY-MM-DD` format. |
| `publishedBefore` | `string` | Not set | Inclusive latest publication date in `YYYY-MM-DD` format. |
| `deadlineAfter` | `string` | UTC date of run start | Inclusive earliest tender deadline date in `YYYY-MM-DD` format. |
| `deadlineBefore` | `string` | Not set | Inclusive latest tender deadline date in `YYYY-MM-DD` format. |
| `minValue` | `number` | Not set | Nonnegative minimum procedure-level estimated value in each notice's native/source currency, with no currency conversion. Cross-currency values are not economically normalized; combine this filter with a narrow country or use case, or inspect the output `currency`. Notices without a numeric value are excluded when this is greater than zero. |
| `rankingMode` | `bestFit \| deadlineSoonest \| highestValue` | `bestFit` | Sort the shortlist by explainable fit, the nearest eligible deadline, or the highest published estimated value. Unknown values sort last in `highestValue` mode. |
| `maxResults` | `integer` | `100` | Maximum number of eligible rows to collect, from 1 to 5,000. A run charge budget can reduce the number actually written. |

### Output

Each default-dataset item follows the `TenderRow` contract. The values in this example are illustrative and do not identify a verified procurement notice:

```json
{
  "noticeId": "412345-2026",
  "title": "Framework agreement for software development and support services",
  "buyerName": "Illustrative City Digital Services Agency",
  "buyerCountryCodes": ["DEU"],
  "cpvCodes": ["72000000", "72200000"],
  "estimatedValue": 2500000,
  "currency": "EUR",
  "publicationDate": "2026-07-10",
  "deadline": "2026-08-31T15:00:00.000Z",
  "daysToDeadline": 47,
  "fitScore": 100,
  "fitReasons": [
    "Keyword match: software",
    "Buyer country match: DEU",
    "CPV match: 72",
    "Estimated value meets minimum: 2500000",
    "Deadline is active: 47 days remaining"
  ],
  "riskFlags": [],
  "sourceUrl": "https://ted.europa.eu/en/notice/412345-2026/html"
}
```

### Pricing

$0.004 per item written to the default dataset. Empty results and notices filtered out before the final dataset write do not create dataset-item events.

A run-level `maxTotalChargeUsd` can cap the rows written below `maxResults`. The final status reports the actual submitted count and, when budget-limited, the eligible count as well.

Need a done-for-you shortlist? See the [EU Tender Shortlist service](https://api.ikoles.dev/services/eu-tender-shortlist) for a custom, ranked delivery.

### Data source and limitations

This Actor queries the official TED Search API. Procedure-level estimated value can be absent from a notice, so `estimatedValue` and `currency` can be `null`. The deterministic fit score uses the requested keyword, country, CPV, minimum-value, and deadline evidence; it is a prioritization aid, not an eligibility decision. Keyword matching uses TED full-text search and is not semantic matching. Verify the source notice for the complete procurement record and current requirements.

### Disclaimer

This independent tool is not affiliated with or endorsed by the European Union or TED. Users are responsible for verifying procurement details on the linked official notice before acting.

# Actor input Schema

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

Find notices matching any of these terms through TED full-text search.

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

ISO 3166-1 alpha-3 buyer country codes, for example DEU, FRA, or POL.

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

Two- to eight-digit CPV codes or prefixes.

## `publishedAfter` (type: `string`):

Earliest publication date, inclusive. Defaults at runtime to 30 UTC calendar days before the run starts.

## `publishedBefore` (type: `string`):

Latest publication date, inclusive. No runtime default.

## `deadlineAfter` (type: `string`):

Earliest tender deadline date, inclusive. Defaults at runtime to the UTC calendar date when the run starts.

## `deadlineBefore` (type: `string`):

Latest tender deadline date, inclusive. No runtime default.

## `minValue` (type: `number`):

Minimum procedure-level estimated value in each notice's native/source currency, with no currency conversion. Notices without a numeric value are excluded when this is greater than zero.

## `rankingMode` (type: `string`):

Order opportunities by explainable fit score, nearest deadline, or highest published estimated value.

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

Maximum number of normalized notices written to the default dataset.

## Actor input object example

```json
{
  "keywords": [],
  "countries": [],
  "cpvCodes": [],
  "rankingMode": "bestFit",
  "maxResults": 100
}
```

# Actor output Schema

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

Items saved to the run's default dataset.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ikoles/eu-ted-tender-deadline-radar").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ikoles/eu-ted-tender-deadline-radar").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call ikoles/eu-ted-tender-deadline-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ikoles/eu-ted-tender-deadline-radar",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/54BqFSG5q4ncv614u/builds/cLqre56MvYSdRtsJO/openapi.json
