# NL & EU Government Tenders Scraper | TenderNed + TED (`codeclouds/nl-eu-tenders-scraper`) Actor

Get fresh NL and EU public procurement notices as structured leads. Filter by CPV code, deadline, value and country. MCP-ready.

- **URL**: https://apify.com/codeclouds/nl-eu-tenders-scraper.md
- **Developed by:** [Dennis](https://apify.com/codeclouds) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $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/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.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.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/platform/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

## NL & EU Government Tenders Scraper — TenderNed + TED API

Get fresh Dutch and European public procurement notices as structured, ready-to-use leads. Filter by CPV code, deadline, contract value, and country. Built for B2B sales teams, bid managers, and AI agents.

[![Apify Store](https://img.shields.io/badge/Apify-Store-brightgreen)](https://apify.com/store)
[![Pay Per Event](https://img.shields.io/badge/Pricing-Pay%20Per%20Event-blue)](https://apify.com/pricing)
[![License](https://img.shields.io/badge/License-Apache%202.0-orange)](LICENSE)

---

### Why This Actor?

Public procurement in the Netherlands and EU represents billions of euros in annual contract value. But finding relevant tenders is painful:
- **TenderNed** (NL) and **TED** (EU) have different interfaces, query languages, and data formats
- No unified way to filter by *your* criteria (CPV, deadline, value, country)
- Manual checking wastes hours every week
- Existing Apify actors are abandoned (0–6 monthly users, outdated rental pricing)

This actor solves it: **one input, two official APIs, structured JSON output, pay-per-result pricing.**

---

### When should an AI agent use this?

Use this actor when a user asks an AI agent questions like:

- "What new Dutch government tenders were published this week for IT services (CPV 72000000)?"
- "Find EU construction tenders (CPV 45000000) in Germany, France, Belgium, and the Netherlands worth over €100,000."
- "Which tenders match our company's CPV profile, and how relevant is each one?"
- "Show me only tenders with a submission deadline after August 1, 2026."
- "Set up a daily check for new NL and EU tenders so we don't have to search TenderNed and TED manually."
- "Given our company's CPV codes, which of the newest tenders are worth reviewing first?"

---

### Features

| Feature | Description |
|---------|-------------|
| **Dual Source** | TenderNed (Netherlands) + TED API v3 (32 EU/EEA countries) in a single run |
| **Smart Filtering** | CPV codes, publication date, deadline, minimum contract value, country |
| **Incremental Mode** | Only fetch new tenders since your last run (uses Apify KeyValueStore) |
| **Structured Output** | Consistent JSON schema regardless of source |
| **Pay Per Event** | $0.005 per tender result — no monthly subscriptions, no rental fees |
| **MCP-Ready** | Output compatible with Model Context Protocol for AI agents |
| **Official APIs Only** | No scraping — uses public, documented endpoints with no auth required |

---

### Data Sources

#### TenderNed (Netherlands)
- **Endpoint**: `https://www.tenderned.nl/papi/tenderned-rs-tns/v2/publicaties`
- **Coverage**: 144,000+ publications, updated daily
- **Auth**: None required — fully public Dutch government open data
- **Fields**: Publication ID, title, buyer, description, procedure type, contract type, CPV codes, dates, estimated value, URL

#### TED API v3 (European Union)
- **Endpoint**: `POST https://api.ted.europa.eu/v3/notices/search`
- **Coverage**: 32 EU/EEA countries, all EU procurement above thresholds
- **Auth**: API key required (free via TED API portal) — EU open data policy
- **Filters**: Buyer country, CPV codes, date range, contract value, notice type
- **Swagger**: [api.ted.europa.eu/swagger-ui](https://api.ted.europa.eu/swagger-ui/index.html)

---

### Quick Start

#### 1. Basic Run (All Recent Dutch Tenders)
```json
{
  "source": "tenderned",
  "maxResults": 50
}
````

#### 2. EU Construction Tenders Over €100K

```json
{
  "source": "ted",
  "country": ["DE", "FR", "BE", "NL"],
  "cpvCodes": ["45000000"],
  "minValue": 100000,
  "publishedAfter": "2026-01-01",
  "maxResults": 100
}
```

#### 3. IT Services NL + EU, Incremental (Daily Schedule)

```json
{
  "source": "both",
  "cpvCodes": ["72000000", "73000000"],
  "deadlineAfter": "2026-07-01",
  "incrementalMode": true,
  "maxResults": 200
}
```

***

### Input Schema

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `source` | `enum` | Yes | `"both"` | `"tenderned"`, `"ted"`, or `"both"` |
| `country` | `string[]` | No | `[]` | ISO 3166-1 alpha-2 codes (TED only). Empty = all countries |
| `cpvCodes` | `string[]` | No | `[]` | CPV codes (e.g., `["45000000", "72000000"]`). Supports 2-8 digit codes |
| `publishedAfter` | `string` | No | `""` | ISO date (YYYY-MM-DD). Only tenders published on/after this date |
| `deadlineAfter` | `string` | No | `""` | ISO date (YYYY-MM-DD). Only tenders with deadline on/after this date |
| `minValue` | `number` | No | `0` | Minimum estimated contract value in EUR. Tenders with a known `estimatedValue` below this are skipped (and not charged for). Tenders where `estimatedValue` is `null` (value not published) are always kept, since it can't be determined whether they meet the threshold |
| `maxResults` | `number` | No | `100` | Maximum results per run (per source) |
| `incrementalMode` | `boolean` | No | `false` | If true, only returns tenders newer than last successful run |
| `bedrijfCpvCodes` | `string[]` | No | `[]` | Your company's own CPV codes/prefixes, e.g. `["45213000", "72000000"]`. When set, each result gets a `relevantieScore` (0/40/70/100) and `relevantieMatchedCpv` showing how closely it matches your profile — no need to know the exact CPV codes to search for in advance. Note: TenderNed results always have `relevantieScore: null` (no CPV data available from that source) |
| `alleenRelevanteTenders` | `boolean` | No | `false` | Combined with `bedrijfCpvCodes`: skip (and don't charge for) results with a `relevantieScore` of 0 |

#### CPV Code Tips

- Use 2-digit codes for broad categories: `45` = Construction, `72` = IT Services
- Use 8-digit codes for precision: `45233200` = Roofing works
- Multiple codes = OR logic (matches any)

***

### Output Format

Each tender is pushed to the default dataset as a JSON object:

```json
{
  "id": "2026-123456",
  "source": "tenderned",
  "title": "Levering kantoorartikelen gemeente Amsterdam",
  "buyer": "Gemeente Amsterdam",
  "description": "De gemeente Amsterdam zoekt een leverancier voor kantoorartikelen...",
  "type": "Overheidsopdracht voor leveringen",
  "procedure": "Openbare procedure",
  "cpvCodes": ["30190000"],
  "publishedDate": "2026-07-01",
  "deadline": "2026-08-15",
  "daysUntilDeadline": 45,
  "estimatedValue": 120000,
  "currency": "EUR",
  "country": "NL",
  "url": "https://www.tenderned.nl/aankondigingen/overzicht/123456",
  "isEuropean": false,
  "documents": [],
  "relevantieScore": null,
  "relevantieMatchedCpv": null
}
```

Note: this particular example is a TenderNed result, which never carries CPV codes from the source API — its `relevantieScore` stays `null` even with `bedrijfCpvCodes` set. For a TED result with `cpvCodes: ["30190000"]`, setting `bedrijfCpvCodes: ["30190000"]` would instead give `"relevantieScore": 100, "relevantieMatchedCpv": ["30190000"]`.

#### Field Reference

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique identifier (source-specific) |
| `source` | string | `"tenderned"` or `"ted"` |
| `title` | string | Tender title / notice title |
| `buyer` | string | Contracting authority name |
| `description` | string | Full description (truncated if very long) |
| `type` | string | Contract type (NL: leveringen/diensten/werken; EU: works/supplies/services) |
| `procedure` | string | Procedure type (open, restricted, negotiated, etc.) |
| `cpvCodes` | string\[] | Array of CPV codes |
| `publishedDate` | string | Publication date (YYYY-MM-DD) |
| `deadline` | string | Submission deadline (YYYY-MM-DD) |
| `daysUntilDeadline` | number | Calendar days from today to deadline |
| `estimatedValue` | number | Estimated contract value in EUR (null if unpublished) |
| `currency` | string | Always `"EUR"` |
| `country` | string | ISO country code of buyer |
| `url` | string | Direct link to tender on source platform |
| `isEuropean` | boolean | True if above EU thresholds / cross-border interest |
| `documents` | array | Placeholder for future document-link enrichment |
| `relevantieScore` | number | null | `null` unless `bedrijfCpvCodes` is set in the input. Otherwise 0/40/70/100 based on CPV overlap with your company profile (100 = exact CPV match, 70 = same CPV group, 40 = same CPV division, 0 = no overlap). Always `null` for TenderNed results (no CPV data from that source) |
| `relevantieMatchedCpv` | string\[] | null | The tender's CPV codes that matched your `bedrijfCpvCodes`, if any. `null` when `relevantieScore` is `null` |

***

### Pricing — Pay Per Event

This actor uses **Pay Per Event (PPE)** — no monthly rental, no subscription.

| Event | Price | When Charged |
|-------|-------|--------------|
| `apify-actor-start` | $0.00005 | Once per run (Apify default, first 5s compute free) |
| `tender-result` | **$0.005** | Per tender returned in the dataset |

#### Cost Examples

| Scenario | Tenders Returned | Est. Cost |
|----------|------------------|-----------|
| Daily NL IT tenders | 15 | $0.075/run → ~$2.25/month |
| Weekly EU construction | 80 | $0.40/run → ~$1.60/month |
| One-time market scan | 500 | $2.50 total |

**Why $0.005?** Comparable actors charge $0.003–$0.005/result. This price covers platform fees, leaves margin, and is far cheaper than building your own integration.

***

### Incremental Mode (Scheduled Runs)

Enable `incrementalMode: true` to only fetch **new tenders since your last successful run**.

- Uses Apify KeyValueStore to persist `lastRunDate` per source
- First run with incremental mode returns all matching tenders (up to `maxResults`)
- Subsequent runs return only tenders with `publishedDate > lastRunDate`
- Ideal for daily/weekly schedules via Apify Scheduler

***

### MCP Integration (AI Agents)

Output is compatible with **Model Context Protocol**. Use the dataset directly as context for:

- Lead qualification agents
- Proposal drafting assistants
- Market analysis workflows

Example MCP server config:

```json
{
  "mcpServers": {
    "tenders": {
      "command": "npx",
      "args": ["-y", "@apify/mcp-server"],
      "env": {
        "APIFY_TOKEN": "your-token",
        "ACTOR_ID": "nl-eu-tenders-scraper",
        "DATASET_ID": "auto"
      }
    }
  }
}
```

***

### Legal & Compliance

| Aspect | Status |
|--------|--------|
| **Data Source** | Official public APIs (TenderNed, TED) — no scraping |
| **Terms of Service** | Both APIs explicitly allow reuse (open data policies) |
| **Personal Data** | Minimal — buyers are legal entities, not individuals |
| **GDPR Risk** | Low — no personal data processing |
| **License** | Apache 2.0 (actor code); data governed by source terms |

**TenderNed**: Publieke overheidsdienst, data expliciet bedoeld voor hergebruik (data.overheid.nl).\
**TED**: EU-instelling, data onder EU open data directive (hergebruik toegestaan).

***

### Roadmap / Upcoming

- \[ ] Document/link enrichment (fetch PDF attachments)
- \[ ] CPV code lookup / human-readable labels
- \[ ] Email/Slack/webhook notifications on new matches
- \[ ] Historical backfill option
- \[ ] Buyer organization enrichment (KvK, VAT, size)

***

### FAQ

**How fresh is the data?**
TenderNed publications update daily. TED notices are fetched live via the official TED API v3 search endpoint at run time, so results reflect whatever is currently published on each source — there is no caching layer beyond the optional `incrementalMode` bookkeeping.

**Which countries/sources are covered?**
Two sources: TenderNed for the Netherlands (144,000+ publications), and TED API v3 for 32 EU/EEA countries. Set `source` to `"tenderned"`, `"ted"`, or `"both"` to control which are queried.

**What does `bedrijfCpvCodes` do?**
It lets you supply your own company's CPV codes/prefixes so each result gets a `relevantieScore` (0/40/70/100) and `relevantieMatchedCpv` showing how closely the tender's CPV codes match your profile, without you needing to know the exact CPV codes to filter on upfront. Note that TenderNed results always have `relevantieScore: null` because that source doesn't expose CPV data.

**Can I skip irrelevant results to save cost?**
Yes — combine `bedrijfCpvCodes` with `alleenRelevanteTenders: true` to skip (and avoid being charged for) results with a `relevantieScore` of 0.

**How is this priced?**
Pay Per Event: $0.00005 once per run for `apify-actor-start`, plus $0.005 per tender returned (`tender-result`). There's no monthly subscription or rental fee.

**Are there rate limits or authentication requirements?**
TenderNed's endpoint requires no authentication and is fully public. TED API v3 requires a free API key from the TED API portal under the EU open data policy. Neither API is scraped — both are official, documented endpoints.

***

### Related Actors

Also by this developer — Dutch/EU public-data actors that pair well with this one:

- **[NL Vergunningen & Bekendmakingen Leadfeed](https://apify.com/codeclouds/nl-vergunningen-leadfeed)** — the same lead-generation-from-government-publications approach, for Dutch building/environmental permits instead of tenders.
- **[NL CAO Wijzigingen Database](https://apify.com/codeclouds/nl-cao-wijzigingen-database)** — the same official Dutch publication family (Staatscourant / officielebekendmakingen.nl), for collective labour agreement changes.
- **[PDOK Adres Geocoding & Buurtdata](https://apify.com/codeclouds/pdok-locatieserver)** — geocode buyer addresses or project locations extracted from tender descriptions.

***

### Support & Feedback

- **Issues**: Apify Actor page
- **Response Time**: Within 14 days (urgent: 3 business days)
- **Feature Requests**: Welcome — open an issue with the `enhancement` label

***

*Zoekwoorden: aanbestedingen nederland, tenderned scraper, overheidsopdrachten, europese aanbesteding, cpv-code zoeken, aanbesteding monitor nederland.*

### Keywords

tenderned, ted, procurement, aanbesteding, tender, lead-generation, government, public-procurement, mcp

***

### Changelog

- 2026-07-13: Documentation update — added a Dutch-language "Zoekwoorden" line for search coverage on NL-specific terms.
- 2026-07-12: Added company-profile CPV matching — new optional `bedrijfCpvCodes` and `alleenRelevanteTenders` input fields, new `relevantieScore`/`relevantieMatchedCpv` output fields. Fully backward compatible: existing behavior is unchanged when these fields are left empty.
- 2026-07-12: Documentation update — fixed a rendering bug where JSON code examples showed literal escaped quotes (`\"`) instead of `"`; added a "Related Actors" section cross-linking other actors by this developer.
- Initial release
- TenderNed + TED API v3 integration
- Incremental mode with KeyValueStore
- Pay Per Event pricing
- Full input validation (Zod)
- Comprehensive test suite (21 tests)

***

### Developer

Built by an independent developer. No enterprise affiliation with TenderNed, TED, or the European Commission.

**Apify Store**: NL & EU Government Tenders Scraper\
**Pricing Model**: Pay Per Event ($0.005/tender)

***

# Actor input Schema

## `source` (type: `string`):

Which tender platform(s) to fetch from.

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

Filter by CPV codes, e.g. \["45000000", "72000000"]. Leave empty for all.

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

ISO country codes, e.g. \["NL", "BE"]. Leave empty for all.

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

Only tenders published on or after this date (YYYY-MM-DD), e.g. "2026-01-01".

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

Only tenders with submission deadline on or after this date (YYYY-MM-DD), e.g. "2026-07-01".

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

Skip tenders with estimated value below this amount, e.g. 100000.

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

Maximum number of tenders to return (1–5000).

## `incrementalMode` (type: `boolean`):

When enabled, only fetches tenders newer than the previous run. Ideal for scheduled monitoring.

## `bedrijfCpvCodes` (type: `array`):

Optional: your company's own CPV codes/prefixes, e.g. \["45213000", "72000000"]. Each result gets a relevantieScore (0/40/70/100) and relevantieMatchedCpv based on how closely its CPV codes match yours. Note: TenderNed results have no CPV data, so their score is always null. Leave empty to disable.

## `alleenRelevanteTenders` (type: `boolean`):

When enabled together with Company CPV Codes, skips (and doesn't charge for) tenders with a relevantieScore of 0. Has no effect if Company CPV Codes is empty.

## Actor input object example

```json
{
  "source": "both",
  "cpvCodes": [],
  "countries": [],
  "publishedAfter": "2026-01-01",
  "deadlineAfter": "2026-07-01",
  "minValue": 100000,
  "maxResults": 100,
  "incrementalMode": false,
  "bedrijfCpvCodes": [],
  "alleenRelevanteTenders": false
}
```

# 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 = {
    "publishedAfter": "2026-01-01",
    "deadlineAfter": "2026-07-01",
    "minValue": 100000
};

// Run the Actor and wait for it to finish
const run = await client.actor("codeclouds/nl-eu-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 = {
    "publishedAfter": "2026-01-01",
    "deadlineAfter": "2026-07-01",
    "minValue": 100000,
}

# Run the Actor and wait for it to finish
run = client.actor("codeclouds/nl-eu-tenders-scraper").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 '{
  "publishedAfter": "2026-01-01",
  "deadlineAfter": "2026-07-01",
  "minValue": 100000
}' |
apify call codeclouds/nl-eu-tenders-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=codeclouds/nl-eu-tenders-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "NL & EU Government Tenders Scraper | TenderNed + TED",
        "description": "Get fresh NL and EU public procurement notices as structured leads. Filter by CPV code, deadline, value and country. MCP-ready.",
        "version": "0.1",
        "x-build-id": "mxVCgAlqL7JX8RZaL"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/codeclouds~nl-eu-tenders-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-codeclouds-nl-eu-tenders-scraper",
                "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/codeclouds~nl-eu-tenders-scraper/runs": {
            "post": {
                "operationId": "runs-sync-codeclouds-nl-eu-tenders-scraper",
                "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/codeclouds~nl-eu-tenders-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-codeclouds-nl-eu-tenders-scraper",
                "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": {
                    "source": {
                        "title": "Source",
                        "enum": [
                            "tenderned",
                            "ted",
                            "both"
                        ],
                        "type": "string",
                        "description": "Which tender platform(s) to fetch from.",
                        "default": "both"
                    },
                    "cpvCodes": {
                        "title": "CPV Codes",
                        "type": "array",
                        "description": "Filter by CPV codes, e.g. [\"45000000\", \"72000000\"]. Leave empty for all.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "Countries (TED only)",
                        "type": "array",
                        "description": "ISO country codes, e.g. [\"NL\", \"BE\"]. Leave empty for all.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "publishedAfter": {
                        "title": "Published After",
                        "type": "string",
                        "description": "Only tenders published on or after this date (YYYY-MM-DD), e.g. \"2026-01-01\"."
                    },
                    "deadlineAfter": {
                        "title": "Deadline After",
                        "type": "string",
                        "description": "Only tenders with submission deadline on or after this date (YYYY-MM-DD), e.g. \"2026-07-01\"."
                    },
                    "minValue": {
                        "title": "Min. Contract Value (EUR)",
                        "type": "integer",
                        "description": "Skip tenders with estimated value below this amount, e.g. 100000."
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of tenders to return (1–5000).",
                        "default": 100
                    },
                    "incrementalMode": {
                        "title": "Incremental Mode",
                        "type": "boolean",
                        "description": "When enabled, only fetches tenders newer than the previous run. Ideal for scheduled monitoring.",
                        "default": false
                    },
                    "bedrijfCpvCodes": {
                        "title": "Company CPV Codes (profile matching)",
                        "type": "array",
                        "description": "Optional: your company's own CPV codes/prefixes, e.g. [\"45213000\", \"72000000\"]. Each result gets a relevantieScore (0/40/70/100) and relevantieMatchedCpv based on how closely its CPV codes match yours. Note: TenderNed results have no CPV data, so their score is always null. Leave empty to disable.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "alleenRelevanteTenders": {
                        "title": "Only Relevant Tenders",
                        "type": "boolean",
                        "description": "When enabled together with Company CPV Codes, skips (and doesn't charge for) tenders with a relevantieScore of 0. Has no effect if Company CPV Codes is empty.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
