Jobs.ch Scraper - Swiss Job Board avatar

Jobs.ch Scraper - Swiss Job Board

Pricing

from $2.20 / 1,000 jobs

Go to Apify Store
Jobs.ch Scraper - Swiss Job Board

Jobs.ch Scraper - Swiss Job Board

Scrape job listings from Jobs.ch: search by keyword, location, or canton, paste a pre-filtered search URL, or check specific job URLs. Full descriptions, contacts, and company data. Export JSON, CSV, Excel.

Pricing

from $2.20 / 1,000 jobs

Rating

0.0

(0)

Developer

ParseBird

ParseBird

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Jobs.ch Scraper - Swiss Job Board

Jobs.ch Scraper extracts job listings from Jobs.ch, Switzerland's largest job board: full descriptions, requirements, contacts, salary ranges, and company profile data — filtered by keyword, canton, or location.

Paste a jobs.ch search URL, search by keyword and canton, or re-check specific job URLs for still-alive status — with strict canton filtering and full contact/company enrichment on every listing.

Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

parsebird/jobs-ch-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/jobs-ch-scraper").call(run_input={"searchQueries":["Software Engineer"],"locations":["Zurich"],"maxResultsPerQuery":50}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Three modes: startUrls (array of pasted jobs.ch search URLs — filters extracted automatically), directUrls (array of job detail URLs — still-alive checks, returns job_status), or searchQueries + locations/cantons (array combinations, deduplicated by job ID). Key inputs: language (de|fr|en), maxResultsPerQuery, maxResults (0=unlimited), employmentType (permanent|temporary|freelance), workloadMin/workloadMax (0-100, strictly bounds the job's own posted range), publicationDate (1|3|7|30 days), companyFilter (all|exclude-hr|only-hr), includeJobDetails (boolean, full description/contacts/company data vs a fast title-only pass), maxConcurrency (1-50). Output rows include title, company, location, canton, employment_type, workload_min/max, description_full, requirements, contact_firstname/lastname/email/phone, apply_url/apply_email, company_website/rating/review_count/benefits, posted_at, source_url. Full actor spec: GET https://api.apify.com/v2/acts/parsebird~jobs-ch-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations

What is Jobs.ch Scraper?

Jobs.ch Scraper is an Apify Actor for extracting structured listing data from Jobs.ch, the largest job board in Switzerland, covering German-, French-, and English-language postings across all 26 cantons. Point it at a search URL, a set of keywords and cantons, or a list of specific job URLs, and it returns clean structured rows — title, company, location, full description, contacts, and company profile data.

Use it as a Jobs.ch API alternative, a Swiss job market research tool, or a repeatable pipeline for recruiting, lead generation, or labor-market analysis. Results download as JSON, CSV, Excel, XML, or HTML, or you can fetch them programmatically through the Apify API.

What can Jobs.ch Scraper do?

  • 🔗 Start URL mode — paste any jobs.ch search URL and every filter in it (keywords, locations, categories, employment type, workload) is extracted automatically
  • 🔎 Search mode — combine keywords × locations × cantons; every combination runs as its own search, deduplicated by job ID
  • ♻️ Direct URL mode — re-check specific job URLs and get back online, offline, or expired status, ideal for periodic "still alive" checks
  • 🗺️ Strict canton filtering — each selected canton gets its own result quota, and every job is confirmed to actually be in that canton before it's returned
  • 📋 Full detail enrichment — description, requirements, contact person, application links, salary text, and company profile (website, employee count, rating, reviews, benefits)
  • 🏢 HR agency filter — include or exclude recruitment-agency postings to focus on direct employers
  • ⏱️ Publication-date filter — pull only jobs posted in the last 1/3/7/30 days for daily scheduled monitoring
  • ⚙️ Fast mode — turn off full details for a cheap, quick title/company/location-only pass
  • 🔌 Run on demand, schedule recurring runs, or connect results to Apify integrations like Google Sheets, Zapier, Make, and webhooks

What data can you extract from Jobs.ch?

FieldDescription
title, company, location, cantonCore listing identity, with canton resolved and verified
employment_type, workload_min, workload_maxContract type and Pensum (workload) percentage range
description_full, requirementsFull job description and an extracted requirements list
contact_firstname, contact_lastname, contact_email, contact_phoneHiring contact, when published
apply_url, apply_emailWhere the application actually goes
company_website, company_employee_count, company_rating, company_benefitsCompany profile enrichment
posted_at, expires_atPublication and expiry dates
job_statusonline / offline / expired — Direct URL mode only

Input parameters

ParameterTypeDefaultDescription
startUrlsarray of strings[]Pre-filtered jobs.ch search URLs — filters extracted from the URL
directUrlsarray of strings[]Direct job URLs to check (still-alive mode)
companyNamesarray of strings[]Company names to search for
searchQueriesarray of strings["Software Engineer"]Keywords to search
locationsarray of strings[] (all Switzerland)City/region names, e.g. Zurich, Basel
cantonsarray of strings[] (all cantons)Canton codes, e.g. ZH, BE, AG
languagestringdede, fr, or en
maxResultsPerQueryinteger100Cap per keyword/location/canton combination
maxResultsinteger0Total cap across all queries. 0 = unlimited
employmentTypestring"" (all)permanent, temporary, or freelance
workloadMin / workloadMaxintegerWorkload / Pensum percentage (0-100)
publicationDatestring"" (any time)1, 3, 7, or 30 days
searchModestringsemanticsemantic (AI-powered) or classic (keyword matching)
includeJobDetailsbooleantrueFetch full descriptions, contacts, and company data
maxConcurrencyinteger10Parallel detail-page workers (1-50)
companyFilterstringallall, exclude-hr, or only-hr
proxyConfigurationobjectDatacenterApify proxy settings — datacenter is sufficient

Mode 1: Start URL (easiest)

Configure your search on jobs.ch with every filter you want, copy the URL from your browser, and paste it here:

{
"startUrls": [
"https://www.jobs.ch/de/stellenangebote/?term=javascript&location=st.%20gallen&location=z%C3%BCrich&category=171&category=174&employment-type=5&employment-grade-min=50&employment-grade-max=100"
],
"maxResults": 100
}

Combine multiple search URLs to scrape different filter combinations in one run:

{
"startUrls": [
"https://www.jobs.ch/de/stellenangebote/?term=Software+Engineer&location=z%C3%BCrich",
"https://www.jobs.ch/fr/offres-emplois/?term=Developpeur&location=gen%C3%A8ve"
],
"maxResults": 200
}

Mode 2: Search (multi-query)

Search multiple keywords, locations, and cantons at once — every combination runs as its own search, and results are deduplicated:

{
"searchQueries": ["Software Engineer", "Softwareentwickler", "Backend Developer"],
"locations": ["Zurich", "Basel"],
"maxResultsPerQuery": 100,
"maxResults": 0
}

With includeJobDetails: true (default), full descriptions, requirements, and contact details are fetched:

{
"searchQueries": ["Data Scientist", "Machine Learning"],
"cantons": ["ZH", "BE", "BS"],
"maxResultsPerQuery": 100,
"includeJobDetails": true
}

Every selected canton gets its own quota — with maxResultsPerQuery: 20 and 3 cantons, you get up to 20 jobs per canton (60 total), each one confirmed to actually be in that canton.

Mode 3: Direct URLs (still-alive checks)

When directUrls is set, the actor skips search entirely, visits each URL directly, and returns job_status (online, offline, or expired) plus full data if the job is still available — ideal for periodic re-checks after deduplication:

{
"directUrls": [
"https://www.jobs.ch/de/stellenangebote/detail/b475b944-eab5-4d69-b251-a325bd272d62/",
"https://www.jobs.ch/fr/offres-emplois/detail/a123b456-cd78-9012-efab-345678901234/",
"https://www.jobs.ch/en/vacancies/detail/c789d012-ef34-5678-90ab-cdef12345678/"
]
}

More examples

Part-time jobs in Basel (40-60% workload):

{
"searchQueries": ["Buchhaltung"],
"locations": ["Basel"],
"workloadMin": 40,
"workloadMax": 60,
"maxResultsPerQuery": 50
}

French-speaking region search:

{
"searchQueries": ["Infirmier", "Aide-soignant"],
"cantons": ["VD"],
"language": "fr",
"maxResultsPerQuery": 100
}

Direct employer postings only (no HR agencies):

{
"searchQueries": ["Marketing Manager"],
"locations": ["Zurich"],
"companyFilter": "exclude-hr",
"maxResultsPerQuery": 100
}

Daily scrape — only new listings from the last 24 hours:

{
"searchQueries": ["Software Engineer"],
"locations": ["Zurich"],
"publicationDate": "1",
"maxResultsPerQuery": 100
}

The date filter also works in Start URL mode — just include publication-date=N in the pasted URL.

Output example

{
"id": "b475b944-eab5-4d69-b251-a325bd272d62",
"title": "Diplomierte Pflegefachperson",
"company": "Clienia Schloessli AG",
"location": "Oetwil am See",
"work_address": "Schloesslistrasse 8, 8618 Oetwil am See",
"canton": "ZH",
"job_status": "online",
"employment_type": "full-time",
"workload_min": 80,
"workload_max": 90,
"description_snippet": "Fuer unseren Bereich in der Kinder- und Jugendpsychiatrie...",
"requirements": ["Erfahrung im Bereich der Kinder- und Jugendpsychiatrie", "Offene, kommunikative Persoenlichkeit"],
"posted_at": "2025-12-10T15:36:17.000Z",
"source_url": "https://www.jobs.ch/de/stellenangebote/detail/b475b944-eab5-4d69-b251-a325bd272d62/",
"source_platform": "jobs.ch",
"contact_firstname": "Irene",
"contact_lastname": "Walczewski",
"contact_phone": "+41 44 929 83 73",
"company_url": "https://www.jobs.ch/de/firmen/23141-clienia-schlossli-ag/",
"company_website": "https://www.clienia.ch/de/",
"company_employee_count": "501 - 1000 employees",
"company_job_count": 21,
"company_rating": 2.5,
"company_review_count": 8,
"company_benefits": ["5 Wochen Ferien", "Attraktive Arbeitszeitformen", "Foerderung von Fort- und Weiterbildungen"],
"search_query": "Pflegefachperson",
"scraped_at": "2026-08-17T14:16:53.609Z"
}

job_status is only populated in Direct URL mode — search-mode results are assumed online since they just came from live search results.

Download in JSON, HTML, CSV, or Excel from the dataset page, or fetch rows programmatically through the API.

How to scrape Jobs.ch listings

  1. Open Jobs.ch Scraper on Apify and click Try for free.
  2. Pick a mode: paste a search URL, enter keywords/locations/cantons, or paste direct job URLs.
  3. Set maxResultsPerQuery and maxResults to control run size and cost.
  4. Start the run and wait for the dataset to populate.
  5. Download results as JSON, CSV, Excel, HTML, XML, or RSS.
  6. Automate it with Apify scheduling, integrations, or the Apify API.

How to use the Jobs.ch API in Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("parsebird/jobs-ch-scraper").call(run_input={
"searchQueries": ["Data Scientist", "Machine Learning"],
"cantons": ["ZH", "BE", "BS"],
"maxResultsPerQuery": 100,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items[:2])

How to use the Jobs.ch API in JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('parsebird/jobs-ch-scraper').call({
searchQueries: ['Software Engineer'],
locations: ['Zurich', 'Basel'],
maxResultsPerQuery: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Use cases

  • Recruiting & sourcing — Pull direct-employer listings (excluding HR agencies) for a specific role and region
  • Labor market research — Compare workload, salary, and remote-work patterns across cantons
  • Lead generation — Extract company websites, industries, and hiring contacts from active job postings
  • Competitive monitoring — Track which roles a specific company is hiring for, canton by canton
  • Daily job alerts — Schedule a run with publicationDate: "1" to catch only new listings each day
  • Link health monitoring — Use Direct URL mode to periodically re-check whether saved job links are still live

How it works

  1. Resolves your input into one of three modes: pasted search URLs, keyword/location/canton combinations, or direct job URLs
  2. Calls jobs.ch's public search API and paginates through results
  3. Applies canton, location, workload, publication-date, and HR-agency filters locally — since jobs.ch's own PLZ/canton and workload data is richer than what the search API filters strictly enforce
  4. Deduplicates by job ID across every query combination in the run
  5. Optionally fetches each job's detail page and parses its full description, requirements, contacts, and company profile
  6. Pushes normalized rows to the dataset and stops once your spending limit is reached

How much does it cost to scrape Jobs.ch?

Jobs.ch Scraper uses pay-per-event pricing, with two events depending on how much data you request per job.

EventWhat it coversPrice per 1,000
job-searchA search-result row (title, company, location, dates) — used when includeJobDetails is off$2.50 / $2.40 / $2.30 / $2.20 (Free / Bronze / Silver / Gold)
job-detailA complete listing with full description, contacts, and company data — used when includeJobDetails is on (default)$4.50 / $4.40 / $4.30 / $4.20 (Free / Bronze / Silver / Gold)

Scraping 100 fully-enriched jobs costs about $0.45 on the Free plan; the same 100 jobs without details costs about $0.25. Apify's free trial credits cover typical test runs.

Jobs.ch Scraper extracts publicly available job listing data from the same public search endpoint jobs.ch's own website uses to render search results and job pages. Scraping publicly accessible data is generally lawful, but you're responsible for how you use the results — always review jobs.ch's Terms of Use and Apify's guide on the legality of web scraping before running large or automated workloads.

ActorBest for
Arbeitsagentur ScraperGermany's federal job board, useful alongside German-speaking Swiss searches
HelloWork Jobs ScraperFrench job listings, useful alongside French-speaking Swiss (Romandie) searches
Greenhouse Jobs ScraperCompany career pages running on the Greenhouse ATS

FAQ

How does canton filtering actually work? Each selected canton in cantons gets its own result quota (maxResultsPerQuery per canton). The actor resolves each job's canton from jobs.ch's own location data and only returns jobs confirmed to be in a selected canton — no guessing from city names alone.

What's the difference between locations and cantons? locations matches a job's city/place name (e.g. "Zurich" matches both "Zürich" and "Zurich"). cantons matches the canton code directly (e.g. "ZH"). Use whichever fits your search — both can be combined with keywords.

Why does workloadMax sometimes exclude a job with a wide workload range? If a job is posted as "50-100%", it genuinely doesn't fit a workloadMax: 60 (up to 60%) request — the actor strictly bounds the job's own posted range to your requested window, rather than returning any job that merely overlaps it.

What happens if a company doesn't publish a direct contact or email? Those fields come back null. Not every jobs.ch listing publishes a named contact, phone number, or email — the actor never fabricates one.

Can I re-check jobs I've already scraped without re-running search? Yes — that's exactly what Direct URL mode is for. Pass the job URLs you already have in directUrls and get back job_status (online, offline, expired) for each.

Can I schedule recurring runs? Yes. Use Apify scheduling to run daily or weekly — pair it with publicationDate: "1" for a clean "what's new today" feed.

How do I report a problem or request a field? Open an issue from the Actor page in Apify Console and include the run ID, input, and the job URL that needs review.