# Jobindex.dk Job Scraper (`crawlerbros/jobindex-dk-scraper`) Actor

Scrape live job listings from Jobindex.dk, Denmark's largest job board. Search by keyword, browse by region/municipality, job category, or company. Get title, company, location, posted date, deadline, apply URL, and more.

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

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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.dk Job Scraper

Scrape **Jobindex.dk** — Denmark's largest job board — for live job listings. Search by keyword, browse by region or municipality, browse by job category, or browse by a specific employer, with filters for employment type, working hours, remote/home-office option, and posting recency. HTTP-only via the public jobindex.dk search pages. No auth, no proxy, no cookies required.

### What this actor does

- **Four modes:** `search` (keyword), `byRegion` (region/municipality browse), `byCategory` (job-category browse), `byCompany` (browse all current openings from one employer)
- **110 Danish regions & municipalities** and **81 job categories** as ready-to-use dropdowns — no need to guess IDs
- **Filters:** employment type, working hours, remote/home-office option, company ID, posted-within window, sort order — combinable across all modes
- **Rich company data:** name, homepage, profile URL, logo, Jobindex company rating
- **Empty fields are omitted**

### Output per job

- `id` — Jobindex internal ad ID
- `title` — job headline
- `company`, `companyUrl`, `companyProfileUrl`, `companyLogoUrl`
- `companyRating`, `companyRatingCount` — Jobindex's aggregated employer rating (when available)
- `companyFollowerCount` — number of Jobindex users following the employer's company profile
- `descriptionSnippet` — short teaser text from the ad body (the same excerpt shown on the Jobindex search-results page, ~1-2 sentences, up to ~400 characters)
- `location` — free-text area name (e.g. `København Ø`)
- `city`, `zipCode` — from the first listed workplace address
- `latitude`, `longitude` — geocoordinates of the first listed workplace address (when Jobindex provides them)
- `addresses[]` — formatted "street, zip city" strings for every listed workplace
- `postedDate` — date first published
- `applicationDeadline` — application deadline date
- `applicationDeadlineDateTime` — precise deadline timestamp (when the employer set one)
- `applicationDeadlineAsap` — `true` when the employer set a rolling/"apply as soon as possible" deadline instead of a fixed date
- `isSponsored` — true for paid/featured listings
- `isRemoteOk` — true only for listings the employer tagged **100% remote/home-office** on Jobindex. Listings tagged "partly remote / hybrid possible" (`employmentPlace=3`) are **not** flagged true here — Jobindex's underlying data only exposes a boolean for the fully-remote case (see Limitations)
- `videoUrl`, `videoThumbnailUrl` — employer-branded video ad, when the listing includes one
- `url` — canonical jobindex.dk detail page
- `applyUrl` — Jobindex's tracked apply link (redirects to the employer's application page), when available
- `recordType: "job"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byRegion` / `byCategory` / `byCompany` |
| `searchQuery` | string | – | Free-text keyword (mode=search); combinable with `region`/`category`/`companyId` filters |
| `region` | array | – | One or more regions/municipalities (mode=byRegion; optional filter otherwise) |
| `category` | array | – | One or more job categories (mode=byCategory; optional filter otherwise) |
| `companyId` | array | – | One or more numeric Jobindex company IDs (mode=byCompany; optional filter otherwise). Find a company's ID in the `companyProfileUrl` output field. |
| `employmentType` | array | – | Permanent, temporary, student job, freelance, not-specified, etc. |
| `workingHours` | array | – | Full-time / part-time / not-specified |
| `employmentPlace` | array | – | Remote/home-office option: 100% remote, partly remote/hybrid, not remote, not specified |
| `postedWithin` | string | \`\` (any time) | Today / last 7 days / last 30 days / online only |
| `sortBy` | string | `score` | `score` (relevance) or `date` (newest first) |
| `maxItems` | int | `50` | Hard cap on emitted job listings (1–1000) |

#### Example: keyword search

```json
{
  "mode": "search",
  "searchQuery": "sygeplejerske",
  "sortBy": "date",
  "maxItems": 50
}
```

#### Example: browse by region + category, full-time only

```json
{
  "mode": "byRegion",
  "region": ["15182"],
  "category": ["1"],
  "workingHours": ["1"],
  "postedWithin": "30",
  "maxItems": 100
}
```

#### Example: browse by category across Denmark

```json
{
  "mode": "byCategory",
  "category": ["1", "4"],
  "sortBy": "date",
  "maxItems": 200
}
```

#### Example: browse all current openings at one employer

```json
{
  "mode": "byCompany",
  "companyId": ["39894"],
  "sortBy": "date",
  "maxItems": 50
}
```

#### Example: remote-friendly jobs only

```json
{
  "mode": "search",
  "searchQuery": "udvikler",
  "employmentPlace": ["2", "3"],
  "maxItems": 50
}
```

### Use cases

- **Recruitment agencies** — monitor new listings in a target region or industry
- **Labor market research** — track job posting volume by category over time
- **HR tech / job aggregators** — feed structured Danish job data into your own platform
- **Salary & demand analysis** — combine with employment-type filters to study hiring trends
- **Company intelligence** — track which employers are actively hiring and how they're rated

### FAQ

**What is Jobindex.dk?** Denmark's largest job portal, aggregating listings from thousands of Danish employers and recruitment agencies. See [jobindex.dk](https://www.jobindex.dk).

**Is this affiliated with Jobindex?** No — this is an independent third-party actor that reads Jobindex's public search-results pages.

**How do I find a region/category ID?** Both `region` and `category` are dropdown selects in the Apify Console — pick by name, no need to know the underlying ID.

**Can I combine keyword search with a region, category, or company filter?** Yes — `region`, `category`, and `companyId` all work as additional filters on `search` mode too, not just their own dedicated modes.

**Why do some jobs have no `companyRating`?** Jobindex only shows a rating once an employer has received enough reviews from users; smaller or newer employers may not have one yet.

**Why do some jobs have no `applyUrl`?** A minority of listings route applications only through the employer's own site without a Jobindex-tracked apply link; use `url` (the Jobindex detail page) in that case.

**How fresh is the data?** Jobindex re-indexes continuously as employers post and remove ads; running the actor gives you the current live listing set for your filters.

**Does `maxItems` guarantee that many results?** No — it's a cap. If fewer jobs match your filters, you'll get fewer records.

### Limitations

- **Region, category, employment-type, working-hours, and remote/home-office option lists** mirror Jobindex's own current option lists, so the dropdowns stay in sync with the live site — no guessed or hand-typed IDs.
- **`employmentPlace` filtering works correctly for all four values**, but the per-listing `isRemoteOk` output field only reflects the fully-remote case. Jobindex only exposes a structured "remote" flag for 100%-remote listings; hybrid/partly-remote listings don't carry an equivalent structured flag, even though they do offer some home-office flexibility. Use the `employmentPlace` input filter itself to browse hybrid-friendly roles rather than relying on `isRemoteOk` for that case.
- **Archived/expired listings** are not supported — Jobindex's job archive is gated behind a logged-in account, and this actor is intentionally cookie-free/auth-free. It returns your current live results without erroring if you request an unsupported window.
- **Job-title autocomplete lookup** is not exposed as a filter — use `searchQuery` for free-text keyword matching instead.
- **Sort orders** are limited to the two Jobindex itself offers: relevance and newest-first.
- **`companyId`** requires the company's numeric Jobindex ID (there is no bounded/finite list — Jobindex hosts tens of thousands of employer profiles). Get it from the `companyProfileUrl` field of any job record for that employer, or browse [jobindex.dk/virksomhedsoversigt](https://www.jobindex.dk/virksomhedsoversigt).
- **A separate "browse companies" mode** (listing employers by name/rating/job count) is not available — Jobindex's company directory page isn't backed by the same reliable data source as its job-search results.
- **A "direct application" link distinct from `applyUrl`** is intentionally not exposed: it is inconsistent across listings (sometimes a dead end for anonymous visitors), so only the reliable `applyUrl` (Jobindex's own tracked redirect) and `url` (the detail page) are provided.
- **`descriptionSnippet` is a teaser, not the full job ad text.** It's the same short excerpt (~1-2 sentences, up to ~400 characters) shown on the Jobindex results page for each listing — the full ad body lives on the employer's own application page (via `applyUrl`/`url`) or the Jobindex detail page.
- **A handful of upstream data points are intentionally excluded** because Jobindex doesn't populate them reliably or publicly document their meaning (e.g. distance-from-searcher, which requires a resolved user location this actor never sends) — only fields with dependable, well-understood values are included in the output.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

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

Free-text keyword search (job title, skill, company, etc.) (mode=search). Can be combined with region/category filters below.

## `region` (type: `array`):

One or more Danish regions, areas, or municipalities to browse/filter jobs by. Required for mode=byRegion; optional filter on other modes.

## `category` (type: `array`):

One or more Jobindex job categories to browse/filter jobs by. Required for mode=byCategory; optional filter on other modes.

## `employmentType` (type: `array`):

Filter by employment type (optional, all modes).

## `workingHours` (type: `array`):

Filter by working hours (optional, all modes).

## `employmentPlace` (type: `array`):

Filter by remote-work (home-office) option, based on how the employer tagged the listing (optional, all modes).

## `companyId` (type: `array`):

One or more numeric Jobindex company IDs to browse/filter jobs by. Required for mode=byCompany; optional filter on other modes. Find a company's ID in the `companyProfileUrl` output field (e.g. jobindex.dk/virksomhed/49935/... -> 49935) or on jobindex.dk/virksomhedsoversigt.

## `postedWithin` (type: `string`):

Only include jobs posted within this time window (optional, all modes).

## `sortBy` (type: `string`):

Result ordering.

## `maxItems` (type: `integer`):

Hard cap on the number of job listings to emit.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "udvikler",
  "region": [
    "15182"
  ],
  "category": [
    "1"
  ],
  "employmentType": [],
  "workingHours": [],
  "employmentPlace": [],
  "companyId": [],
  "postedWithin": "",
  "sortBy": "score",
  "maxItems": 30
}
```

# Actor output Schema

## `jobs` (type: `string`):

Dataset containing all scraped Jobindex.dk job listings.

# 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 = {
    "mode": "search",
    "searchQuery": "udvikler",
    "region": [
        "15182"
    ],
    "category": [
        "1"
    ],
    "employmentType": [],
    "workingHours": [],
    "employmentPlace": [],
    "companyId": [],
    "postedWithin": "",
    "sortBy": "score",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/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 = {
    "mode": "search",
    "searchQuery": "udvikler",
    "region": ["15182"],
    "category": ["1"],
    "employmentType": [],
    "workingHours": [],
    "employmentPlace": [],
    "companyId": [],
    "postedWithin": "",
    "sortBy": "score",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/jobindex-dk-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 '{
  "mode": "search",
  "searchQuery": "udvikler",
  "region": [
    "15182"
  ],
  "category": [
    "1"
  ],
  "employmentType": [],
  "workingHours": [],
  "employmentPlace": [],
  "companyId": [],
  "postedWithin": "",
  "sortBy": "score",
  "maxItems": 30
}' |
apify call crawlerbros/jobindex-dk-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/jobindex-dk-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/bTE7U9yyr1DhVLpba/builds/jMC6a3noTWVdVAcPg/openapi.json
