
Google Ads Scraper
scrape.ly/store/querystone/google-ads-scraperLead generationSEO tools
4 monthly users

Scrape duunitori.fi, Finland's largest job board: job title, company, location, salary, employment type, posting and closing dates, apply link, business ID and full description. Search by keyword and location or paste duunitori.fi URLs.
Get every job from duunitori.fi, Finland's largest job board, as clean structured data: title, company, business ID, every location, salary range, employment type, posting and closing dates, the apply link and the full description as text, HTML and Markdown. Search by keyword and location or paste duunitori.fi links. No login, no cookies, and about 1,000 jobs with full details in under a minute.
ohjelmistokehittäjä, sairaanhoitaja, python) and, if you like, locations (Helsinki, Tampere, Uusimaa, Pääkaupunkiseutu). Or paste duunitori.fi links into Duunitori URLs.| Field | What it does |
|---|---|
searchQueries | Keywords, one search each. Matches job title and company (turn on searchInDescription to also match the description). |
locations | Cities, municipalities or regions. Several locations are combined into one search. |
startUrls | duunitori.fi search, area, company or job links. |
maxResults | Total jobs to save (0 = no limit). |
maxResultsPerSearch | Optional cap per keyword or link. |
daysOld | Only jobs posted within the last N days. |
includeDetails | Open each job page for salary, employment type, closing date and more (on by default). |
incrementalMode / stateKey | Only new and changed jobs since the last run with the same key. |
proxyConfiguration | Finnish residential proxies by default (the site only shows job pages to visitors in Finland). |
{
"searchQueries": ["ohjelmistokehittäjä"],
"locations": ["Helsinki"],
"maxResults": 20,
"daysOld": 7,
"includeDetails": true
}
One row per job. The main fields:
| Field | Example |
|---|---|
title | Senior Software Developer / Architect |
company / companyBusinessId | Forge Digital Oy / 3347904-6 |
location / locations | Helsinki / ["Helsinki", "Tampere"] |
salaryText, salaryMin, salaryMax, salaryPeriod | 5 500–6 500 €/kk, 5500, 6500, MONTH |
employmentType | FULL_TIME |
occupation / category | ohjelmistokehittäjä / tieto- ja tietoliikennetekniikka |
postedDate / validThrough | 2026-10-20T12:44:41Z / 2026-11-02T21:59:00Z |
applyUrl | The employer's application form, or the job page when applications go through Duunitori |
description, descriptionHtml, descriptionMarkdown | Full job description |
extractedEmails, extractedPhones, extractedUrls, socialProfiles | Contacts and links found in the description |
changeType | new or updated in "Only new and changed jobs" mode |
A real row from a test run (description shortened, the recruiter's contact details replaced with fictional ones):
{
"jobId": "20665486",
"url": "https://duunitori.fi/tyopaikat/tyo/forge-digital-oy-senior-software-developer-architect-sdsuu-20665486",
"title": "Senior Software Developer / Architect",
"company": "Forge Digital Oy",
"companyUrl": "https://duunitori.fi/tyopaikat/yritys/forge-digital-oy",
"companyBusinessId": "3347904-6",
"location": "Helsinki",
"locations": ["Helsinki", "Tampere"],
"salaryText": "5 500–6 500 €/kk",
"salaryMin": 5500,
"salaryMax": 6500,
"salaryCurrency": "EUR",
"salaryPeriod": "MONTH",
"employmentType": "FULL_TIME",
"occupation": "ohjelmistokehittäjä",
"category": "tieto- ja tietoliikennetekniikka",
"postedDate": "2026-10-20T12:44:41.525489Z",
"validThrough": "2026-11-02T21:59:00Z",
"applyUrl": "https://forgedigital.careers.haileyhr.app/en-GB/job/2b768dad-862e-4747-b608-b864208f1a5d/a43b951a-4da2-4a77-a168-da6206f6f63d/c4423254-f1a6-4db4-a4b2-0b5a8e952c12?utm_source=duunitori.fi&utm_medium=referral&source=duunitori",
"applicationType": "other",
"description": "Innostaako teollisuuden kriittisten järjestelmien rakentaminen? Etsimme tiimiimme senior-kehittäjää tai -arkkitehtia, joka haluaa tehdä työtä, jolla on oikeasti…",
"extractedEmails": ["anna.virtanen@example.fi"],
"extractedPhones": ["040 123 4567"],
"detailsLoaded": true,
"searchQuery": "ohjelmistokehittäjä",
"searchLocation": "Helsinki",
"position": 1,
"source": "duunitori.fi",
"scrapedAt": "2026-10-22T01:45:59Z"
}
You pay $1.00 per 1,000 jobs ($0.001 per saved job), plus platform usage. Platform usage is not included and is small: on our test runs 1,000 jobs with full details used about $0.08 (mostly Finnish residential proxy traffic), so 1,000 jobs ≈ $1.08 in total. With "Load job details" turned off, 1,000 jobs used about $0.003 of platform usage. You are only charged for jobs that are saved; a run never charges past the maximum cost you set.
Is it legal to scrape duunitori.fi? The actor collects only public job ads that anyone can open without an account. Job ads can contain personal data such as a recruiter's name and e-mail; make sure your use of it complies with the GDPR and your local laws.
Do I need a login or my own proxy? No. No account, cookies or login are used. The site only shows job pages to visitors in Finland, so the actor uses Finnish residential proxies by default; if you pick another proxy, it switches to Finnish residential when the site blocks it.
How many results can I get? As many as the site lists: set Max results to 0 for every matching job. All of duunitori.fi is roughly 17,500 open jobs at a time.
Why is a field empty?
The actor fills what the job ad publishes. Many ads have no salary, coordinates are rarely given, and some employers do not show a business ID. If a job page cannot be loaded, the row still has the list data (title, company, location, date, full description) and detailsError says why.
Can I schedule it or use it from the API? Yes. Schedule it daily with "Only new and changed jobs" on to receive only new postings, and read results from the dataset API or connect them to your integrations.
Can I migrate from a similar actor on another platform? Yes. The main inputs (keywords, location, posting age, max results, start URLs, incremental mode) and the main output fields (salary, employment type, closing date, occupation, description in text, HTML and Markdown, extracted contacts) work the same way.
applyUrl then points to the job page.Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
searchQueriesarrayOptionalSearch keywords
Job titles, skills or company names to search for, one per line, for example ohjelmistokehittäjä, sairaanhoitaja, python or Nordea. Each keyword is a separate search. Leave empty with a location to get every job there, or leave everything empty to get the newest jobs in all of Finland.
locationsarrayOptionalLocations
Finnish cities, municipalities or regions, for example Helsinki, Tampere, Uusimaa or Pääkaupunkiseutu. Several locations are combined into one search (jobs in any of them). Names without ä/ö also work (Seinajoki). Leave empty to search all of Finland.
startUrlsarrayOptionalDuunitori URLs
duunitori.fi links: search pages (duunitori.fi/tyopaikat?haku=python&alue=helsinki), area pages (duunitori.fi/tyopaikat/alue/tampere), company pages (duunitori.fi/tyopaikat/yritys/) or single job pages (duunitori.fi/tyopaikat/tyo/).
maxResultsintegerOptionaldefault 20Max results
Maximum number of jobs to save in total, across all keywords and URLs. Use 0 for no limit (every matching job; all of duunitori.fi is about 17,500 jobs).
maxResultsPerSearchintegerOptionaldefault 0Max results per search
Cap the jobs saved per keyword or URL, so one broad search does not use up the whole limit. 0 means no cap.
daysOldintegerOptionalPosted within (days)
Only jobs posted within the last N days (1 = last 24 hours). Leave empty for any posting date. Applies to searches; a pasted job page is always saved.
searchInDescriptionbooleanOptionaldefault falseAlso match keywords in the job description
By default a keyword matches the job title and company. Turn this on to also find jobs that mention the keyword only in their description.
includeDetailsbooleanOptionaldefault trueLoad job details
Open each job page for salary, employment type, closing date, occupation, category, every location, the apply link, the company's business ID (Y-tunnus) and the description as HTML and Markdown. Turn off for a faster, cheaper list with title, company, location, posting date and the full description text.
incrementalModebooleanOptionaldefault falseOnly new and changed jobs
For scheduled runs: save only jobs that are new or whose title, company, location or description changed since an earlier run with the same state key. Each saved job says whether it is new or updated.
stateKeystringOptionalState key
Name for the memory of jobs already seen, used by 'Only new and changed jobs'. Use the same key on every scheduled run of one search. Leave empty to derive it from the keywords, locations and URLs.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["RESIDENTIA…Proxy configuration
duunitori.fi only opens job pages for visitors in Finland, so Finnish residential proxies are the default. Other choices are switched to Finnish residential automatically when the site blocks them.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| jobId | string | null | Duunitori's job number (the digits at the end of the job URL). |
| url | string | null | Job page on duunitori.fi. |
| title | string | null | Job title. |
| company | string | null | Hiring company or recruiter. |
| companyUrl | string | null | The company's page on duunitori.fi (job page details). |
| companyBusinessId | string | null | Finnish business ID of the employer when the job page shows it. |
| location | string | null | Main municipality of the job. |
| locations | array | null | Every municipality or region the job page lists. |
| latitude | number | null | Latitude when the site has one (rare). |
| longitude | number | null | Longitude when the site has one (rare). |
| salaryText | string | null | Salary as the job page shows it, for example 5 500–6 500 €/kk. |
| salaryMin | number | null | Lower salary bound. |
| salaryMax | number | null | Upper salary bound. |
| salaryCurrency | string | null | EUR when a salary is given. |
| salaryPeriod | string | null | HOUR, DAY, WEEK, MONTH or YEAR. |
| employmentType | string | null | FULL_TIME, PART_TIME, TEMPORARY, INTERN, CONTRACTOR... as the site tags it. |
| occupation | string | null | Occupation the site assigns, for example ohjelmistokehittäjä. |
| category | string | null | Job category, for example tieto- ja tietoliikennetekniikka. |
| postedDate | string | null | When the job was published (ISO 8601, UTC). |
| validThrough | string | null | Application deadline (ISO 8601, UTC). |
| applyUrl | string | null | Where to apply (the employer's or the recruiting system's form). |
| applicationType | string | null | How the site sends applicants on, as its own data layer names it. |
| description | string | null | Full job description as plain text. |
| descriptionHtml | string | null | Job description HTML from the job page. |
| descriptionMarkdown | string | null | Job description converted to Markdown. |
| extractedEmails | array | null | E-mail addresses found in the description. |
| extractedPhones | array | null | Phone numbers found in the description. |
| extractedUrls | array | null | Links found in the description (duunitori.fi links excluded). |
| socialProfiles | object | null | LinkedIn, X/Twitter, Instagram, Facebook, YouTube, TikTok and GitHub links found in the description. |
| imageUrl | string | null | The job's own share or banner image (the site's generic image is left out). |
| detailsLoaded | boolean | null | True when the job page was read for this row. |
| detailsError | string | null | Why the job page could not be read; the row then has the list data only. |
| changeType | string | null | new or updated, in 'Only new and changed jobs' mode. |
| searchQuery | string | null | The keyword that found this job. |
| searchLocation | string | null | The location(s) of that search. |
| position | number | null | Position in the search results. |
| source | string | null | Always duunitori.fi. |
| scrapedAt | string | null | When the row was saved (UTC). |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Job | One saved job listing. | $0.001 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('openrole/duunitori-scraper').call({
"searchQueries": [
"ohjelmistokehittäjä"
],
"locations": [
"Helsinki"
],
"maxResults": 20,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"RESIDENTIAL"
],
"scrapelyProxyCountry": "FI"
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run openrole/duunitori-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=openrole/duunitori-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
No examples yet
The developer hasn't published example inputs for this actor.

Scrape Google Maps places for any search term and city, with no code or with one API call. A real run, its output, its log and its exact cost, plus the limits and the legal side.
Read the article
Paste an Amazon search or product URL into a ready-made Actor and get one row per product with price, ASIN, rating and review count. This guide covers the no-code steps, the API, ZIP code pricing, a real run and its cost.
Read the article
Scrape Google search results by query and country and get each results page as JSON: organic results with positions, People Also Ask and related searches. Run it without code or from Python, with a real run, the cost per page and Google's terms.
Read the articleScrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.