# DOFFIN Scraper — Norwegian Government Tenders (`studio-amba/doffin-scraper`) Actor

Search and extract Norwegian public procurement tenders from DOFFIN, Norway's official government tender database. Filter by keyword, status, CPV code, location, or date range. Returns tender details, buyer info, deadlines, and CPV codes. No API key, no cookies, no login required.

- **URL**: https://apify.com/studio-amba/doffin-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 5 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 result scrapeds

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

## Norwegian Government Tenders Scraper — DOFFIN

Search and extract Norwegian public procurement tenders from DOFFIN (Database for offentlige innkjop), Norway's official national tender database. All Norwegian public authorities are legally required to publish procurement notices above NOK 1.3 million on DOFFIN, making it the single most complete source for Norwegian government contract opportunities.

This actor reads tender data straight from doffin.no's own search backend, the same source that powers the official website. Filter by keyword, tender status, CPV code, location, or publication date range. Returns full tender details including buyer information, deadlines, CPV classification codes, estimated values, and document links. No API key, no cookies, no login required.

### How to scrape DOFFIN data

DOFFIN is operated by DFO (Direktoratet for forvaltning og okonomistyring) on behalf of the Norwegian Ministry of Trade, Industry and Fisheries. This actor queries the same data source as the doffin.no search page — no registration, account, or API key needed. Enter your search keywords, pick optional filters, and run.

#### Who benefits from this data?

- **Government contractors** — Monitor new procurement opportunities daily across all Norwegian municipalities, counties, and central government agencies. Never miss a relevant tender in your industry.
- **Nordic market researchers** — Analyze public spending patterns, procurement volumes, and contract award trends across the Norwegian public sector.
- **B2B sales teams** — Identify which Norwegian government bodies are buying what you sell. Build targeted prospect lists for the NOK 600+ billion annual public procurement market.
- **Consultancies and advisory firms** — Track procurement activity by sector, region, or buyer to advise clients on market entry and bidding strategy.
- **Compliance and legal teams** — Monitor competitor contract awards and verify procurement procedural compliance.
- **EU/EEA market intelligence** — DOFFIN includes all notices that Norway is required to publish on TED (Tenders Electronic Daily) under EEA rules.

#### Search by keyword

Enter any keyword to find relevant tenders. The API searches across tender titles, descriptions, and buyer names. Use Norwegian for best results: "IT-tjenester" (IT services), "bygg" (construction), "renhold" (cleaning), "programvare" (software), "konsulent" (consulting), "helse" (health).

#### Filter by status

- **ACTIVE** — Open tenders you can bid on right now
- **EXPIRED** — Deadline has passed (useful for market research)
- **AWARDED** — Contract has been awarded (competitor intelligence)
- **CANCELLED** — Procurement was cancelled

#### Filter by CPV code

CPV (Common Procurement Vocabulary) codes classify what is being procured. Common codes for Norwegian tenders:

- 72000000 — IT services
- 45000000 — Construction work
- 71000000 — Architectural, engineering, and planning services
- 79000000 — Business services
- 33000000 — Medical equipment and pharmaceuticals
- 60000000 — Transport services

#### Filter by date

Use the `publishedAfter` and `publishedBefore` date filters to monitor new publications or research historical procurement patterns.

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQuery` | String | `IT-tjenester` | Keywords to search in tender titles, descriptions, and buyer names |
| `tenderStatus` | Enum | `all` | Filter: `all`, `ACTIVE`, `EXPIRED`, `AWARDED`, or `CANCELLED` |
| `cpvCode` | String | — | CPV classification code (e.g., 72000000 for IT services) |
| `location` | String | — | NUTS code (e.g. NO081 Oslo, NO0A1 Rogaland) or a county or city name (Oslo, Bergen, Trøndelag); comma-separated for several |
| `publishedAfter` | String | — | Only tenders published on or after this date (YYYY-MM-DD) |
| `publishedBefore` | String | — | Only tenders published on or before this date (YYYY-MM-DD) |
| `maxResults` | Integer | `100` | Maximum number of tenders to return (1-10,000) |
| `proxyConfiguration` | Object | NO residential | Apify proxy settings |

### What data does this scraper extract?

| Field | Type | Description |
|-------|------|-------------|
| `title` | String | Tender title / announcement heading |
| `referenceNumber` | String | DOFFIN reference number (e.g., 2026-100282) |
| `organization` | String | Contracting authority / buyer name |
| `status` | String | ACTIVE, EXPIRED, or AWARDED |
| `publicationDate` | String | Date the tender was published |
| `deadline` | String | Bid submission deadline (if applicable) |
| `estimatedValue` | String | Estimated contract value |
| `currency` | String | Currency code (typically NOK) |
| `category` | String | Notice type (contract notice, award notice, etc.) |
| `cpvCodes` | Array | CPV classification codes with descriptions |
| `region` | String | Geographic region in Norway |
| `description` | String | Full tender description |
| `contactInfo` | Object | Contact name, email, phone, URL (when available) |
| `url` | String | Direct link to the tender on doffin.no |
| `scrapedAt` | String | ISO timestamp of when the data was scraped |

### Example output

```json
{
    "title": "Anskaffelse av IT-driftstjenester",
    "referenceNumber": "2026-103456",
    "organization": "Oslo kommune",
    "status": "ACTIVE",
    "publicationDate": "2026-05-20",
    "deadline": "2026-06-30T12:00:00Z",
    "estimatedValue": "15000000",
    "currency": "NOK",
    "category": "Contract notice",
    "cpvCodes": [
        {
            "code": "72000000",
            "description": "IT services: consulting, software development, Internet and support"
        },
        {
            "code": "72500000",
            "description": "Computer-related services"
        }
    ],
    "region": "Oslo",
    "description": "Oslo kommune inviterer til konkurranse om anskaffelse av IT-driftstjenester...",
    "contactInfo": {
        "name": "Innkjopsavdelingen",
        "email": "innkjop@oslo.kommune.no"
    },
    "url": "https://www.doffin.no/notice/2026-103456",
    "scrapedAt": "2026-05-27T14:30:00.000Z"
}
```

### Tips for best results

- **Daily monitoring**: Run on a schedule to catch new tenders within hours of publication. Set `publishedAfter` to yesterday's date for fresh opportunities only.
- **CPV code targeting**: After initial broad searches, note the CPV codes most relevant to your business and use them as filters for precise results.
- **Competitor intelligence**: Search for competitor names or specific service descriptions to track what contracts they are pursuing or winning.
- **Combine with TED**: For full EEA procurement coverage, pair this actor with EU TED data. Larger Norwegian tenders above EU thresholds appear on both DOFFIN and TED.

### How much does it cost to run?

The DOFFIN data source is free. Your only cost is Apify compute time and proxy usage.

| Search size | Estimated time | Estimated cost |
|-------------|---------------|----------------|
| 20 tenders | ~30 seconds | ~$0.01 |
| 100 tenders | ~2 minutes | ~$0.05 |
| 500 tenders | ~10 minutes | ~$0.15 |
| 1,000 tenders | ~20 minutes | ~$0.30 |

Each tender requires one additional API call to fetch full details (CPV codes, contact info), which adds to run time.

### Use as an API

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("studio-amba/doffin-scraper").call(run_input={
    "searchQuery": "programvare",
    "tenderStatus": "ACTIVE",
    "maxResults": 50,
})

for tender in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{tender['title']} | {tender['organization']} | Deadline: {tender['deadline']}")
```

### Limitations

- **Deadline may be empty**: Not all notice types have a submission deadline (e.g., prior information notices, voluntary ex-ante transparency notices).
- **Estimated value often absent**: Many tenders do not disclose the estimated contract value in the published notice.
- **Detail fetching adds time**: Each tender gets an individual API call for full details. Set `maxResults` accordingly if you need fast runs.
- **Norwegian text**: Most tender content is in Norwegian. Keyword searches work best with Norwegian terms.

### Other European procurement scrapers

Check the [Studio AMBA actor catalog](https://apify.com/studio-amba) for more European data scrapers, including Dutch (TenderNed), Belgian, and other Nordic procurement portals.

### Your feedback

Found a bug or want a feature? Open an issue on the [Issues tab](https://console.apify.com/actors/studio-amba~doffin-scraper/issues).

# Actor input Schema

## `searchQuery` (type: `string`):

Search tenders by keyword (matched against title, description, and buyer name). Use Norwegian for best results. Examples: 'IT-tjenester', 'bygg', 'renhold', 'programvare', 'konsulent'.

## `tenderStatus` (type: `string`):

Filter by tender status. ACTIVE = open for bids, EXPIRED = deadline passed, AWARDED = contract awarded.

## `cpvCode` (type: `string`):

Filter by CPV (Common Procurement Vocabulary) code. Examples: 72000000 (IT services), 45000000 (construction), 71000000 (architectural services). Leave empty for all categories.

## `location` (type: `string`):

Filter by place: a NUTS code ('NO081' Oslo, 'NO084' Akershus, 'NO0A1' Rogaland, 'NO0A2' Vestland) or a Norwegian county or city name ('Oslo', 'Bergen', 'Trøndelag', 'Tromsø'). Several, comma-separated, match any of them. Leave empty for all of Norway.

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

Only tenders published on or after this date. Format: YYYY-MM-DD.

## `publishedBefore` (type: `string`):

Only tenders published on or before this date. Format: YYYY-MM-DD.

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

Maximum number of tenders to return.

## `proxyConfiguration` (type: `object`):

Apify proxy configuration. Norwegian proxies recommended for best reliability.

## Actor input object example

```json
{
  "searchQuery": "IT-tjenester",
  "tenderStatus": "all",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NO"
  }
}
```

# 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 = {
    "searchQuery": "IT-tjenester",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "NO"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/doffin-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "IT-tjenester",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "NO",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/doffin-scraper").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 '{
  "searchQuery": "IT-tjenester",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NO"
  }
}' |
apify call studio-amba/doffin-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/doffin-scraper"
        }
    }
}
```

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/ACcHUYDeGq2cSwANF/builds/UTpRHIXWkXuhEfIhE/openapi.json
