# Nordic Tenders Scraper - TED API (`teddythebuilder/nordic-public-tenders-monitor`) Actor

Scrape public tenders from Swedish, Norwegian, Danish, Finnish and Icelandic buyers via the official EU TED API. Get title, buyer org number, CPV, value, deadline, winners and links. Keyword/CPV filters, only-new mode. Export JSON/CSV or call via API.

- **URL**: https://apify.com/teddythebuilder/nordic-public-tenders-monitor.md
- **Developed by:** [Teddy Wasserman](https://apify.com/teddythebuilder) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.75 / 1,000 tender notices

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### What does Nordic Tenders Scraper do?

**Nordic Tenders Scraper is a TED API scraper for public procurement tenders from Sweden, Norway, Denmark, Finland and Iceland.** It returns every call for tender (upphandling, anbud, udbud, hankinta, útboð) and every contract award published by Nordic public buyers on TED (Tenders Electronic Daily), the EU's official procurement journal, as clean, typed JSON.

Typical uses: daily bid alerts for your CPV codes or keywords, competitor intelligence on who won which contract and for how much, and lead lists of municipalities, regions and state agencies that buy what you sell, complete with their organisation numbers.

The data comes from the **official source**, the EU Publications Office TED API v3. There is no HTML scraping, no login, no API key and no proxy, so runs are fast (a 20-notice run takes a few seconds) and the output schema is stable.

### Why use Nordic Tenders Scraper?

- **Official, stable source.** Notices come straight from the TED API published by the EU Publications Office. No fragile HTML parsing, no captchas and no blocked IPs.
- **Nordic focus in one click.** The countries are preselected. No need to learn TED's expert query syntax or buyer-country codes.
- **Only-new mode for alerts.** Turn on `onlyNew` and schedule the Actor. Every run outputs only notices you haven't received before, tracked per saved search (`monitorId`). No duplicates in your inbox, Slack or CRM.
- **Buyer organisation numbers.** Swedish org.nr, Norwegian organisasjonsnummer, Danish CVR and Finnish Y-tunnus where TED has them, with a fallback that finds the Swedish org.nr in the notice text. Join tenders straight to company registers and your CRM.
- **Contract winners with IDs.** Award notices include every winning company with its national company ID, country and SME/large size, so a framework agreement with five suppliers lists all five.
- **Deadlines you can act on.** `tenderDeadline` and `daysToDeadline` are computed for every call for tender, and `onlyOpenForBids` drops expired ones.
- **Your language.** Titles and descriptions come in English when the notice has an English version, otherwise in the original language. You can prefer Swedish, Norwegian, Danish or Finnish instead.
- **Privacy built in.** Sole traders who win contracts are identified by personal ID numbers, and their names and identifiers are redacted.

### What data can you extract?

Each dataset item is one TED notice.

| Field | Example | Description |
|---|---|---|
| `noticeId` | `681365-2026` | TED publication number |
| `title` | `Sweden – IT services: consulting, software development…` | Notice title in your preferred language |
| `description` | `NSVA bjuder in intresserade leverantörer…` | Procedure description (up to 2,000 characters) |
| `formType` | `competition` | competition, result, planning, change, dir-awa-pre or cont-modif |
| `noticeType` / `procedureType` | `cn-standard` / `open` | eForms notice subtype and procedure |
| `contractNature` | `services` | services, supplies or works |
| `buyerName` | `Nordvästra Skånes Vatten och Avlopp AB` | Contracting authority |
| `buyerOrgNumber` | `556765-3786` | National organisation number of the buyer |
| `buyerCountry` / `buyerCountryIso2` | `SWE` / `SE` | Buyer country |
| `buyerCity` / `buyerWebsite` | `Helsingborg` / `https://nsva.se/` | Buyer location and website |
| `mainCpv` / `cpvCodes` | `72000000` | Main and all CPV classification codes |
| `placeOfPerformanceNuts` | `["SE224"]` | NUTS region codes |
| `estimatedValue` / `currency` | `10000000` / `SEK` | Estimated contract value |
| `isFrameworkAgreement` | `false` | Whether it is a framework agreement |
| `publicationDate` | `2026-10-02` | Date published on TED |
| `tenderDeadline` / `daysToDeadline` | `2026-11-05` / `32` | Bid deadline and days left |
| `winners` | `[{"name": "Hifab AB", "identifier": "556125-7881", …}]` | Winning companies (award notices) |
| `awardedValue` | `4500000` | Sum of awarded lot values, where published |
| `tedUrl` / `pdfUrl` | TED links | Human-readable notice and PDF |
| `procurementDocumentsUrl` / `submissionUrl` | e-tendering links | Where to download documents and submit a bid |
| `isNew` / `scrapedAt` | `true` | Monitor-mode flag and run timestamp |

### How to use Nordic Tenders Scraper (step by step)

1. Open the Actor and click **Try for free**. The default input (Nordic buyers, keyword "software", calls for tender from the last 7 days, 20 results) runs in seconds.
2. Choose **Buyer countries**. Sweden, Norway, Denmark and Finland are preselected; Iceland is optional.
3. Add **keywords** (matched in any language, e.g. `software`, `programvara`, `ohjelmisto`) and/or **CPV codes** (`72` = IT services, `45` = construction works, `48` = software packages, `79` = business services, `33` = medical equipment). Short codes are expanded to divisions automatically.
4. Pick **Notice types**: *Calls for tender* for bid opportunities, *Contract awards* for who won, or both.
5. For alerts, open **Advanced filters and monitor mode**, switch on **Only new since last run**, give the search a `monitorId`, and add a **Schedule** in Apify Console (for example daily at 07:00).
6. Download the results as JSON, CSV or Excel, or connect them to Google Sheets, Slack, Zapier, Make or your own API client.

### Input example

Daily IT and software tender alerts for Sweden and Norway, only tenders still open for bids:

```json
{
  "countries": ["SWE", "NOR"],
  "cpvCodes": ["72", "48"],
  "noticeTypes": ["competition"],
  "publishedWithinDays": 3,
  "onlyOpenForBids": true,
  "onlyNew": true,
  "monitorId": "it-se-no",
  "maxResults": 200
}
```

Contract awards in Finland and Sweden over the last 30 days, with estimated value of at least 1,000,000 (in the notice currency):

```json
{
  "countries": ["FIN", "SWE"],
  "noticeTypes": ["result"],
  "publishedWithinDays": 30,
  "minEstimatedValue": 1000000,
  "maxResults": 500
}
```

### Output example

Two real items from 2 October 2026 (descriptions shortened). A call for tender:

```json
{
  "noticeId": "681365-2026",
  "title": "Sweden – IT services: consulting, software development, Internet and support – Plattform för geografisk information VA",
  "description": "Nordvästra Skånes Vatten och Avlopp AB (NSVA), 556765-3786, bjuder in intresserade leverantörer till att inkomma med anbudsansökan avseende upphandling av Plattform för geografisk ...",
  "formType": "competition",
  "noticeType": "cn-standard",
  "procedureType": "neg-w-call",
  "contractNature": "services",
  "buyerName": "Nordvästra Skånes Vatten och Avlopp AB",
  "buyerOrgNumber": "556765-3786",
  "buyerCountry": "SWE",
  "buyerCountryIso2": "SE",
  "buyerCity": "Helsingborg",
  "buyerWebsite": "https://nsva.se/",
  "mainCpv": "72000000",
  "cpvCodes": ["72000000", "48000000", "48300000", "72212326", "72250000"],
  "placeOfPerformanceNuts": ["SE224"],
  "estimatedValue": 10000000.0,
  "currency": "SEK",
  "isFrameworkAgreement": false,
  "publicationDate": "2026-10-02",
  "tenderDeadline": "2026-11-05",
  "daysToDeadline": 32,
  "winners": [],
  "awardedValue": null,
  "tedUrl": "https://ted.europa.eu/en/notice/-/detail/681365-2026",
  "pdfUrl": "https://ted.europa.eu/en/notice/681365-2026/pdf",
  "procurementDocumentsUrl": "https://annonser.clira.io/upphandling/1a2a616a-cec2-43a7-8faa-ccce3bca9848",
  "submissionUrl": "https://annonser.clira.io/upphandling/1a2a616a-cec2-43a7-8faa-ccce3bca9848",
  "source": "TED API v3 (EU Publications Office)",
  "isNew": false,
  "scrapedAt": "2026-10-04T09:52:51+00:00"
}
```

A contract award (framework agreement with five winners):

```json
{
  "noticeId": "681442-2026",
  "title": "Sweden – Architectural, construction, engineering and inspection services – Tekniska konsulttjänster avseende Huvudbesiktningsman och besiktningstjänster",
  "formType": "result",
  "noticeType": "can-standard",
  "procedureType": "open",
  "contractNature": "services",
  "buyerName": "MKB Fastighets Aktiebolag",
  "buyerOrgNumber": "556049-1432",
  "buyerCountry": "SWE",
  "buyerCity": "Malmö",
  "mainCpv": "71000000",
  "estimatedValue": 28000000.0,
  "currency": "SEK",
  "isFrameworkAgreement": true,
  "publicationDate": "2026-10-02",
  "winners": [
    {"name": "Hifab AB", "identifier": "556125-7881", "country": "SWE", "size": "sme"},
    {"name": "AFRY Infrastructure AB", "identifier": "556185-2103", "country": "SWE", "size": "large"},
    {"name": "Åkermans Ingenjörsbyrå AB", "identifier": "556643-4436", "country": "SWE", "size": "sme"},
    {"name": "Byggadministration Harald Olsson Aktiebolag", "identifier": "556122-9278", "country": "SWE", "size": "sme"},
    {"name": "Projektstyrning syd AB", "identifier": "559260-2261", "country": "SWE", "size": "sme"}
  ],
  "tedUrl": "https://ted.europa.eu/en/notice/-/detail/681442-2026"
}
```

Every field is always present (missing values are `null`), so the data loads cleanly into spreadsheets, databases and BI tools. Export as JSON, CSV, Excel, XML or HTML from the dataset tab or the API.

### How much does it cost to scrape Nordic tenders?

The Actor uses pay-per-event pricing. You pay only for notices delivered, plus a tiny start fee.

| Event | Price | Bronze (−15%) | Silver (−30%) | Gold, Platinum, Diamond (−45%) |
|---|---|---|---|---|
| Run start | $0.0005 | $0.000425 | $0.00035 | $0.000275 |
| Tender notice | $0.005 ($5 per 1,000) | $0.00425 | $0.0035 | $0.00275 |

Discounts apply automatically according to your Apify subscription tier. Worked examples at the base price:

- **One-off market scan:** all 1,000 Nordic IT tenders from the last quarter ≈ 1,000 × $0.005 + $0.0005 ≈ **$5.00**.
- **Daily alert in monitor mode:** a typical CPV search yields 5–15 new notices a day, so about 300 notices a month ≈ **$1.50/month** plus 30 × $0.0005 in start fees ($0.015).
- **Quick test:** the default 20-notice run costs about **$0.10**, which is within the free $5 monthly credit of the Apify free plan.

Use `maxResults` to cap spending per run. Platform usage (compute) is included in the event prices.

### Use cases

- **Bid managers and sales teams.** Get a morning list of new Nordic tenders that match your CPV codes, with deadlines and submission links, before your competitors find them.
- **Competitive intelligence.** Pull contract awards to see which suppliers win which public buyers, at what value and how often, including SME or large size.
- **Business development and market sizing.** Find which municipalities, regions and agencies buy your category, ranked by volume and value, then join on `buyerOrgNumber` to firmographics from [Nordic Company Registry](https://apify.com/teddythebuilder/nordic-company-registry).
- **Consultants and tender-writing agencies.** Run one saved search per client with separate `monitorId`s and deliver weekly digests.
- **Analysts and researchers.** Build procurement datasets by country, CPV, procedure type and framework agreements for spend analysis.
- **AI agents.** Give an agent a compact, flat record per tender to summarise, score for fit or draft a go/no-go note.

### Use with AI agents, MCP and the API

The Actor works through the Apify API, the Apify MCP server and the official clients. Input is small and output is flat JSON, so agents can call it cheaply.

Run it and get the items with one HTTP call:

```bash
curl -X POST "https://api.apify.com/v2/acts/teddythebuilder~nordic-public-tenders-monitor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"countries": ["SWE"], "keywords": ["cyber security"], "publishedWithinDays": 7, "maxResults": 20}'
```

Python with `apify-client`:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("teddythebuilder/nordic-public-tenders-monitor").call(run_input={
    "countries": ["NOR", "DNK"],
    "cpvCodes": ["45"],
    "noticeTypes": ["competition"],
    "onlyOpenForBids": True,
    "maxResults": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["publicationDate"], item["buyerName"], item["title"], item["tenderDeadline"])
```

For MCP clients such as Claude Desktop or Cursor, add the Apify MCP server and enable `teddythebuilder/nordic-public-tenders-monitor` as a tool. The agent can then search Nordic tenders in natural language ("find open Norwegian construction tenders over 10 MNOK").

### Integrations

- **Google Sheets:** append each run's notices to a sheet for a shared tender pipeline.
- **Slack, Microsoft Teams and email:** send new tenders to a channel with a webhook or Apify's integrations after each scheduled run.
- **Zapier and Make:** trigger on "Actor run succeeded", then create CRM deals (HubSpot, Pipedrive, Salesforce) or Trello/Asana cards.
- **n8n:** use the Apify node to run the Actor on a cron and route notices by CPV code.
- **Webhooks:** POST the run result to your own endpoint for custom processing.

### Data source and legality

- **Source:** TED API v3 (`api.ted.europa.eu`) operated by the Publications Office of the European Union. Below-threshold national tenders that are not published on TED are not included.
- **Licence:** TED content may be reused, including commercially, under the Commission's reuse policy (Decision 2011/833/EU), with attribution to the source.
- **Personal data:** the Actor outputs organisation-level procurement data. Contact persons and their e-mails or phone numbers are not output. When a winner is a sole trader identified by a personal ID number, the name and identifier are replaced with `[sole trader - redacted]`.
- The Actor calls only the public API, respects its rate limits with backoff, and does not scrape any website.

### FAQ

#### Which tenders are covered?

All notices on TED whose buyer is in Sweden, Norway, Denmark, Finland or Iceland: calls for tender, contract awards, prior information notices, corrigenda, direct-award pre-announcements and contract modifications. TED covers tenders above the EU thresholds and many voluntary below-threshold publications. Purely national below-threshold notices (for example only on Visma Opic, Mercell or Doffin) may be missing.

#### How fresh is the data?

TED publishes new notices every working day (Tuesday to Saturday). A daily schedule in monitor mode picks up each day's notices within hours of publication.

#### How does "only new since last run" work?

The Actor stores the IDs it has delivered for each `monitorId` in a key-value store in your account. The next run with the same `monitorId` skips those IDs. The first run outputs everything that matches and saves the baseline. Use different `monitorId`s for different searches.

#### Why did I get zero results?

Your filters are probably too narrow: a rare keyword, a CPV code outside your countries' activity, or a short `publishedWithinDays`. Try widening the date range or removing keywords. In monitor mode, zero results simply means nothing new was published since the last run, and you are not charged for notices.

#### Can I search in Swedish, Norwegian, Danish or Finnish?

Yes. Keywords are matched against the full notice text in all languages. Combine terms, for example `["programvara", "software", "ohjelmisto"]`; a notice matches if any keyword appears.

#### Does it work on the Apify free plan?

Yes. The free plan's monthly credit covers hundreds of notices. Set `maxResults` to control spending per run.

#### Can you add a field or another country?

Yes, please open an issue. For all EU countries, a broader EU tenders actor is in preparation. If the Actor saves you time, a short review on the Store page helps other buyers find it.

### Related actors

- [Nordic Company Registry](https://apify.com/teddythebuilder/nordic-company-registry): look up buyers and winners by organisation number in the Swedish, Norwegian and Finnish company registers, with industry codes and new-company lists.
- [Swedish Jobs Scraper](https://apify.com/teddythebuilder/swedish-jobs-monitor): Platsbanken job ads and "companies hiring now" lists from Arbetsförmedlingen's official API.
- [Career Site Jobs API](https://apify.com/teddythebuilder/career-site-jobs-api): jobs straight from company career sites on Greenhouse, Lever, Ashby, Workable, Recruitee and Teamtailor in one schema, with new/removed-job tracking.
- [Tech Stack Detector](https://apify.com/teddythebuilder/tech-stack-detector): bulk-detect the CMS, e-commerce platform, analytics, CDN and email provider behind any list of company domains.

### Changelog and support

- **2026-10-04 (1.1):** winner identifiers are now paired correctly. TED lists identifiers for all tenderers, so each winner's org number is matched through the tenderer list. Award notices now list every winner (framework agreements with several suppliers). Faster default input (20 results). New title.
- **2026-10-04 (1.0):** first public release.

Found a problem or need a field? Open an issue on the **Issues** tab. We reply within 24 hours.

# Actor input Schema

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

Countries of the contracting authority (ISO 3166-1 alpha-3). Leave empty for all five Nordic countries.

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

Optional. A notice matches if ANY keyword/phrase appears in its text (any language). Example: "cyber security", "programvara", "bygg".

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

competition = open calls for tender (bid opportunities); result = contract awards (who won, for how much); planning = prior information notices. Empty = all.

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

Only notices published in the last N days.

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

Maximum number of notices to output (each is one billable result). Example: 20 for a quick test, 1000 for a full export.

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

Optional CPV codes (8 digits, or a 2-4 digit division/group which is padded with zeros, e.g. 72 = IT services, 45 = construction, 48 = software packages).

## `onlyOpenForBids` (type: `boolean`):

Drop notices whose tender deadline has passed.

## `minEstimatedValue` (type: `integer`):

Optional. Drop notices with a lower (or missing) estimated value. Value is in the notice's own currency (SEK/NOK/DKK/EUR/ISK).

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

Remember which notices you already received (per monitor ID) and output only new ones. Schedule the Actor daily for tender alerts. The first run outputs everything that matches and stores the baseline.

## `monitorId` (type: `string`):

Name of this saved search for monitor mode. Use different IDs for different searches.

## `preferredLanguage` (type: `string`):

Titles/descriptions are returned in this language when the notice has it, otherwise the original language.

## Actor input object example

```json
{
  "countries": [
    "SWE",
    "NOR",
    "DNK",
    "FIN"
  ],
  "keywords": [
    "software"
  ],
  "noticeTypes": [
    "competition"
  ],
  "publishedWithinDays": 7,
  "maxResults": 20,
  "onlyOpenForBids": false,
  "onlyNew": false,
  "monitorId": "default",
  "preferredLanguage": "eng"
}
```

# Actor output Schema

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

No description

# 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 = {
    "countries": [
        "SWE",
        "NOR",
        "DNK",
        "FIN"
    ],
    "keywords": [
        "software"
    ],
    "noticeTypes": [
        "competition"
    ],
    "publishedWithinDays": 7,
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("teddythebuilder/nordic-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 = {
    "countries": [
        "SWE",
        "NOR",
        "DNK",
        "FIN",
    ],
    "keywords": ["software"],
    "noticeTypes": ["competition"],
    "publishedWithinDays": 7,
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("teddythebuilder/nordic-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 '{
  "countries": [
    "SWE",
    "NOR",
    "DNK",
    "FIN"
  ],
  "keywords": [
    "software"
  ],
  "noticeTypes": [
    "competition"
  ],
  "publishedWithinDays": 7,
  "maxResults": 20
}' |
apify call teddythebuilder/nordic-public-tenders-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,teddythebuilder/nordic-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/hdg0ipS62xSRt8Cra/builds/pakECWBFQollEE42U/openapi.json
