# Public Tenders Scraper: EU TED & UK Contracts (`rookdev/public-tenders-monitor`) Actor

New government tenders and contract notices from the official EU TED and UK Find a Tender and Contracts Finder APIs, filtered by keywords, CPV codes, countries and value, with only-new monitoring and Slack-ready summaries.

- **URL**: https://apify.com/rookdev/public-tenders-monitor.md
- **Developed by:** [Rook Dev](https://apify.com/rookdev) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 notices

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Public Tenders Scraper: EU TED & UK Contracts

**Get new government tenders from the EU (TED) and the UK (Find a Tender, Contracts Finder) in one clean table, filtered to your market, or schedule it and get only the tenders published or updated since the last run, with a ready-made one-line alert for each.**

- **Three official sources, one row shape.** EU Tenders Electronic Daily (every EU and EEA country), UK Find a Tender and UK Contracts Finder, all from their official open-data APIs. Same fields for all: title, buyer, country, deadline, value, CPV codes, procedure and a link to the official notice.
- **Filters that matter for bidding.** Keywords, exclusions, CPV codes (prefix match), buyer countries, minimum value (any currency, compared in euros) and notice type: open tenders, planned tenders or contract awards.
- **Monitoring built in.** Turn on *Only new and updated notices*, schedule it, and you pay only for what is new: `new` tenders, and `changed` ones when the buyer moves the deadline or the value (with the previous deadline and value).
- **Slack-ready.** Every row has a one-line `summary`, and the run's status message lists the first new tenders, so the built-in Slack integration posts *"New tender (DE, TED): Rahmenvereinbarung Kreativagentur 2027 - 2030 – Tourismus-Agentur Schleswig-Holstein GmbH. Deadline 2026-11-30 06:30 UTC"* with no extra tools.
- **Complete UK coverage.** Find a Tender is read in full and filtered here, so Procurement Act 2023 notices are included. (Asking that API for `stages=tender` returns only notices under the old regulations: 9 of the 101 tender notices published on 28 and 29 October 2026.)
- **No personal data.** Contact names, e-mail addresses and phone numbers are never collected, and sentences carrying them are removed from descriptions. You get organisations and links to the official notices.

It calls three public APIs with plain HTTP requests: no browser, no proxies, no logins. Runs are fast, cheap and gentle on the services.

### Sample output

```json
{
  "status": "new",
  "summary": "New tender (GB, Find a Tender): EEAST - 26-T20 - Neurodiversity Awareness Training – East of England Ambulance Service NHS Trust. Deadline 2026-11-23 12:00 UTC, GBP 1,000,000",
  "source": "uk-find-a-tender",
  "noticeId": "102921-2026",
  "stage": "tender",
  "title": "EEAST - 26-T20 - Neurodiversity Awareness Training",
  "buyer": "East of England Ambulance Service NHS Trust",
  "buyerCountry": "GB",
  "deadline": "2026-11-23T12:00:00Z",
  "valueAmount": 1000000,
  "valueCurrency": "GBP",
  "cpvCodes": ["80000000"],
  "noticeType": "UK4",
  "procedureType": "Open procedure",
  "publishedAt": "2026-10-29T19:29:31Z",
  "description": "The Contracting Authority is seeking to establish a Light Touch Framework Agreement with a suitably qualified and experienced Supplier to co-design, develop and deliver a suite of Neurodiversity Aware…",
  "url": "https://www.find-tender.service.gov.uk/Notice/102921-2026",
  "trackingId": "ocds-h6vhtk-079422/tender",
  "firstSeenAt": "2026-10-29T22:00:00Z",
  "scrapedAt": "2026-10-29T22:00:00Z"
}
```

A real notice published on 29 October 2026 (the description is cut short in our test capture; live rows carry up to 500 characters). TED rows look the same, with the title in English when the notice has an English version and otherwise in its original language, for example `"title": "Dostawa aparatu RTG z adaptacją pomieszczeń - 1 kpl"`, `"buyerCountry": "PL"`, `"valueAmount": 2090617.94`, `"valueCurrency": "PLN"`.

### Who uses it

- **Companies that bid for public contracts:** a daily feed of the tenders in your CPV codes and countries, in Slack or a sheet, before competitors spot them.
- **Bid writers, consultants and agencies:** watch tenders for several clients, one saved task per client, each with its own filters and memory.
- **Sales and RevOps teams:** public buyers who are about to spend are warm leads; contract awards show who won what, for how much, and when it renews.
- **Market and competitor research:** export a week or two of notices in a sector to size demand by country, buyer and value.
- **AI agents:** a narrow, predictable tool for "what new tenders match this profile?"; works through the Apify MCP server.

### How to use it

1. Keep the three **Sources** or pick the ones you need.
2. Add **CPV codes** (the most reliable filter across languages), **Keywords** and **Buyer countries**. Leave a filter empty to skip it.
3. Click **Start**. Download the results as JSON, CSV or Excel, or read them through the API.

**To monitor:** turn on **Only new and updated notices since the last run**, save the input as a task and add a daily schedule. The first run returns every matching notice in the window that is still open for bids as `new` (or, with **Start quietly**, just records them); after that you get only new tenders and tenders whose deadline or value moved. Monitoring skips notices whose deadline has already passed. Connect the task to Slack, e-mail, Google Sheets, Make, Zapier or n8n to get alerts. Keep **Published or updated in the last (days)** at 3 or more (7 is the default): a weekday schedule does not run at weekends, and a 1-day window would miss what was published then.

#### Input examples

IT and software tenders in Germany, Austria and the Netherlands, last 7 days:

```json
{
  "sources": ["ted"],
  "cpvCodes": ["72", "48"],
  "countries": ["DE", "AT", "NL"]
}
```

Daily monitor for marketing tenders worth at least EUR 100,000 in the EU and the UK, starting quietly:

```json
{
  "sources": ["ted", "uk-find-a-tender", "uk-contracts-finder"],
  "cpvCodes": ["79340000", "79341000"],
  "keywords": ["marketing", "advertising", "Werbung", "publicité"],
  "excludeKeywords": ["printing"],
  "minValue": 100000,
  "publishedWithinDays": 3,
  "onlyNew": true,
  "skipExistingOnFirstRun": true
}
```

Contract awards in the UK for construction (who won, and for how much):

```json
{ "sources": ["uk-find-a-tender", "uk-contracts-finder"], "stages": ["award"], "cpvCodes": ["45"] }
```

#### Inputs

| Field | What it does |
| --- | --- |
| `sources` | `ted`, `uk-find-a-tender`, `uk-contracts-finder` (all three by default). |
| `keywords` | Keep notices that mention any of these words or phrases (whole words, any case). TED searches the full notice text in its own language; the UK sources search title, description and buyer. |
| `excludeKeywords` | Drop notices whose title, description or buyer mentions any of these. |
| `cpvCodes` | Keep notices with a CPV code starting with any of these: `72`, `48`, `45`, `79340000`. A full code with trailing zeros covers everything below it. |
| `countries` | Buyer countries as ISO codes (`DE`, `FR`, `PL`, `GB`; `UK`, `EL` and three-letter codes work too). The UK sources are left out unless `GB` is listed, and the status message says so. |
| `stages` | `tender` (open calls for bids, default), `planning` (planned tenders), `award` (contract awards). |
| `minValue` | Minimum value in euros. Other currencies are converted at approximate fixed rates; notices without a stated value are kept. |
| `publishedWithinDays` | How far back each run looks, 1 to 60 days (default 7). Use 3 or more for a scheduled monitor. |
| `onlyNew` | Monitoring: return only new notices and tenders whose deadline or value moved. |
| `skipExistingOnFirstRun` | Monitoring: the first run records what exists without returning it. |
| `maxNoticesPerSource` | Row cap per source per run (default 1,000). When monitoring, new notices go out oldest first and those over the cap are held back for the next run; the status message says how many. If more new notices arrive per run than the cap allows, raise it or narrow the filters, because a notice that leaves the window before it is delivered is not sent. |
| `stateStoreName` | Name of the key-value store that holds the monitoring memory. |

A filter value that cannot be used (a CPV code with letters, an unknown country) stops the run before anything is fetched, with a free row explaining it, so a typo never turns a narrow search into an expensive one.

### Output

One row per notice: `status`, `summary`, `source`, `noticeId`, `stage`, `title`, `buyer`, `buyerCountry`, `deadline` (UTC; the last lot deadline when lots differ, the request-to-participate deadline for restricted procedures), `valueAmount` and `valueCurrency` (estimated value for tenders, awarded value for awards), `cpvCodes`, `noticeType` (the source's own type: `cn-standard`, `UK4`...), `procedureType`, `publishedAt`, `description` (plain text, up to 500 characters), `url` (the official notice), `trackingId`, `firstSeenAt` (monitoring) and `scrapedAt`. `status` is `current` in a normal run, or `new` or `changed` when monitoring; `changed` rows also have `previousDeadline`, `previousValueAmount` and `previousValueCurrency`.

Inputs that produced no data get a free row with `status` `invalid_input`, `error`, `not_found` or `skipped` and a plain-English `error`. A `RUN_SUMMARY` record in the run's key-value store lists, per source, the TED query used, the window, pages and records read, matches, whether everything was read, notices held back by the cap and any records that could not be read (skipped and counted, never failing the source).

### Get alerts in Slack, Google Drive, Make, Zapier or n8n

1. Turn on monitoring, click **Save as a new task**, and add a daily schedule to the task (for example 07:00 on weekdays; TED publishes Monday to Friday).
2. On the task's **Integrations** tab, pick **Slack**, connect your workspace, choose the **Run succeeded** event and a channel, and paste this as the message:

```handlebars
*{{resource.statusMessage}}*
<https://console.apify.com/storage/datasets/{{resource.defaultDatasetId}}|Open all new tenders>
```

The status message reads like *Checked 3 source(s), saved 7 notice row(s) (6 new, 1 changed). New tender (DE, TED): Rahmenvereinbarung Kreativagentur 2027 - 2030 – Tourismus-Agentur Schleswig-Holstein GmbH. Deadline 2026-11-30 06:30 UTC; …* so the alert itself tells you what to look at.

- **Google Drive:** the **Upload results to GDrive** integration saves each run's rows as CSV or JSON.
- **Make, Zapier, n8n:** use the Apify app's "Actor run finished" trigger, read the dataset and map `summary` and `url` into a message, a sheet row or a CRM task.
- **Webhooks:** send the run to your own endpoint and read the dataset through the API.

### Pricing

Pay per event, no platform usage charges on top:

| Event | Price |
| --- | --- |
| Notice returned (`notice`) | $3.00 per 1,000 notices |
| Source checked (`source-checked`) | $1.00 per 1,000 source checks |

Rows for inputs that could not be used are free. A source check is charged after its rows are delivered, so if your spending limit stops the run before any of a source's rows go out, that check is free.

- **One-off market scan:** IT and software tenders (CPV 72 and 48) published on TED in the 7 days to 29 October 2026 numbered 1,036. A run with the default cap returns 1,000 of them plus the UK matches, for about **$3.00 to $3.30**.
- **Daily monitoring of the same market:** about 1,036 new matching tenders a week across the EU is about **$3.10 a week, about $13.50 a month**, plus $0.09 a month for checking three sources every day. A narrower monitor, such as software tenders in CPV 72 from German buyers (88 in the same week), costs about **$0.26 a week, about $1.20 a month**. With **Start quietly**, the first run costs only the source checks ($0.003) instead of paying for the notices already published.

Set a maximum cost per run in the run options and the Actor stops cleanly when it reaches it: sources it could not check get a free `skipped` row, and when monitoring, notices it could not deliver come on the next run. Rows it delivered are never charged twice.

### Data sources, licences, coverage and delays

| Source | What it covers | Delay | Licence |
| --- | --- | --- | --- |
| **TED** (`api.ted.europa.eu`, Search API v3, no key needed) | Notices published in the Supplement to the Official Journal of the EU: tenders above EU thresholds from all EU countries, EEA countries and EU institutions, plus voluntary notices. About 4,000 notices per publishing day (22,654 in the 7 days to 29 October 2026, 11,359 of them calls for competition). | Published Monday to Friday; notices are searchable the day their issue comes out. | Content of the Publications Office of the EU, reusable free of charge with acknowledgement of the source under the Commission's reuse policy (see TED's legal notice). |
| **Find a Tender** (`find-tender.service.gov.uk`, OCDS release packages) | UK above-threshold notices, and every notice under the Procurement Act 2023 (from 24 February 2025), including planned procurements and awards. About 400 to 500 releases a day across all stages. | Near real time: a notice is in the API as soon as it is published. | Open Government Licence v3.0. |
| **Contracts Finder** (`contractsfinder.service.gov.uk`, OCDS search) | Lower-value contracts in England under the older rules, and their awards. Most new procurements now go to Find a Tender, so expect only a handful of new tenders a day here. | Near real time. | Open Government Licence v3.0. |

**Attribution.** Contains public sector information licensed under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/) (Find a Tender and Contracts Finder). TED data: source TED, Publications Office of the European Union. This Actor is independent and not endorsed by either service; if you republish the data, keep these acknowledgements. A long wait requested by a service (Retry-After) is always respected: the source is skipped for that run with a free row rather than asked again early.

Each source is read newest first, a page at a time, with a short pause between pages. TED and the UK services are queried for the window you choose. When a tender has several versions in the window (a notice and its updates), only the newest one is used, by publication date and then notice number, and your filters are checked on that version, so a superseded deadline or value is never shown.

### FAQ

**Is this allowed?** Yes. All three sources are official open-data APIs published so that anyone can reuse procurement notices, under the licences above; the Actor uses only those APIs, needs no account and does not load the websites. Notices are about organisations spending public money. Contact points can name a person, so the Actor never reads contact names, e-mail addresses or phone numbers, and removes sentences carrying them from descriptions. The official notice behind each `url` has the buyer's contact details.

**Why does my English keyword miss TED tenders?** TED notices are written in the buyer's language. Use CPV codes, which are the same in every language, or add translations (`software`, `Software`, `logiciel`, `oprogramowanie`). On TED the keyword search covers the whole notice, including lot descriptions.

**What counts as `changed`?** A tender you already received whose deadline or value moved: a TED change notice, or a Find a Tender or Contracts Finder update. Other edits (new documents, clarifications) are not reported. Notices are matched across updates through `trackingId`. Some TED change notices name the notice they change only by its publication number; the Actor looks those up on TED (one extra search when needed, at no extra charge), so a corrected award or planned tender is not sent again as new.

**Why are no tenders ever reported removed?** Each run reads a recent window, and notices that age out of it still exist. The Actor remembers each tender while it is open for bids, so an update to an older tender still arrives as `changed`; once its deadline passes it is forgotten (monitoring never sends a closed tender). Notices without a deadline, such as contract awards, are remembered for 60 days after they were last seen.

**Why did the UK sources not run?** You set **Buyer countries** without `GB`. The UK services only list UK buyers, so they are left out (nothing is charged for them) and the status message says so; add `GB` to include them.

**Are winners included in contract awards?** Not in this version: award rows give the buyer, the contract and the awarded value. A winning supplier can be a sole trader, which is a person, so supplier names are left out. Open the official notice for the winner.

**Can the same tender appear twice?** A tender is one row per source. Some UK tenders under the older rules are published on both Find a Tender and Contracts Finder, so they can come as two rows, one per source.

**What about very large windows?** TED returns at most 15,000 notices per search, and a monitoring run reads up to 5,000 matching notices per source. A window that holds more is read newest first and the run says so in its status message; narrow the filters or shorten the window.

**Why is the first monitoring run bigger?** Nothing has been seen yet, so every notice in the window counts as new. Turn on **Start quietly** to skip that. If the window holds more matching notices than **maxNoticesPerSource** (1,000 by default), the rest are held back and arrive on the next runs, up to 1,000 at a time and still marked `new`, so a busy window can take a few runs to catch up. That is the backlog arriving, not repeats: each notice is sent once. Start quietly, a shorter window or narrower filters avoid it. Each saved task, and each combination of filters, keeps its own memory, and normal (non-monitoring) runs never touch it.

**Why did my run stop early, or skip a source?** The status message and a free `skipped` row say why, and nothing is charged for what was not read:

- *Spending limit:* a source starts only when your maximum cost per run still covers one source check and one notice ($0.004). Raise the limit, or the source is read on the next run.
- *Rate limit:* Find a Tender and Contracts Finder ask clients to slow down when they are called often, for example `HTTP 429` with `Retry-After: 120` when a run is started again a minute after the last one. The Actor never calls back early: the row says "the service asked to wait 120 s; it will be read next run". This is not an error and is not counted as a problem. Schedule monitors hourly or less often, and do not run two tasks on the UK sources at the same minute. Contracts Finder sometimes answers `HTTP 403` for a few minutes after too many requests; that shows as an error row and also clears by the next run.
- *No matches:* a normal run stops a source after 10 pages in a row (2,500 TED notices, or 1,000 UK records) with no notice matching your filters, and the status message says the source was not read in full. Loosen the filters or shorten the window. Monitoring runs read the whole window.
- *Safety limit:* if a run does a lot of work that produces nothing to return (a service answering very slowly, say), it stops after about $0.02 of compute and lists the sources it did not check, free. Run it again later. If one Apify account's runs keep producing nothing to charge, new runs from that account stop early for up to 24 hours, with a free row that says so; normal use never gets near this.

**Do monitors read the whole window every time?** TED, yes: it filters on its side, so that is cheap. The UK services have no filters on their side, so after a complete read a monitor reads them only from that read onwards, with a day of overlap for late notices.

**Are there input limits?** Up to 100 keywords, exclude keywords, CPV codes and countries each (keywords up to 200 characters). A longer list is reported in a free row and nothing is fetched, because cutting a list of exclusions would widen your search. For more, split the list across several tasks.

**Can I use it from code or an AI agent?** Yes: through the Apify API, the Python and JavaScript clients, or the Apify MCP server. Inputs and outputs are stable and documented above.

### Support

Open an issue on the Issues tab with your input (without any personal data); I aim to answer within a day.

# Changelog

This Actor's version history is a separate document: https://apify.com/rookdev/public-tenders-monitor/changelog.md

# Actor input Schema

## `sources` (type: `array`):

Official open-data APIs to read: EU Tenders Electronic Daily (TED: EU, EEA and partner countries), UK Find a Tender (above-threshold and Procurement Act 2023 notices) and UK Contracts Finder (English contracts, mostly lower value).

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

Keep notices that mention any of these words or phrases (whole words, any case). TED searches the full notice text, in the language it was written in, so add translations (software, Software, logiciel, oprogramowanie) or use CPV codes. On the UK sources the title, description and buyer are searched. At most 100, of up to 200 characters each.

## `excludeKeywords` (type: `array`):

Drop notices whose title, description or buyer mentions any of these words or phrases, for example cleaning or catering. At most 100.

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

Keep notices with a CPV code starting with any of these, for example 72 (IT services), 48 (software packages), 45 (construction works) or 79340000 (advertising and marketing). A full code with trailing zeros covers everything below it. At most 100.

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

ISO country codes of the buyer, for example DE, FR, PL or GB (UK, EL and three-letter codes also work). Applies to TED. The UK sources only list UK buyers, so they are left out unless GB is in this list. Leave empty for all countries.

## `stages` (type: `array`):

Tenders are open calls for bids (the default). Planned tenders are prior information and pipeline notices; contract awards say who won what and for how much.

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

Drop notices whose stated value is below this, converted to euros at approximate fixed rates (for example GBP 1 = EUR 1.15). Notices that state no value are kept. 0 keeps everything.

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

How far back each run looks. For a monitor, use at least 3 days, because a weekday schedule does not run at weekends and a shorter window misses what was published then; 7 days leaves room for missed runs. A longer window costs more on the first run only.

## `onlyNew` (type: `boolean`):

Turn on, save as a task and schedule it to get only notices you have not seen yet (new) and tenders whose deadline or value moved (changed). Monitoring returns and remembers only notices still open for bids (deadline not passed); after the first run, the UK sources are read from the last run onwards. The first run returns everything open in the window as new. Normal runs never touch this memory.

## `skipExistingOnFirstRun` (type: `boolean`):

Monitoring only: the first run records the notices in the window without returning or charging for them (you pay only the source checks), so you get only new ones from the second run on.

## `maxNoticesPerSource` (type: `integer`):

Stop after this many rows from each source, to cap costs. When monitoring, new notices go out oldest first and those over the cap are held back for the next run (the status message says how many). If more new notices arrive per run than the cap allows, raise it or narrow the filters: a notice that leaves the window before it is delivered is not sent.

## `stateStoreName` (type: `string`):

Key-value store that remembers which notices you have already seen (lowercase letters, digits and hyphens). Each saved task and each combination of filters keeps its own memory inside it, so the default works for most people.

## Actor input object example

```json
{
  "sources": [
    "ted",
    "uk-find-a-tender",
    "uk-contracts-finder"
  ],
  "keywords": [
    "software"
  ],
  "stages": [
    "tender"
  ],
  "minValue": 0,
  "publishedWithinDays": 7,
  "onlyNew": false,
  "skipExistingOnFirstRun": false,
  "maxNoticesPerSource": 20,
  "stateStoreName": "public-tenders-monitor-state"
}
```

# Actor output Schema

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

One row per tender or contract notice

# 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 = {
    "sources": [
        "ted",
        "uk-find-a-tender",
        "uk-contracts-finder"
    ],
    "keywords": [
        "software"
    ],
    "maxNoticesPerSource": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("rookdev/public-tenders-monitor").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 = {
    "sources": [
        "ted",
        "uk-find-a-tender",
        "uk-contracts-finder",
    ],
    "keywords": ["software"],
    "maxNoticesPerSource": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("rookdev/public-tenders-monitor").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "sources": [
    "ted",
    "uk-find-a-tender",
    "uk-contracts-finder"
  ],
  "keywords": [
    "software"
  ],
  "maxNoticesPerSource": 20
}' |
apify call rookdev/public-tenders-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rookdev/public-tenders-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bq3OyLycXOz3GQOBa/builds/Qw0Djn52mCLLaEBfx/openapi.json
