# EU Tender Scraper - Public Procurement & TED Leads (`arvin-data/eu-tender-radar`) Actor

Clean EU public procurement leads from the official TED database. One flat row per tender, one language instead of 24, real deadlines, plain-language industry categories.

- **URL**: https://apify.com/arvin-data/eu-tender-radar.md
- **Developed by:** [Mike Ulre](https://apify.com/arvin-data) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 Radar — Public Procurement Leads

Find the public contracts you can actually bid on, across all 27 EU member states plus the EEA.

**🌐 Live examples and full overview: [tender.arvin.world](https://tender.arvin.world)**

Every day, European public authorities publish thousands of tenders to **TED** (Tenders Electronic Daily), the official EU procurement journal. The data is public — but it is not usable. Every title arrives in 24 languages at once, categories are bare numeric codes, and the majority of notices are for deadlines that have already passed. This Actor turns that into a clean lead list.

### What you get

One flat row per tender, in the language you choose:

| Field | Description |
|---|---|
| `title`, `description` | Single language, not a 24-language blob |
| `buyer`, `country`, `country_name` | Who is buying, and where |
| `deadline`, `days_until_deadline` | Real, computed urgency |
| `is_open_opportunity` | Whether you can still bid at all |
| `category_en` / `category_de` | Plain-language industry, not a raw CPV number |
| `cpv_codes`, `cpv_primary` | The CPV matching *your* filter, not an arbitrary side code |
| `value_eur` | Contract value where the authority published one |
| `winner` | On award notices: who won — useful for competitor research |
| `url`, `pdf_url` | Straight to the official notice |

### Why not just use the TED website

Three things this Actor does that the raw source does not:

1. **Deadline reality.** Filtering by publication date returns mostly expired tenders. Setting *minimum days left* gives you only contracts you still have time to respond to.
2. **The right category.** A single tender often carries five CPV codes. If you sell IT and the notice is tagged both `72` (IT services) and `79` (business consultancy), you want to see "IT services" — this Actor picks the code that matches your filter.
3. **One language.** Pick English, German, French, Spanish, Italian, Dutch, Polish or Portuguese. Missing fields fall back to English rather than coming back empty.

### Typical uses

- **Weekly lead alerts** — schedule it for every Monday with a 7-day look-back and push straight to your CRM, a Google Sheet or Slack.
- **Market sizing** — switch off *only open opportunities* to include award notices and see what a sector actually spends, and who wins.
- **Competitor tracking** — award notices carry the winning supplier's name.

### Example input

```json
{
  "cpv": ["72", "48"],
  "countries": ["DE", "AT", "NL"],
  "minDaysLeft": 14,
  "publishedSinceDays": 30,
  "language": "eng",
  "maxResults": 200
}
````

Software and IT-services tenders from Germany, Austria and the Netherlands, published in the last 30 days, with at least two weeks left to prepare a bid.

### Tips

- **Use two-digit CPV prefixes.** `72` covers all IT services; `72100000` matches one narrow sub-category and will return very little.
- **Most notices publish no contract value.** That is normal in EU procurement. A minimum-value filter therefore keeps value-less notices unless you explicitly discard them.
- **Nothing returned?** Widen the look-back window, lower *minimum days left*, or shorten your CPV codes.

### Data source and licence

Data comes from [TED](https://ted.europa.eu), published by the Publications Office of the European Union. Reuse — including commercial reuse — is permitted under [Commission Decision 2011/833/EU](https://eur-lex.europa.eu/eli/dec/2011/833/oj) and CC BY 4.0. Every record carries the required attribution in its `attribution` field. This Actor uses the official public TED Search API; it does not scrape or circumvent anything.

This Actor is not affiliated with or endorsed by the European Union.

# Actor input Schema

## `cpv` (type: `array`):

CPV codes or prefixes describing what you sell. Two digits is usually right: 72 = IT services, 48 = software, 45 = construction, 71 = engineering, 33 = medical, 79 = business services, 85 = health & social. Leave empty to receive every sector.

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

Two-letter country codes of the contracting authorities, e.g. DE, AT, NL. Leave empty for all EU/EEA countries.

## `keywords` (type: `string`):

Optional free-text term that must appear in the notice title, e.g. "cloud" or "Softwareentwicklung".

## `publishedSinceDays` (type: `integer`):

How far back to look. 30 days suits a monthly sweep, 7 days a weekly alert.

## `minDaysLeft` (type: `integer`):

Drops tenders whose deadline is too close to respond to. Set 0 to keep everything still open, 7 to only see what you realistically have time for.

## `onlyOpenOpportunities` (type: `boolean`):

On: contract and prior information notices only. Off: also includes award notices — useful for competitor and pricing research.

## `minValueEur` (type: `integer`):

Filters out small contracts. Note that many notices publish no value at all; those are kept unless you enable the option below.

## `requireValue` (type: `boolean`):

Only relevant together with a minimum value. Most notices omit the value, so switching this on shrinks results considerably.

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

Language for titles, descriptions and category labels. TED publishes in 24 languages; missing fields fall back to English.

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

Upper bound on the number of tenders returned.

## Actor input object example

```json
{
  "cpv": [
    "72",
    "48"
  ],
  "countries": [
    "DE",
    "AT"
  ],
  "keywords": "",
  "publishedSinceDays": 30,
  "minDaysLeft": 7,
  "onlyOpenOpportunities": true,
  "minValueEur": 0,
  "requireValue": false,
  "language": "eng",
  "maxResults": 100
}
```

# 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 = {
    "cpv": [
        "72",
        "48"
    ],
    "countries": [
        "DE",
        "AT"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arvin-data/eu-tender-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 = {
    "cpv": [
        "72",
        "48",
    ],
    "countries": [
        "DE",
        "AT",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("arvin-data/eu-tender-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 '{
  "cpv": [
    "72",
    "48"
  ],
  "countries": [
    "DE",
    "AT"
  ]
}' |
apify call arvin-data/eu-tender-radar --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "EU Tender Scraper - Public Procurement & TED Leads",
        "description": "Clean EU public procurement leads from the official TED database. One flat row per tender, one language instead of 24, real deadlines, plain-language industry categories.",
        "version": "0.1",
        "x-build-id": "BZwsGlYKt33DaXm2D"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/arvin-data~eu-tender-radar/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-arvin-data-eu-tender-radar",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/arvin-data~eu-tender-radar/runs": {
            "post": {
                "operationId": "runs-sync-arvin-data-eu-tender-radar",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/arvin-data~eu-tender-radar/run-sync": {
            "post": {
                "operationId": "run-sync-arvin-data-eu-tender-radar",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "cpv": {
                        "title": "Industry (CPV codes)",
                        "type": "array",
                        "description": "CPV codes or prefixes describing what you sell. Two digits is usually right: 72 = IT services, 48 = software, 45 = construction, 71 = engineering, 33 = medical, 79 = business services, 85 = health & social. Leave empty to receive every sector.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "Buyer countries",
                        "type": "array",
                        "description": "Two-letter country codes of the contracting authorities, e.g. DE, AT, NL. Leave empty for all EU/EEA countries.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Title keyword",
                        "type": "string",
                        "description": "Optional free-text term that must appear in the notice title, e.g. \"cloud\" or \"Softwareentwicklung\".",
                        "default": ""
                    },
                    "publishedSinceDays": {
                        "title": "Published within the last … days",
                        "minimum": 1,
                        "maximum": 365,
                        "type": "integer",
                        "description": "How far back to look. 30 days suits a monthly sweep, 7 days a weekly alert.",
                        "default": 30
                    },
                    "minDaysLeft": {
                        "title": "Minimum days left to bid",
                        "minimum": 0,
                        "maximum": 180,
                        "type": "integer",
                        "description": "Drops tenders whose deadline is too close to respond to. Set 0 to keep everything still open, 7 to only see what you realistically have time for.",
                        "default": 7
                    },
                    "onlyOpenOpportunities": {
                        "title": "Only tenders you can still bid on",
                        "type": "boolean",
                        "description": "On: contract and prior information notices only. Off: also includes award notices — useful for competitor and pricing research.",
                        "default": true
                    },
                    "minValueEur": {
                        "title": "Minimum contract value (EUR)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Filters out small contracts. Note that many notices publish no value at all; those are kept unless you enable the option below.",
                        "default": 0
                    },
                    "requireValue": {
                        "title": "Discard notices without a published value",
                        "type": "boolean",
                        "description": "Only relevant together with a minimum value. Most notices omit the value, so switching this on shrinks results considerably.",
                        "default": false
                    },
                    "language": {
                        "title": "Output language",
                        "enum": [
                            "eng",
                            "deu",
                            "fra",
                            "spa",
                            "ita",
                            "nld",
                            "pol",
                            "por"
                        ],
                        "type": "string",
                        "description": "Language for titles, descriptions and category labels. TED publishes in 24 languages; missing fields fall back to English.",
                        "default": "eng"
                    },
                    "maxResults": {
                        "title": "Maximum results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Upper bound on the number of tenders returned.",
                        "default": 100
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
