# TED Tender Monitor — EU Procurement Alerts (`uplifted_novice_vbl/ted-tender-watch`) Actor

TED tender monitor for new or changed EU public procurement notices. Filter by CPV, country, keyword, minimum value, or notice type and receive EU tender alerts as JSON or signed webhooks. Unofficial and not affiliated with TED, the EU, or its Publications Office.

- **URL**: https://apify.com/uplifted\_novice\_vbl/ted-tender-watch.md
- **Developed by:** [Telemark Digital](https://apify.com/uplifted_novice_vbl) (community)
- **Categories:** Automation, Lead generation, News
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 new tenders

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

**TED Tender Monitor - EU Procurement Alerts monitors official TED notices on a schedule.** It checks the official TED Search API and delivers only new or changed notices matching CPV, country, keyword, minimum known EUR value, or notice type as structured JSON and optional HMAC-signed webhooks.

> **Independent service notice:** This is an unofficial, independent community Actor. It is not affiliated with, endorsed by, or operated by TED, the European Union, or the Publications Office of the European Union.

### What it does

- Filter EU tenders by CPV prefix, buyer country, keyword, minimum known EUR value, and TED notice type.
- Receive new and changed notices as structured JSON in an Apify dataset and, optionally, as one HMAC-signed webhook per run.
- Pay only for delivered new or changed notices. Sample runs, the first prime run, duplicates, skipped records, quiet days, and failures before the final charge step trigger no tender event charge.

#### 30-second quickstart

1. Leave **Free sample mode** on and click **Start**. You will receive the ten newest matching competition notices, with no state and no tender charge.
2. Turn sample mode off and run the same input once. This free **prime run** records the current matching publication numbers but delivers no tenders, preventing a historical flood.
3. Save the configuration as an Apify Task and schedule it. Add a signed webhook if your CRM, agent, or automation needs push delivery.

### Why most TED monitors silently lose tenders

TED's `publication-date` has day-level granularity. Thousands of notices can share one value, so `SORT BY publication-date DESC` plus page-number pagination does not define a stable order. Repeating the same page can change its membership while a new Official Journal release arrives; page-number mode also documents that cross-page consistency is not guaranteed.

This Actor avoids that trap:

1. It queries a publication-date overlap window but sorts by deterministic `publication-number DESC`.
2. It uses TED's point-in-time-consistent `ITERATION` pagination until the result set is exhausted.
3. It normalizes and sorts deliveries by `(publicationDate ASC, publicationNumber ASC within that date)`.
4. It deduplicates on universal `publication-number`, including pre-eForms notices that have no UUID.
5. It journals each attempted dataset record, commits seen state only after the complete dataset write, and verifies an interrupted run's actual dataset before recovering IDs. Unconfirmed records remain eligible for delivery and billing is never retried for an already committed ID.

#### Replayable correctness recipe

- Run a new non-sample filter once: the dataset contains a `prime` record and zero tender deliveries.
- Run the identical filter again without a new TED release: the summary reports zero new tenders and the run costs $0 in tender events.
- Change a state-defining filter such as CPV, country, keyword, minimum value, or notice type: the canonical state key changes and the new filter primes separately.

For an independent API check, send the same keyless TED Search request twice with `SORT BY publication-number DESC`; the ordered publication numbers remain stable. Do not use date-only page 1 as a cursor.

### Honest alternatives

| Option | Where it wins | Where TED Tender Monitor - EU Procurement Alerts wins |
|---|---|---|
| Established Apify TED scrapers | They already have adoption, a review history, and some offer AI enrichment or lower per-result pricing. | This Actor delivers stateful only-new results, signed push, explicit change notices, and documented no-truncation behavior. |
| Existing delta-monitor Actors | Some already use a KV seen-set; one is cheaper. | This implementation documents the date-sort failure, uses ITERATION paging, handles legacy corrigenda, exposes overflow, and tests no rebilling under backlog. |
| Official TED email and RSS alerts | If you just want an email, use TED's free alerts. They are the right choice for a person reading notices. | This Actor is for machine-shaped JSON, pipelines, CRMs, automations, and agents. |
| Tender intelligence SaaS or flat-price APIs | They can provide curation, enrichment, support, analytics, and SLAs. | This Actor is usage-priced, runs inside Apify, and is focused on correct new-only delivery rather than enrichment. |

This is a tender monitor, not an award analytics product, translation service, multi-source portal, or bid-scoring tool.

### Input reference

| Input | Default | Meaning |
|---|---:|---|
| `sampleMode` | `false` (`true` in the Store prefill) | Return ten newest matches; write no state; charge no tender events. |
| `cpvCodes` | `[]` | CPV prefixes, 2–8 digits. `72` covers IT; `45` covers construction. Empty means all sectors. |
| `countries` | `[]` | Buyer countries as ISO alpha-3 codes such as `DEU`, `FRA`, `ESP`. |
| `keywords` | `[]` | OR-matched full-text words or phrases. Terms are safely quoted. |
| `minValueEur` | `0` | Minimum for known procedure-level EUR values. Unknown or non-EUR values still pass with `valueUnknown=true`. No FX conversion is performed. |
| `noticeTypes` | competition types | One or more accepted TED codes listed below. |
| `includeChangeNotices` | `true` | Include modern linked changes and automatically add `can-modif` plus legacy `corr` to the TED query. |
| `lookbackDays` | `3` | Minimum overlap. Effective lookback automatically expands to the actual run gap plus one day. |
| `maxNewPerRun` | `5000` | Delivery/billing ceiling from 1–10,000. Excess matches are explicitly deferred oldest-first. |
| `webhookUrl` | unset | Optional HTTP(S) destination; must be supplied with `webhookSecret`. |
| `webhookSecret` | unset | Secret used for `X-Watch-Signature`. |
| `stateKey` | Task + filter hash | Advanced override. Giving multiple Tasks the same value deliberately makes them share state. |

Accepted current notice types are `brin-ecs`, `brin-eeig`, `can-desg`, `can-modif`, `can-social`, `can-standard`, `can-tran`, `cn-desg`, `cn-social`, `cn-standard`, `compl`, `pin-buyer`, `pin-cfc-social`, `pin-cfc-standard`, `pin-only`, `pin-rtl`, `pin-tran`, `pmc`, `qu-sy`, `subco`, and `veat`. Live legacy code `corr` is also accepted.

The default state key is SHA-256 over the Apify Task identity and canonical sorted `cpvCodes`, `countries`, `keywords`, `minValueEur`, and `noticeTypes`. Ad-hoc runs use the Apify user identity as their scope. Separate Tasks therefore keep independent history even when their filters are identical. An explicit `stateKey` deliberately overrides this isolation so multiple Tasks can share state. Delivery-only settings do not silently fork historical state. Suppressed changes are not marked seen, so enabling change delivery later can surface them once. Runs sharing one state key are serialized with an Apify Request Queue lease; an overlapping run exits before delivery or billing.

### Output schema

The default dataset contains three explicit record types:

- `tender`: one delivered new or changed notice.
- `prime`: the required free first-run information record.
- `summary`: counts and overflow/budget flags for sample and monitoring runs.

Representative tender record:

```json
{
  "recordType": "tender",
  "publicationNumber": "488405-2026",
  "noticeIdentifier": "69d7fb9a-e58b-4f91-a2fd-7d59312fde31",
  "publicationDate": "2026-07-15",
  "noticeType": "cn-standard",
  "isChangeNotice": false,
  "modifiesPublicationNumber": null,
  "title": "Spain – Repair and maintenance services of electrical building installations – …",
  "titleLanguage": "eng",
  "buyerName": "Reus Mobilitat i Serveis SA",
  "buyerCountry": "ESP",
  "cpvCodes": ["50711000"],
  "estimatedValueEur": null,
  "valueUnknown": true,
  "deadlineDate": "2026-09-14",
  "links": {
    "html": "https://ted.europa.eu/en/notice/-/detail/488405-2026",
    "pdf": "https://ted.europa.eu/en/notice/488405-2026/pdf",
    "xml": "https://ted.europa.eu/en/notice/488405-2026/xml"
  },
  "isNew": true,
  "firstSeenAt": "2026-07-16T09:00:00.000Z",
  "stateKey": "sha256:…"
}
````

Title selection is deterministic: `eng` when present, otherwise the alphabetically first available ISO-639-2 language key. CPVs are a deduplicated notice/lot union. The value is procedure-level only; lot values are never summed. The earliest valid lot deadline is exposed. Missing fields remain `null` and are never invented.

### Pricing and billing honesty

- `new-tender`: **$0.005** per newly delivered notice.
- `changed-tender`: **$0.005** per delivered correction or modification.
- Actor start: **no start event is configured**; platform usage is included rather than added to the event price.
- Sample, prime, duplicate, malformed, skipped, and quiet paths: **$0 tender event charge**. Failures before the final charge step also trigger no tender event charge.

Charging happens only after filtering, deduplication, and durable dataset/state delivery. The Actor reads the run's maximum-charge limit and defers work that cannot fit. A rare platform charge failure after delivery is never retried for the same publication number; preserving “never billed twice” takes priority over developer revenue.

A corrigendum is new information and is billed as its own `changed-tender` event. Therefore one procurement can produce up to two charges: the original `new-tender`, then its later correction. This is deliberate and visible in `isChangeNotice`.

### Scheduling, signed webhooks, and integrations

Save a primed input as an Apify Task, then choose the cadence that matches your filter. Narrow CPV/country filters can run hourly or daily. Broad EU-wide filters should run daily or increase `maxNewPerRun`; persistent filters whose protected in-window seen-set alone would exceed 150,000 IDs fail explicitly instead of evicting IDs and rebilling them.

When configured, the webhook body is the JSON array of tender records only. Headers:

- `X-Watch-Signature`: lowercase hex HMAC-SHA256 of the exact body using `webhookSecret`.
- `X-Watch-Run-Id`: the Apify run ID.

Webhook delivery makes one initial attempt plus three retries with backoff. Every request has a 15-second timeout and runs after state commit but before billing. A webhook failure never removes dataset results or repeats a charge.

Connect the dataset or run event through Apify integrations to Make, Zapier, n8n, Slack, cloud storage, or your own API. AI agents can discover this Actor through the Apify MCP server using Store search, inspect its schema, add it as a tool, and call it; it is not automatically preinstalled in every agent.

#### Run through the Apify API

Use an Authorization header so your token is not placed in a URL or log:

```bash
curl -X POST "https://api.apify.com/v2/acts/uplifted_novice_vbl~ted-tender-watch/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sampleMode":true,"cpvCodes":["72"],"countries":["DEU"]}'
```

The run response links to its default dataset. For scheduled monitoring, use the same JSON with `sampleMode=false`, run it once to prime, then save it as an Apify Task and attach a schedule.

### Change notices

Modern eForms changes are detected from `change-notice-version-identifier` or `modification-previous-notice-identifier`. TED also still serves legacy `notice-type=corr` records whose linkage fields can be empty, so `corr` is treated as a change for compatibility. `modifiesPublicationNumber` is set only when a linkage value is actually a TED publication number; UUID/version identifiers are not mislabeled.

If `includeChangeNotices=false`, change records are neither delivered nor added to the seen-set. Enabling the option later can deliver a previously suppressed change once.

### Limits, errors, and FAQ

#### What data source is used?

Only the official keyless TED API v3 Search endpoint. There is no HTML scraping fallback, no login, and no third-party tender source.

#### What happens during TED rate limits or outages?

The client self-caps at two requests per second. HTTP 429 and 5xx responses retry after approximately 1, 4, and 16 seconds. Persistent failure ends cleanly before state advancement or tender charges.

#### Can a malformed notice stop the batch?

No. A notice missing the universal publication number or publication date is logged, skipped, and never charged. An unknown stored state schema does stop the run with a clear error; state is never wiped or guessed.

#### Does minimum value convert currencies?

No. Current eForms procedure values come from BT-27 fields; older global aliases are a fallback. Only an unambiguous EUR procedure value is compared. Missing, ambiguous, and non-EUR values remain deliverable as unknown so a potentially relevant opportunity is not silently lost.

#### What is not included in v1?

AI relevance scoring, summaries, translation, per-lot output, email formatting, award analytics, historical backfill, national portals, currency conversion, a custom MCP server, and a separate dashboard are intentionally out of scope.

#### Where can I get support?

Open the Actor's **Issues** tab in Apify Console with the run ID, input with secrets removed, and the relevant log excerpt. Do not post webhook secrets or Apify tokens.

European teams may search for the same job using terms such as **przetargi**, **appalti**, **ausschreibung**, or **licitaciones**. The Actor is built for **TED Europa**, **eForms**, **CPV**, **EU tenders**, procurement pipelines, a **tender alert**, and a stateful **tender monitor**.

### Changelog

#### 0.1 — 2026-07-16

Initial publish-ready release: deterministic ITERATION client, stateful new-only delivery, current eForms and legacy mapping, signed webhooks, honest PPE events, complete Apify schemas, and recovery-aware deduplication.

# Actor input Schema

## `sampleMode` (type: `boolean`):

Returns the 10 newest matching TED notices immediately. Writes no monitor state and triggers no tender charges. Turn this off when you are ready to prime a saved monitor.

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

Optional 2–8 digit Common Procurement Vocabulary prefixes, for example 72 for IT or 45 for construction. Empty means every sector.

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

Optional ISO-3166 alpha-3 buyer country codes such as DEU, FRA, ESP. Empty means all countries.

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

Optional full-text terms, OR-matched by TED. Empty means no keyword clause. Each term is safely quoted in the expert query.

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

Client-side minimum for known procedure-level EUR values. Notices with missing, ambiguous, or non-EUR values still pass with valueUnknown=true; this Actor never performs FX conversion or silently drops unknown values.

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

Official TED notice-type codes. Defaults to competition notices. Legacy corr is accepted because it remains present in the live Search API.

## `includeChangeNotices` (type: `boolean`):

When enabled, the TED query automatically includes can-modif and legacy corr alongside your selected types, and delivers linked changes as separately billed changed-tender events.

## `lookbackDays` (type: `integer`):

Overlap floor for late publication. The Actor automatically extends this to the real gap since the last successful run, plus one safety day, so weekly and fortnightly schedules remain covered.

## `maxNewPerRun` (type: `integer`):

Billing and delivery ceiling. Overflow is explicit and deferred oldest-first without advancing past undelivered notices. Broad EU-wide filters should run daily or use a higher cap.

## `webhookUrl` (type: `string`):

Optional HTTP(S) endpoint. Receives one JSON array of delivered tender records after durable dataset and state delivery, with one initial attempt plus three bounded retries. Requires webhookSecret.

## `webhookSecret` (type: `string`):

Required with webhookUrl. Used for the X-Watch-Signature HMAC-SHA256 header. Stored as a secret input value.

## `stateKey` (type: `string`):

Optional advanced override for deliberately sharing monitor state. By default, state is isolated per Apify Task and filter set; changing filters starts a fresh prime run. Supplying the same stateKey to multiple Tasks intentionally overrides Task isolation.

## Actor input object example

```json
{
  "sampleMode": true,
  "cpvCodes": [],
  "countries": [],
  "keywords": [],
  "minValueEur": 0,
  "noticeTypes": [
    "cn-standard",
    "cn-social",
    "cn-desg"
  ],
  "includeChangeNotices": true,
  "lookbackDays": 3,
  "maxNewPerRun": 5000
}
```

# Actor output Schema

## `items` (type: `string`):

Tender, prime, and summary records in the default dataset.

## `runSummary` (type: `string`):

Machine-readable summary or prime record.

# 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 = {
    "sampleMode": true,
    "cpvCodes": [],
    "countries": [],
    "keywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("uplifted_novice_vbl/ted-tender-watch").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 = {
    "sampleMode": True,
    "cpvCodes": [],
    "countries": [],
    "keywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("uplifted_novice_vbl/ted-tender-watch").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 '{
  "sampleMode": true,
  "cpvCodes": [],
  "countries": [],
  "keywords": []
}' |
apify call uplifted_novice_vbl/ted-tender-watch --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TED Tender Monitor — EU Procurement Alerts",
        "description": "TED tender monitor for new or changed EU public procurement notices. Filter by CPV, country, keyword, minimum value, or notice type and receive EU tender alerts as JSON or signed webhooks. Unofficial and not affiliated with TED, the EU, or its Publications Office.",
        "version": "0.1",
        "x-build-id": "BJjl19dnI58rweOhh"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/uplifted_novice_vbl~ted-tender-watch/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-uplifted_novice_vbl-ted-tender-watch",
                "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/uplifted_novice_vbl~ted-tender-watch/runs": {
            "post": {
                "operationId": "runs-sync-uplifted_novice_vbl-ted-tender-watch",
                "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/uplifted_novice_vbl~ted-tender-watch/run-sync": {
            "post": {
                "operationId": "run-sync-uplifted_novice_vbl-ted-tender-watch",
                "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": {
                    "sampleMode": {
                        "title": "Free sample mode",
                        "type": "boolean",
                        "description": "Returns the 10 newest matching TED notices immediately. Writes no monitor state and triggers no tender charges. Turn this off when you are ready to prime a saved monitor.",
                        "default": false
                    },
                    "cpvCodes": {
                        "title": "CPV code prefixes",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional 2–8 digit Common Procurement Vocabulary prefixes, for example 72 for IT or 45 for construction. Empty means every sector.",
                        "items": {
                            "type": "string",
                            "pattern": "^[0-9]{2,8}$"
                        },
                        "default": []
                    },
                    "countries": {
                        "title": "Buyer countries",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional ISO-3166 alpha-3 buyer country codes such as DEU, FRA, ESP. Empty means all countries.",
                        "items": {
                            "type": "string",
                            "pattern": "^[A-Za-z]{3}$"
                        },
                        "default": []
                    },
                    "keywords": {
                        "title": "Keywords or phrases",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional full-text terms, OR-matched by TED. Empty means no keyword clause. Each term is safely quoted in the expert query.",
                        "items": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "default": []
                    },
                    "minValueEur": {
                        "title": "Minimum procedure value (EUR)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Client-side minimum for known procedure-level EUR values. Notices with missing, ambiguous, or non-EUR values still pass with valueUnknown=true; this Actor never performs FX conversion or silently drops unknown values.",
                        "default": 0
                    },
                    "noticeTypes": {
                        "title": "TED notice types",
                        "minItems": 1,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Official TED notice-type codes. Defaults to competition notices. Legacy corr is accepted because it remains present in the live Search API.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "brin-ecs",
                                "brin-eeig",
                                "can-desg",
                                "can-modif",
                                "can-social",
                                "can-standard",
                                "can-tran",
                                "cn-desg",
                                "cn-social",
                                "cn-standard",
                                "compl",
                                "corr",
                                "pin-buyer",
                                "pin-cfc-social",
                                "pin-cfc-standard",
                                "pin-only",
                                "pin-rtl",
                                "pin-tran",
                                "pmc",
                                "qu-sy",
                                "subco",
                                "veat"
                            ]
                        },
                        "default": [
                            "cn-standard",
                            "cn-social",
                            "cn-desg"
                        ]
                    },
                    "includeChangeNotices": {
                        "title": "Include change and corrigendum notices",
                        "type": "boolean",
                        "description": "When enabled, the TED query automatically includes can-modif and legacy corr alongside your selected types, and delivers linked changes as separately billed changed-tender events.",
                        "default": true
                    },
                    "lookbackDays": {
                        "title": "Minimum overlap window (days)",
                        "minimum": 1,
                        "maximum": 30,
                        "type": "integer",
                        "description": "Overlap floor for late publication. The Actor automatically extends this to the real gap since the last successful run, plus one safety day, so weekly and fortnightly schedules remain covered.",
                        "default": 3
                    },
                    "maxNewPerRun": {
                        "title": "Maximum new tenders per run",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Billing and delivery ceiling. Overflow is explicit and deferred oldest-first without advancing past undelivered notices. Broad EU-wide filters should run daily or use a higher cap.",
                        "default": 5000
                    },
                    "webhookUrl": {
                        "title": "Signed webhook URL",
                        "type": "string",
                        "description": "Optional HTTP(S) endpoint. Receives one JSON array of delivered tender records after durable dataset and state delivery, with one initial attempt plus three bounded retries. Requires webhookSecret."
                    },
                    "webhookSecret": {
                        "title": "Webhook HMAC secret",
                        "type": "string",
                        "description": "Required with webhookUrl. Used for the X-Watch-Signature HMAC-SHA256 header. Stored as a secret input value."
                    },
                    "stateKey": {
                        "title": "State key override",
                        "maxLength": 200,
                        "type": "string",
                        "description": "Optional advanced override for deliberately sharing monitor state. By default, state is isolated per Apify Task and filter set; changing filters starts a fresh prime run. Supplying the same stateKey to multiple Tasks intentionally overrides Task isolation."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
