# Jobindex Scraper (`solidcode/jobindex-dk-scraper`) Actor

\[💰 $1.6 / 1K] Extract job listings from Jobindex.dk and IT-Jobbank.dk, Denmark's largest job boards. Search by keyword, location, category, and employment type to get titles, companies, salaries, descriptions, contacts, and apply links.

- **URL**: https://apify.com/solidcode/jobindex-dk-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 results

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

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Jobindex Scraper

Pull live job listings from Jobindex.dk and IT-Jobbank.dk — Denmark's two largest job boards — with company names, salaries when listed, full descriptions, application deadlines, and contact details extracted from every ad. Search by keyword, narrow to a Danish region or any of 89 job categories, then export a clean, structured row per vacancy. Built for Danish recruiters, labor-market analysts, and relocation services who need fresh, structured vacancy data without copying listings by hand.

### Why This Scraper?

- **Both Jobindex.dk and IT-Jobbank.dk in one actor** — flip a single dropdown to switch between Denmark's all-sector board and its dedicated IT/tech portal; the same clean schema comes out of both.
- **89 job categories, mapped to plain English** — filter to "Sygeplejerske" (Nurse), "Systemudvikling" (Software development), "Jura" (Law) and 86 more, each shown with its English translation so you never guess a Danish slug.
- **11 employment types plus on-site / remote / hybrid filters** — target permanent, temporary, student, graduate, internship, flex-job, freelance and more, then layer in workplace and full-time / part-time on top.
- **Full descriptions in plain text AND HTML** — pick "Text", "HTML", or "Both" and get the entire ad body, not a truncated snippet, with original formatting preserved when you need it.
- **Contact details pulled from every ad** — emails, phone numbers, and application URLs are regex-extracted from each description into ready-to-use arrays for sourcing and outreach.
- **Company ratings, logos, and profile links** — every row carries the employer's Jobindex rating score and rating count when published, plus logo and company-profile URL.
- **Direct apply links on every job** — the external application URL and canonical job-page URL are captured per vacancy, so candidates and ATS imports go straight to the source.
- **All 5 Danish regions and ~98 municipalities** — type "København", "Aarhus", "Fyn", or "Zealand" and it resolves to the right area; English names and common spellings are matched automatically.
- **Up to ~1,000 jobs per keyword on Jobindex (1,250 on IT-Jobbank)** — bounded, predictable depth with full last-page retention, so a deep pull never trims mid-page or runs away on cost; split a broad keyword into narrower ones to reach further.

### Use Cases

**Recruitment & Sourcing**

- Build candidate-facing job feeds for a niche or region
- Pull every open nursing, engineering, or IT role across Denmark into one sheet
- Track which companies are hiring for a given title this week
- Power an internal ATS or job-aggregator import

**Labor-Market Research**

- Measure hiring demand by category, region, and employment type
- Track remote vs. on-site vs. hybrid posting trends over time
- Benchmark salary mentions across sectors where pay is published
- Quantify how many roles a sector posts per week

**Lead Generation**

- Build employer contact lists from extracted emails and phone numbers
- Identify companies actively hiring as a sales signal
- Target firms by category, region, or rating score
- Reach hiring managers via application URLs and company profiles

**Relocation & Career Services**

- Surface English-friendly and remote roles for international candidates
- Map opportunities by Danish municipality for relocating clients
- Filter to graduate, internship, and student jobs for early-career advice
- Compare IT vacancy volume on IT-Jobbank against the wider Jobindex board

**Competitive Intelligence**

- Watch a competitor's open roles to infer growth and team direction
- Track headcount signals by counting active postings per company
- Monitor which categories rivals are expanding into

### Getting Started

#### Search by Keyword

The simplest run — one keyword, default board:

```json
{
    "searchQueries": ["software engineer"],
    "maxResults": 50
}
```

#### Filter by Region and Category

```json
{
    "searchQueries": ["sygeplejerske"],
    "location": "Region Hovedstaden",
    "categories": ["17"],
    "datePosted": "7",
    "maxResults": 200
}
```

#### IT-Jobbank, Remote Roles

```json
{
    "searchQueries": ["backend developer", "data engineer"],
    "portal": "it-jobbank.dk",
    "workplace": "remote",
    "employmentType": "permanent",
    "maxResults": 300
}
```

#### Paste Direct URLs

Paste any Jobindex or IT-Jobbank search or job-page URL — filters baked into the URL are honored as-is:

```json
{
    "startUrls": [
        { "url": "https://www.jobindex.dk/jobsoegning?q=projektleder" }
    ],
    "includeJobDetails": true,
    "descriptionFormat": "both"
}
```

#### Full-Featured Example

```json
{
    "searchQueries": ["marketing manager"],
    "portal": "jobindex.dk",
    "location": "Aarhus",
    "categories": ["55", "58"],
    "employmentType": "permanent",
    "workHours": "fulltime",
    "workplace": "hybrid",
    "datePosted": "14",
    "maxResults": 500,
    "includeJobDetails": true,
    "descriptionFormat": "both"
}
```

### Input Reference

#### What to Search

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQueries` | string\[] | `["software engineer"]` | Job titles or keywords. Each runs a separate search; results are merged and de-duplicated. Up to 50 keywords. |
| `startUrls` | URL\[] | `[]` | Paste full Jobindex.dk / IT-Jobbank.dk search or job-page URLs. Filters in the URL are kept exactly; pagination is automatic. Up to 100. |
| `portal` | select | `Jobindex.dk` | Which board to search: Jobindex.dk (all sectors) or IT-Jobbank.dk (IT & tech). |

#### Filters & Limits

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `location` | string | `""` | A Danish region or municipality (e.g. "København", "Aarhus", "Fyn"). Empty searches all of Denmark. |
| `categories` | select\[] | `[]` | One or more of 89 Jobindex job categories. Empty includes every category. |
| `employmentType` | select | `Any` | Permanent, temporary, student, apprentice, graduate, internship, flex-job, volunteer, youth, freelance, or hourly. |
| `workplace` | select | `Any` | On-site, remote, or hybrid. |
| `workHours` | select | `Any` | Full-time or part-time. |
| `datePosted` | select | `Any time` | Only jobs posted within the last 1, 3, 7, 14, or 30 days. |
| `maxResults` | integer | `50` | Target jobs per keyword (1–2,000). Note: a single search returns at most ~1,000 jobs on Jobindex (1,250 on IT-Jobbank) — split broad keywords or add filters to go deeper (see Tips). The last page is kept in full, so the count can slightly overshoot. |

#### Advanced

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `includeJobDetails` | boolean | `true` | Fetch each job's detail page for the full description, salary, deadline, and contacts. Off = faster, lighter scan. |
| `descriptionFormat` | select | `Text` | Return the description as plain text, HTML, or both. |

### Output

Each job posting is one flat row in the dataset. Here's a representative result with full details enabled:

```json
{
    "title": "Senior Backend Developer",
    "company": "Nordic Software A/S",
    "location": "København K, 1050",
    "city": "København",
    "zipCode": "1050",
    "region": "Region Hovedstaden",
    "employmentType": "Fastansættelse",
    "workplace": "Hjemmearbejde muligt",
    "workHours": "Fuldtid",
    "isRemote": true,
    "category": null,
    "salaryText": "45.000 kr.",
    "salaryMin": 45000,
    "salaryMax": null,
    "salaryPeriod": "month",
    "postedDate": "2026-06-08",
    "deadline": "2026-06-30",
    "descriptionSnippet": "Vi søger en erfaren backend-udvikler til vores team...",
    "description": "Vi søger en erfaren backend-udvikler til vores voksende team i hjertet af København...",
    "descriptionHtml": "<div class=\"jobtext-jobad__body\"><p>Vi søger en erfaren backend-udvikler...</p></div>",
    "extractedEmails": ["jobs@nordicsoftware.dk"],
    "extractedPhones": ["+45 33 12 34 56"],
    "extractedUrls": ["https://nordicsoftware.dk/karriere"],
    "applyUrl": "https://nordicsoftware.dk/apply/12345",
    "companyUrl": "https://www.jobindex.dk/virksomhed/nordic-software",
    "companyLogo": "https://www.jobindex.dk/img/logo/nordic.png",
    "companyRatingScore": 4.3,
    "companyRatingCount": 87,
    "jobUrl": "https://www.jobindex.dk/vis-job/h1234567",
    "jobId": "h1234567",
    "portal": "jobindex.dk",
    "searchQuery": "software engineer",
    "scrapedAt": "2026-06-12T14:30:00Z"
}
```

#### Core Fields

| Field | Type | Description |
|-------|------|-------------|
| `title` | string | Job title |
| `company` | string | Hiring company / employer name |
| `category` | string | Jobindex category the job is filed under, when a category filter is applied |
| `jobUrl` | string | Canonical Jobindex / IT-Jobbank job-page URL |
| `applyUrl` | string | External application URL, when published |
| `jobId` | string | Stable per-job identifier |
| `portal` | string | Source board (jobindex.dk / it-jobbank.dk) |

#### Location

| Field | Type | Description |
|-------|------|-------------|
| `location` | string | Listed location text as shown on the ad |
| `city` | string | Parsed city name |
| `zipCode` | string | Danish postal code |
| `region` | string | Danish region label |

#### Employment

| Field | Type | Description |
|-------|------|-------------|
| `employmentType` | string | Permanent, temporary, student, etc., when stated |
| `workplace` | string | On-site / remote / hybrid, when stated |
| `workHours` | string | Full-time / part-time, when stated |
| `isRemote` | boolean | True when the listing indicates remote work |

#### Compensation & Dates

| Field | Type | Description |
|-------|------|-------------|
| `salaryText` | string | Raw salary text (DKK), when listed |
| `salaryMin` | number | Parsed minimum salary, when listed |
| `salaryMax` | number | Parsed maximum salary, when listed |
| `salaryPeriod` | string | Salary period (month / year / hour), when listed |
| `postedDate` | string | When the job was posted (ISO-8601) |
| `deadline` | string | Application deadline, when present |

#### Description & Contacts

| Field | Type | Description |
|-------|------|-------------|
| `descriptionSnippet` | string | Short teaser from the result card |
| `description` | string | Full plain-text description (when details fetched) |
| `descriptionHtml` | string | Full HTML description (when format includes HTML) |
| `extractedEmails` | string\[] | Emails parsed from the description |
| `extractedPhones` | string\[] | Phone numbers parsed from the description |
| `extractedUrls` | string\[] | URLs parsed from the description |

#### Company & Metadata

| Field | Type | Description |
|-------|------|-------------|
| `companyUrl` | string | Company profile / website URL, when present |
| `companyLogo` | string | Company logo image URL, when present |
| `companyRatingScore` | number | Jobindex company rating, when published |
| `companyRatingCount` | integer | Number of company ratings, when published |
| `searchQuery` | string | The keyword or URL that produced this row |
| `scrapedAt` | string | ISO timestamp of data collection |

### Tips for Best Results

- **Start with a small `maxResults`** — run 50 first to confirm the keyword and filters return what you expect, then scale up to a deeper pull.
- **Keep "Fetch Full Job Details" on for descriptions and contacts** — turning it off is faster, but `description`, `salary`, `extractedEmails`, and `extractedPhones` come only from each job's detail page.
- **Salary is best-effort** — Danish employers rarely publish pay, so `salaryText`, `salaryMin`, and `salaryMax` are filled only when an ad mentions a figure; treat empty salary fields as "not disclosed", not missing data.
- **Split broad keywords to go past the depth cap** — a single keyword returns at most about 1,000 jobs on Jobindex (1,250 on IT-Jobbank). For a sector sweep, break "developer" into "backend developer", "frontend developer", etc., or add a region or category filter.
- **Aggregated and external ads have no on-site body** — some listings link straight to an employer's own site, so their full description comes back empty; the title, company, location, and dates are still complete.
- **Use IT-Jobbank for tech precision** — switching `portal` to IT-Jobbank.dk yields a cleaner IT/tech result set than keyword-filtering the general board.
- **Combine keywords and URLs in one run** — paste a pre-built filtered search URL alongside fresh keywords; results are merged and de-duplicated across everything.

### Pricing

**From $1.60 per 1,000 results** — a flat, predictable rate that undercuts comparable Danish job-board actors and adds no per-run start fee beyond Apify's small fixed charge. Bronze, Silver, and Gold subscribers pay progressively less; the table below shows total cost at each discount tier.

| Results | No discount | Bronze | Silver | Gold |
|---------|-------------|--------|--------|------|
| 100 | $0.19 | $0.18 | $0.17 | $0.16 |
| 1,000 | $1.92 | $1.80 | $1.70 | $1.60 |
| 10,000 | $19.20 | $18.00 | $17.00 | $16.00 |
| 100,000 | $192.00 | $180.00 | $170.00 | $160.00 |

A "result" is any job row in the output dataset. No compute or time-based charges — you pay per result, plus a small fixed per-run start fee.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom APIs on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor is designed for legitimate recruitment research, labor-market analysis, and lead generation. You are responsible for complying with applicable laws — including the GDPR when handling any personal data — and with Jobindex.dk and IT-Jobbank.dk's terms of service. Do not use extracted data for spam, harassment, or any unlawful purpose, and handle candidate and employer contact details responsibly. </content> </invoke>

# Actor input Schema

## `searchQueries` (type: `array`):

Job titles or keywords to search for, such as 'software engineer', 'sygeplejerske', or 'projektleder'. Each keyword runs a separate search and the results are merged and de-duplicated. Up to 50 keywords per run. Leave empty if you only want to use direct URLs below.

## `startUrls` (type: `array`):

Paste full Jobindex.dk or IT-Jobbank.dk search-result URLs (for example https://www.jobindex.dk/jobsoegning?q=udvikler) and/or individual job-page URLs. Any filters baked into a search URL are scraped exactly as-is, and pagination is handled automatically. Up to 100 URLs per run.

## `portal` (type: `string`):

Which job board to search. Jobindex.dk covers all sectors; IT-Jobbank.dk focuses on IT and tech roles. Ignored for any keyword that is overridden by a pasted URL.

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

A Danish region or municipality, such as 'Region Hovedstaden', 'København', 'Aarhus', 'Aalborg', or 'Odense'. Matched to the nearest Jobindex area. Leave empty to search all of Denmark.

## `employmentType` (type: `string`):

Filter by the type of employment. Leave on 'Any' for all types.

## `workplace` (type: `string`):

Filter by where the work happens. Leave on 'Any' for all options.

## `workHours` (type: `string`):

Filter by full-time or part-time. Leave on 'Any' for both.

## `categories` (type: `array`):

Restrict results to one or more Jobindex job categories. Leave empty to include every category. Categories combine with your keywords and other filters.

## `datePosted` (type: `string`):

Only show jobs published within this time period.

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

Maximum number of jobs to collect per search keyword (up to 2,000). Use 50 for a quick scan or a higher number for deep research. The last page is always kept in full, so the final count can slightly overshoot this number. Note: each individual keyword search can return at most about 1,000 jobs (Jobindex) or 1,250 (IT-Jobbank); to go deeper, split a broad keyword into several narrower ones or add filters.

## `includeJobDetails` (type: `boolean`):

Fetch the full description, salary, deadline, and contact details from each job's detail page. Leave on for the richest data. Turn off for faster, lighter scans — the description, salary, and contact fields will then be empty.

## `descriptionFormat` (type: `string`):

How to return the job description. 'Text' gives clean plain text, 'HTML' preserves formatting, 'Both' includes each in its own field.

## Actor input object example

```json
{
  "searchQueries": [
    "software engineer"
  ],
  "startUrls": [],
  "portal": "jobindex.dk",
  "employmentType": "",
  "workplace": "",
  "workHours": "",
  "categories": [],
  "datePosted": "",
  "maxResults": 50,
  "includeJobDetails": true,
  "descriptionFormat": "text"
}
```

# Actor output Schema

## `overview` (type: `string`):

Table of scraped job listings with key fields.

## `detail` (type: `string`):

Complete job records including descriptions, salary, contact details, and company metadata.

# 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 = {
    "searchQueries": [
        "software engineer"
    ],
    "startUrls": [],
    "portal": "jobindex.dk",
    "location": "",
    "employmentType": "",
    "workplace": "",
    "workHours": "",
    "categories": [],
    "datePosted": "",
    "maxResults": 50,
    "includeJobDetails": true,
    "descriptionFormat": "text"
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/jobindex-dk-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 = {
    "searchQueries": ["software engineer"],
    "startUrls": [],
    "portal": "jobindex.dk",
    "location": "",
    "employmentType": "",
    "workplace": "",
    "workHours": "",
    "categories": [],
    "datePosted": "",
    "maxResults": 50,
    "includeJobDetails": True,
    "descriptionFormat": "text",
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/jobindex-dk-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "software engineer"
  ],
  "startUrls": [],
  "portal": "jobindex.dk",
  "location": "",
  "employmentType": "",
  "workplace": "",
  "workHours": "",
  "categories": [],
  "datePosted": "",
  "maxResults": 50,
  "includeJobDetails": true,
  "descriptionFormat": "text"
}' |
apify call solidcode/jobindex-dk-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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