Jobindex.dk & IT-Jobbank [$1.5💰] Denmark Jobs Scraper
Pricing
Pay per event
Jobindex.dk & IT-Jobbank [$1.5💰] Denmark Jobs Scraper
Scrape Jobindex.dk and IT-Jobbank.dk — Denmark's largest job board and its IT sister site. Keyword or URL in; one row per job: title, company, geocoded location, dates, apply URL, stated salary. Incremental mode returns only new or changed ads, so scheduled runs stay cheap.
Pricing
Pay per event
Rating
4.0
(1)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
0
Bookmarked
18
Total users
2
Monthly active users
2 days ago
Last modified
Share
Jobindex Scraper
Turn any Jobindex.dk or IT-Jobbank.dk search into clean, structured data. Search by keyword or paste search-result URLs and single job URLs — and get one flat row per job with title, company, location + coordinates, publish and deadline dates, apply URL, a teaser, and the stated salary whenever the ad names one. Flip on detail mode to add the full job-ad body text, or incremental mode so a scheduled run returns only the ads that are new or have changed.
Built for recruitment-market research, salary and hiring-trend analysis, job aggregation and lead generation across the Danish job market.
How it works

✨ Why use this scraper?
- Two live Danish portals, one run — jobindex.dk (all sectors) and it-jobbank.dk (the IT-only sister site with its own ad inventory). Each row is tagged with the
siteit came from. - Only pay for what moved — turn on Only return new & changed ads and the actor remembers every ad between runs. Unchanged ads are skipped: not pushed, not billed, and their detail page is never even fetched. A daily watch costs a few cents.
- Rich rows out of the box — ~30 fields per job from the search results alone: title, company name + profile, location with latitude/longitude, first-seen and drop-off dates, apply deadline, apply URL, teaser text, logo and flags (remote, sponsored, archived).
- Salary when it's there — the ad text is mined for stated wages (
timeløn på 180 kr.,35.000–40.000 kr. pr. måned) intosalaryTextplus parsedsalaryMin/salaryMax, currency and pay period. No guessing: ads without a stated wage get explicitnulls. - Two ways in — keyword searches, or paste search-result URLs (with any filters you set on the site) and single job URLs. Mix sites and kinds in one run.
- Danish-IP ready — these are Danish sites; every request routes through Danish residential IPs so you get the real page, not a geo-block.
- Full ad text on demand — turn on Scrape job detail pages (or paste a job URL) to add the complete job-ad body text.
- Geocoded locations — each job carries structured addresses (street, zip, city) with coordinates, ready to drop onto a map.
- JSON, CSV, Excel or API — pipe straight into your sheet, BI tool or pipeline. Billed per job.
🎯 Use cases
| You are a… | Use it to… |
|---|---|
| Recruiter / agency | Track live openings by keyword, company and location across Denmark |
| Market researcher | Measure hiring volume, remote-work share and posting velocity per sector |
| Job-board / aggregator | Seed a Danish jobs dataset with structured, deduplicated listings |
| Hiring-alert builder | Schedule an incremental run and receive only newly posted or edited ads |
| Data / app builder | Build a geocoded map of open roles from the address coordinates |
| Sales / lead-gen | Find hiring companies with their profile, homepage and follower count |
📥 Supported inputs
- Search keywords — e.g.
ingeniør,sygeplejerske,developer,marketing. Each is searched and paginated, once per portal you selected. - Portals —
jobindexand/orit-jobbank, chosen with thesitesinput. Defaults tojobindex. - Search-result URLs —
https://www.jobindex.dk/jobsoegning?...orhttps://www.it-jobbank.dk/jobsoegning?...with any filters you applied on the site (area, category, etc.). - Single job URLs —
https://www.jobindex.dk/vis-job/{id}orhttps://www.it-jobbank.dk/jobannonce/{id}/{slug}. Auto-classified and always fully detailed.
⚙️ How it works
- Collect search-result pages from your keywords / URLs, per portal (20–24 jobs per page, up to 50 pages).
- Parse each job card into a flat row — company, location + coordinates, dates, apply URL, teaser.
- Compare (incremental mode) each ad against the state from previous runs and label it
new,changedorunchanged; unchanged ads stop here, before costing you a request or a row. - Enrich each surviving job from its detail page (when Scrape job detail pages is on): full ad body text.
- Export one row per job to the dataset — JSON, CSV, Excel or API.
⚙️ Input parameters
| Field | Type | Default | What it does |
|---|---|---|---|
searchQueries | array | ["ingeniør"] | Keyword searches. Each is searched and paginated, once per selected portal. |
sites | array | ["jobindex"] | Which portals keyword searches run against: jobindex, it-jobbank, or both. |
startUrls | array | [] | Search-result URLs and/or single job URLs, from either site. Auto-classified by kind and portal. |
scrapeDetails | boolean | false | Also fetch each job's detail page for the full ad body text (fullText). ~2× requests. Pasted job URLs are always fully detailed. |
incremental | boolean | false | Remember ads between runs and label each row new / changed / unchanged. Unchanged ads are skipped and never billed. |
emitUnchanged | boolean | false | With incremental on, return unchanged ads too (full snapshot plus change labels) instead of only what moved. |
stateStoreName | string | jobindex-incremental-state | Named key-value store holding the change-detection state. Use different names to track separate watchlists. |
stateRetentionDays | integer | 90 | Forget ads not seen for this many days, so a long-expired ad counts as new if reposted. |
maxItems | integer | 1000 | Hard cap on rows for the whole run. Each row is one paid job event. |
maxItemsPerSearch | integer | 1000 | Cap per keyword / URL. |
maxConcurrency | integer | 6 | Parallel HTTP requests (1–15). |
maxRequestRetries | integer | 12 | Retry budget on 403 / 429 / 5xx; each retry rotates to a fresh Danish residential IP. |
proxy | object | DK Residential | Proxy config (defaults to Apify Residential, country DK). |
📊 Output overview
Each dataset record is one job listing. Rows carry the search-card fields (title, company block, location + coordinates, dates, apply URL, teaser, logo, flags) and — when Scrape job detail pages is on, or for pasted job URLs — the full ad body text (fullText). In incremental mode every row also carries changeType and firstSeenAt.
📦 Output sample
{"rowType": "job","site": "jobindex","jobId": "h1677520","headline": "Product Developer, Footwear","jobUrl": "https://www.jobindex.dk/vis-job/h1677520","applyUrl": "https://www.jobindex.dk/c?t=e6185324&ctx=w","companyName": "hummel","companyId": 955,"companyProfileUrl": "https://www.jobindex.dk/virksomhed/955/hummel#om-virksomhed","companyHomeUrl": "https://www.hummel.dk/","companyFollowers": 1140,"area": "Aarhus C","addresses": [{"line": "Balticagade 20","zipcode": "8000","city": "Aarhus C","simpleString": "Balticagade 20, 8000 Aarhus C","latitude": 56.155226,"longitude": 10.221049}],"latitude": 56.155226,"longitude": 10.221049,"firstDate": "2026-06-26","lastDate": "2026-07-09","applyDeadline": "2026-07-09T21:59:59Z","applyDeadlineAsap": false,"homeWorkplace": false,"hasSpo": true,"summary": "Do you have a sharp eye for what makes a collection come together? …","salaryText": null,"salaryMin": null,"salaryMax": null,"salaryCurrency": null,"salaryPeriod": null,"changeType": "new","firstSeenAt": "2026-08-17","sourceUrl": "https://www.jobindex.dk/jobsoegning?q=developer","sourceMode": "search","scrapedAt": "2026-08-17T03:24:12.172Z"}
🗂 Key output fields
| Field | Description |
|---|---|
site | Portal the ad came from — jobindex or it-jobbank |
jobId | Job id (tid), e.g. h1677520 |
headline | Job title |
jobUrl | Canonical job URL on its portal |
applyUrl | Outbound redirect to the employer's apply flow |
companyName / companyId | Employer name and portal company id |
companyProfileUrl / companyHomeUrl | Portal profile and employer homepage |
companyFollowers | Follower count on the company's profile |
area | Primary display area |
addresses | Structured addresses: street, zip, city + latitude / longitude |
latitude / longitude | Coordinates of the first address (convenience) |
firstDate / lastDate | First published / drops-off-search dates (YYYY-MM-DD) |
applyDeadline / applyDeadlineAsap | ISO deadline, or ASAP flag |
homeWorkplace | Remote / home-working flagged |
hasSpo | Sponsored / promoted placement |
summary | Listing-card teaser text |
salaryText / salaryMin / salaryMax | Wage stated in the ad text — verbatim snippet + parsed range (single amounts: min = max). null when the ad names no pay, which most Danish ads don't |
salaryCurrency / salaryPeriod | DKK; hour / month / year when the ad says so |
changeType | new, changed or unchanged vs the previous run (incremental mode) |
firstSeenAt | Date this actor first saw the ad (incremental mode) |
fullText | Full job-ad body text (when scrapeDetails is on) |
💰 Pricing
| Event | When it fires | Rate |
|---|---|---|
| Actor start | Once per run | $0.0005 |
| Job listing | Per row actually emitted | $0.0015 — that's $1.50 per 1,000 jobs |
What that means in practice:
| Scenario | Cost |
|---|---|
| One-off pull of 1,000 jobs | ~$1.50 |
| Daily incremental watch on a 500-ad search, ~20 ads move per day | ~$0.03 per run, under $1 a month |
| A run where nothing changed | $0.0005 — the start event only |
Skipped and blocked requests are never billed, and in incremental mode unchanged ads cost nothing at all. The low start fee is deliberate: frequent small scheduled runs shouldn't be punished by a per-run charge.
🔍 What makes this richer than the competition
| Capability | Typical competing actors | This actor |
|---|---|---|
| Portals covered | jobindex.dk, sometimes bundled with ofir.dk — which has shut down (it now answers HTTP 410 with "Ofir.dk er lukket") and serves no ads at all | jobindex.dk + it-jobbank.dk, both live and verified |
| Scheduled runs | Full re-scrape every run; you pay for every row every time | Incremental mode returns only new/changed ads and bills only those |
| Wasted detail fetches | Detail page fetched before knowing whether the ad changed | Change is decided on the search card first, so unchanged ads cost zero requests |
| Geocoding | Text location only | Structured addresses with latitude/longitude per address |
| Salary | Often absent, or inferred | Mined verbatim from the ad text with parsed range, currency and period — explicit null when the ad states no pay, never an estimate |
| Empty-run behaviour | A blocked run can silently "succeed" with 0 rows | Fails loudly when every request was blocked, so a broken run never looks like an empty market |
| Start fee | Commonly $0.01 per run | $0.0005 per run |
❓ FAQ
Do I need an account or API key? No. Paste keywords or URLs and run.
What is IT-Jobbank and why is it here? it-jobbank.dk is Jobindex's IT-only sister site, running on the same platform but with its own ad inventory. Setting sites to both gets you general and IT-specific Danish vacancies in one run, each row tagged with its site.
What does Scrape job detail pages add? The search row is already rich (~30 fields including a teaser). Turning it on visits each job's detail page to add the full ad body text (fullText) — at roughly double the requests. Job URLs you paste are always fully detailed.
How does incremental mode decide something "changed"? It fingerprints each ad's title, company, area, apply deadline, salary and apply URL. If any of those move, the ad comes back as changed; if none do, it's unchanged and skipped. The fingerprint deliberately ignores the teaser text, so a wording tweak in how teasers are extracted can never flood you with false changes.
What happens on the very first incremental run? There is nothing to compare against, so every ad is new. Run it once to seed the state, then schedule it.
Can I watch several searches separately? Yes — give each schedule its own stateStoreName (for example jobindex-state-nurses and jobindex-state-devs) and their histories stay independent.
Does it extract salary? When the ad text states a wage (timeløn på 180 kr., 35.000–40.000 kr. pr. måned), the row carries the verbatim salaryText plus parsed salaryMin/salaryMax, salaryCurrency and salaryPeriod. Most Danish ads don't publish pay — those rows have explicit nulls, never guesses. Turning on Scrape job detail pages mines the full ad body, not just the teaser.
Can I use my own filters? Yes. Apply any filters on the site (area, category, contract type), copy the resulting jobsoegning?... URL, and paste it into startUrls.
Which locations does it cover? All of Denmark. Each job carries structured addresses with coordinates where the portal provides them.
What format is the output? JSON, CSV, Excel or via API — one row per job.
💬 Support
Found a missing field or a page that won't parse? Open an issue on the actor's Issues tab with the input you used — fixes usually ship within a day or two.
🛠 Additional services
Need a custom field, a different Danish job board, or a scheduled feed into your database? Reach out via the Issues tab.
🔎 Explore more scrapers
Browse the full portfolio of job-board and directory scrapers on the Apify Store.
🤖 For AI Agents & LLM Apps
Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/jobindex-scraper).
Purpose: scrape Jobindex.dk and IT-Jobbank.dk — Denmark's largest job board and its IT sister site — into one flat row per job: title, company profile, geocoded addresses, publish + deadline dates, apply URL, teaser, mined salary when the ad states one, optional full ad text, optional change labels.
Minimal input:
{ "searchQueries": ["developer"], "maxItems": 20 }
Both portals, only what changed since last run:
{ "searchQueries": ["developer"], "sites": ["jobindex", "it-jobbank"], "incremental": true, "maxItems": 100 }
Output: one dataset row per job — site, jobId, headline, jobUrl, applyUrl, companyName, companyId, companyProfileUrl, companyHomeUrl, companyFollowers, area, addresses [{line, zipcode, city, latitude, longitude}], latitude, longitude, firstDate, lastDate, applyDeadline, applyDeadlineAsap, homeWorkplace, hasSpo, summary, salaryText, salaryMin, salaryMax, salaryCurrency, salaryPeriod, sourceUrl, sourceMode, scrapedAt, plus fullText when scrapeDetails is on and changeType + firstSeenAt when incremental is on.
Behaviors an agent should know:
- Always set
maxItems— one uncapped keyword can return up to 1,000 rows (20 per page × 50 pages), and selecting both portals runs each keyword twice. searchQueriesandstartUrlsare additive.sitesapplies to keywords only; a pasted URL's portal comes from the URL itself.incremental: truemakes runs stateful via a named key-value store. The first run labels everythingnew; later runs emit onlynewandchangedunlessemitUnchangedis true. An incremental run that returns zero rows means nothing moved — it is a success, not a failure.- Salary fields are mined from the ad text and are
nullfor most rows — Danish ads rarely publish pay. Non-null values are verbatim from the ad, never estimates. - Billing: one
jobevent per emitted row plus a small actor-start event. Skipped, blocked and failed requests are never billed. - A Danish residential proxy is built in; only pass your own
proxyif you have a specific reason.
⚠️ Disclaimer
This scraper collects only publicly available job-listing data from Jobindex.dk and IT-Jobbank.dk. It does not access private accounts, bypass authentication, or collect personal data beyond what employers publish on public job ads. You are responsible for using the scraped data in compliance with the sites' terms, Danish and EU law (including GDPR), and any applicable regulations. Use it for legitimate research, aggregation and analysis.
SEO Keywords
Jobindex scraper, Jobindex.dk scraper, IT-Jobbank scraper, it-jobbank.dk scraper, Denmark jobs scraper, Danish job listings API, scrape Jobindex, job board scraper Denmark, Jobindex jobs data, danish jobs dataset, danish IT jobs scraper, recruitment data Denmark, hiring trends Denmark, job posting scraper, new job alerts Denmark, incremental job scraper, job change detection, vis-job scraper, jobsoegning scraper, Apify Jobindex, extract Jobindex jobs, Danish vacancies data, Jobindex salary data, Danish jobs salary, løn data Danmark, Denmark job market analysis.