Jobs.ch Scraper - Swiss Job Board Data Extraction
Pricing
from $2.49 / 1,000 job search results
Jobs.ch Scraper - Swiss Job Board Data Extraction
Scrapes job listings from jobs.ch, Switzerland's largest job board powered by JobCloud.
Pricing
from $2.49 / 1,000 job search results
Rating
4.7
(3)
Developer
Ale
Maintained by CommunityActor stats
6
Bookmarked
60
Total users
21
Monthly active users
2 hours
Issues response
10 days ago
Last modified
Categories
Share
Jobs.ch Job Scraper
Scrapes job listings from jobs.ch, Switzerland's largest job board powered by JobCloud.
Four Scraping Modes
This scraper supports four distinct modes for different use cases:
| Mode | Input | Output | Use Case |
|---|---|---|---|
| SEARCH MODE | Search queries + filters | Basic or full job data | New job discovery, market analysis |
| START URL MODE | startUrls: [...] | Basic or full job data | Paste pre-filtered jobs.ch URLs — easiest way to scrape |
| COMPANY MODE | companyNames: [...] | All jobs from companies | Monitor specific companies' hiring |
| DIRECT URLS MODE | directUrls: [...] | Full job data + job_status | Still-alive checks, re-scraping specific jobs |
Use with AI Agents (MCP)
Connect this actor to any MCP-compatible AI client — Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, or custom agents.
Apify MCP server URL:
https://mcp.apify.com?tools=santamaria-automations/jobs-ch-scraper
Example prompt once connected:
"Use
jobs-ch-scraperto scrape job listings from jobs ch. Return results as a table."
Clients that support dynamic tool discovery (Claude.ai, VS Code) will receive the full input schema automatically via add-actor.
Features
- Publication date filter - Only return jobs posted in the last 1, 3, 7, or 30 days — ideal for daily scrapes
- Start URL mode - Paste pre-filtered jobs.ch search URLs — the actor extracts all filters automatically
- Multi-query search - Run multiple search keywords in a single run with deduplication
- Multi-location search - Search across multiple cities or regions in a single run
- Multi-canton search - Select multiple Swiss cantons at once (ZH, BE, AG, etc.) with strict filtering
- Concurrent detail fetching - Fetches job detail pages in parallel (configurable, default 10 workers)
- Multi-language support - Search in German, French, or English
- Employment type filter - Filter by permanent, temporary, or freelance positions
- Workload filter - Filter by Pensum percentage (e.g., 40-60% for part-time)
- Nationwide coverage - Access jobs from all Swiss cantons and regions
- Comprehensive job data - Extracts title, company, location, salary, workload, contact details, and more
- HR company filtering - Filter out recruitment agencies to get direct employer postings, or filter to only show HR agencies
- Standardized output - Returns data in the
JobListingschema format withsearch_querytracking - Job status detection - Identify online, offline, or expired jobs in Direct URLs mode
Pricing
Pay-per-event pricing:
| Event | Price |
|---|---|
| Actor start | $0.05 |
| Search result (per job in SERP) | $0.00275 (~$2.75 / 1000 jobs) |
| Detail page (full job data) | $0.005 (~$5 / 1000 jobs) |
Example: A run fetching 1000 jobs with full details costs $0.05 + $2.75 + $5.00 = **$7.80**.
Input
| Field | Type | Description | Default |
|---|---|---|---|
startUrls | string[] | Pre-filtered jobs.ch search URLs — extracts all filters from URL | [] |
directUrls | string[] | Direct job URLs to scrape (skips search mode) | [] |
companyNames | string[] | Company names to search for | [] |
searchQueries | string[] | One or more search keywords (deduplicated across queries) | ["Software Engineer"] |
locations | string[] | One or more city/region names (e.g., "Zurich", "Basel") | [] (all Switzerland) |
cantons | string[] | One or more canton codes (e.g., "ZH", "BE", "AG") — multi-select | [] (all cantons) |
language | string | Search language: de, fr, or en | de |
maxResultsPerQuery | integer | Maximum results per query/location/canton combination | 100 |
maxResults | integer | Total cap across all queries (0 = unlimited) | 0 |
employmentType | string | Filter by type: permanent, temporary, freelance | "" (all) |
workloadMin | integer | Minimum workload/Pensum percentage (0-100) | - |
workloadMax | integer | Maximum workload/Pensum percentage (0-100) | - |
publicationDate | string | Filter by posting age: 1 (24h), 3 (3 days), 7 (7 days), 30 (30 days) | "" (any time) |
searchMode | string | semantic (AI-powered) or classic (keyword matching) | semantic |
includeJobDetails | boolean | Fetch full job descriptions | true |
maxConcurrency | integer | Parallel detail page workers (1-50) | 10 |
companyFilter | string | Filter by company type: all, exclude-hr, only-hr | all |
proxyConfiguration | object | Apify proxy settings (datacenter is sufficient) | Datacenter |
Mode 1: START URL MODE (Easiest)
The simplest way to scrape: configure your search on jobs.ch with all the filters you want, copy the URL from your browser, and paste it here. The actor extracts all filters automatically — keywords, locations, cantons, categories, industries, employment type, workload, and more.
{"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}
You can also 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 MODE (Multi-Query)
Search for jobs using multiple keywords, locations, and cantons. Each combination runs as a separate search, results are deduplicated:
{"searchQueries": ["Software Engineer", "Softwareentwickler", "Backend Developer"],"locations": ["Zurich", "Basel"],"cantons": [],"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}
Mode 3: DIRECT URLS MODE (Still Alive Checks)
When directUrls is provided, the scraper operates in direct mode:
- Skips search phase - Goes directly to provided job URLs
- Job status detection - Returns
online,offline,expired, orunknown - Full data extraction - Same as detail page scraping
- Use case: Periodic "still alive" checks, re-scraping specific jobs 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/"]}
Direct URLs mode workflow:
- Provide array of Jobs.ch job detail URLs
- Scraper visits each URL directly
- Detects if job is still online or has been removed
- Extracts full job data if available
- Returns
job_statusfield indicating availability
Language Support
Jobs.ch is a multilingual platform. Choose your preferred search language:
| Language | Code | Description |
|---|---|---|
| German | de | Default - most listings in German-speaking regions |
| French | fr | Listings in French-speaking regions (Romandie) |
| English | en | International positions and English-language listings |
Note: The language parameter sets the UI language but jobs are shown in all languages based on your search criteria.
Canton Filter
Select one or more Swiss cantons for regional job searches. Multiple cantons can be selected at once. Each canton gets its own result quota — for example, with maxResultsPerQuery: 20 and 3 cantons selected, you get up to 20 jobs per canton (60 total).
Results are strictly filtered: the actor resolves each job's actual canton using Swiss postal codes (PLZ), canton suffixes in place names (e.g. "Dättwil AG"), and a 200+ city mapping. Only jobs confirmed to be in a selected canton are returned.
| Canton | Code | Major Cities |
|---|---|---|
| Zurich | ZH | Zurich, Winterthur |
| Bern | BE | Bern, Biel/Bienne |
| Aargau | AG | Aarau, Baden |
| Geneva | GE | Geneva |
| Vaud | VD | Lausanne, Montreux |
| Basel-Stadt | BS | Basel |
| St. Gallen | SG | St. Gallen |
| Ticino | TI | Lugano, Bellinzona |
See full list of 26 cantons in the input schema.
Employment Type
Filter jobs by contract type:
| Type | Description |
|---|---|
permanent | Permanent/unlimited contracts (Festanstellung) |
temporary | Temporary/fixed-term contracts (Temporar) |
freelance | Freelance/contract work (Freiberuflich) |
Workload Filter (Pensum)
Filter jobs by workload percentage:
| Example | Description |
|---|---|
workloadMin: 80 | Jobs with at least 80% workload (typically full-time) |
workloadMax: 60 | Part-time jobs up to 60% |
workloadMin: 40, workloadMax: 60 | Part-time jobs between 40-60% |
This is useful for finding specific part-time or full-time positions.
HR Company Filtering
Filter jobs by company type:
| Option | Description |
|---|---|
all | Include all companies (default) |
exclude-hr | Remove HR/recruitment agencies (e.g., Adecco, Randstad, Manpower) |
only-hr | Show only HR/recruitment agency postings |
The filter detects HR companies by matching company names against common patterns.
Example Input
Start URL (Easiest — Copy from Browser)
{"startUrls": ["https://www.jobs.ch/de/stellenangebote/?term=Software+Engineer&location=z%C3%BCrich&location=bern&category=171&employment-type=5"],"maxResults": 200}
Multi-Query + Multi-Location (IT Jobs in Zurich & Basel)
{"searchQueries": ["Software Engineer", "Softwareentwickler", "DevOps"],"locations": ["Zurich", "Basel"],"maxResultsPerQuery": 100,"maxResults": 0}
Multi-Canton Search (All Jobs in ZH, BE, BS)
{"searchQueries": [""],"cantons": ["ZH", "BE", "BS"],"maxResultsPerQuery": 500}
Part-Time Jobs in Basel (40-60%)
{"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 (Last 24 Hours)
Use publicationDate to avoid re-fetching old listings. Ideal for daily scheduled runs:
{"searchQueries": ["Software Engineer"],"locations": ["Zurich"],"publicationDate": "1","maxResultsPerQuery": 100}
The date filter also works in Start URL mode — just include publication-date=N in your URL:
{"startUrls": ["https://www.jobs.ch/de/stellenangebote/?term=softwareentwickler®ion=13&publication-date=1"],"maxResults": 100}
Direct URLs - Still Alive Check
{"directUrls": ["https://www.jobs.ch/de/stellenangebote/detail/b475b944-eab5-4d69-b251-a325bd272d62/","https://www.jobs.ch/de/stellenangebote/detail/a123b456-cd78-9012-efab-345678901234/"]}
Output
Each job listing follows the standardized JobListing schema:
{"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","top_listing": null,"employment_type": "full-time","workload_min": 80,"workload_max": 90,"remote_option": null,"salary_text": null,"description_snippet": "Fuer unseren Bereich in der Kinder- und Jugendpsychiatrie...","description_full": "Full job description text...","requirements": ["Erfahrung im Bereich der Kinder- und Jugendpsychiatrie", "Offene, kommunikative Persoenlichkeit"],"posted_at": "2025-12-10T15:36:17.000Z","expires_at": null,"source_url": "https://www.jobs.ch/de/stellenangebote/detail/b475b944-eab5-4d69-b251-a325bd272d62/","source_platform": "jobs.ch","contact_salutation": "Frau","contact_firstname": "Irene","contact_lastname": "Walczewski","contact_email": null,"contact_phone": "+41 44 929 83 73","contact_raw": "Irene Walczewski","apply_url": null,"apply_email": null,"company_url": "https://www.jobs.ch/de/firmen/23141-clienia-schlossli-ag/","company_website": "https://www.clienia.ch/de/","company_industry": "Health care / Social services","company_employee_count": "501 - 1000 employees","company_job_count": 21,"company_jobs_url": "https://www.jobs.ch/de/firmen/23141-clienia-schlossli-ag/stellenangebote/","company_description": null,"company_rating": 2.5,"company_review_count": 8,"company_reviews_url": "https://www.jobs.ch/de/firmen/23141-clienia-schlossli-ag/bewertungen/","company_social_urls": null,"company_benefits": ["5 Wochen Ferien", "Attraktive Arbeitszeitformen", "Foerderung von Fort- und Weiterbildungen"],"search_query": "Pflegefachperson","scraped_at": "2025-12-11T14:16:53.609Z"}
Output Fields
| Field | Description |
|---|---|
id | Unique job posting ID |
title | Job title |
company | Company name |
location | City/location name |
work_address | Full work address (street, postal code, city) |
canton | Swiss canton code (ZH, BE, AG, etc.) |
job_status | Job availability: online, offline, expired, unknown (Direct URLs mode only) |
top_listing | Boolean - if job is a paid promotion (Direct URLs: always null) |
employment_type | permanent, temporary, freelance, full-time, part-time |
workload_min | Minimum workload percentage (Pensum) |
workload_max | Maximum workload percentage (Pensum) |
remote_option | remote, hybrid, onsite, or null |
salary_text | Salary as displayed (if available) |
description_snippet | First 500 characters of description |
description_full | Complete job description |
requirements | Array of job requirements |
posted_at | Publication date |
expires_at | Expiration date (if available) |
source_url | Link to job posting (language-specific URL) |
source_platform | Always "jobs.ch" |
contact_salutation | "Herr" or "Frau" |
contact_firstname | Contact person first name |
contact_lastname | Contact person last name |
contact_email | Contact email address |
contact_phone | Contact phone number |
contact_raw | Raw contact text |
apply_url | External application URL |
apply_email | Application email address |
company_url | Company profile URL on jobs.ch |
company_website | Company's external website |
company_industry | Company industry/sector |
company_employee_count | Employee count range (e.g., "501 - 1000 employees") |
company_job_count | Number of open positions at company |
company_jobs_url | URL to company's job listings |
company_rating | Company rating (0-5 stars) |
company_review_count | Number of company reviews |
company_reviews_url | URL to company reviews page |
company_benefits | Array of company benefits |
search_query | The search keyword that found this job (null for direct URLs) |
scraped_at | Timestamp when the job was scraped |
Notes on job_status field:
- Only populated in Direct URLs mode (Mode 3)
- In Search modes (Mode 1 & 2), this field is
nullsince jobs from search results are assumed to be online - Values:
online- Job is currently availableoffline- Job page returns 404 or "not found"expired- Job explicitly marked as expiredunknown- Unable to determine status
Performance
Detail page fetching runs in parallel with configurable concurrency (maxConcurrency, default 10). With 10 workers, fetching 60 jobs with full details across 3 cantons takes about 1-2 minutes. Adjust maxConcurrency up to 50 for faster results.
Datacenter proxies are sufficient — jobs.ch has no anti-bot protection on its API or detail pages. No residential proxies needed.
Usage
Via Apify Console
- Go to the actor page
- Configure input parameters
- Click "Start"
- Download results from the Dataset tab (JSON, CSV, Excel)
Via API
curl -X POST "https://api.apify.com/v2/acts/santamaria-automations~jobs-ch-scraper/runs" \-H "Authorization: Bearer YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"searchQueries": ["Data Scientist", "Machine Learning Engineer"],"cantons": ["ZH", "BE"],"maxResultsPerQuery": 100}'
Via Apify SDK
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('santamaria-automations/jobs-ch-scraper').call({searchQueries: ['Marketing Manager', 'Product Manager'],locations: ['Zurich', 'Basel'],employmentType: 'permanent',maxResultsPerQuery: 150,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Found ${items.length} jobs`);
Coverage
Jobs.ch is Switzerland's largest job board, covering all 26 cantons:
German-Speaking Regions
- Zurich (ZH), Bern (BE), Luzern (LU), Aargau (AG)
- St. Gallen (SG), Basel (BS/BL), Thurgau (TG)
- Solothurn (SO), Schaffhausen (SH), Graubunden (GR)
French-Speaking Regions (Romandie)
- Geneva (GE), Vaud (VD), Fribourg (FR)
- Neuchatel (NE), Valais (VS), Jura (JU)
Italian-Speaking Region
- Ticino (TI)
Data Source
This actor scrapes data from Switzerland's largest job board:
- Website: jobs.ch
- Coverage: All of Switzerland (26 cantons)
- Platform: Powered by JobCloud
Common Use Cases
- Job market analysis: Track hiring trends by region/category
- Competitive intelligence: Monitor competitors' hiring
- Job aggregation: Build job search platforms
- Still-alive monitoring: Check if previously scraped jobs are still active (Direct URLs mode)
- Post-deduplication enrichment: Scrape basic data first, then fetch details for new jobs only
- Career research: Analyze salary ranges and requirements
- Recruitment sourcing: Find candidates via company postings
Legal Notice
This actor accesses publicly available job listings. Please ensure your use case complies with jobs.ch terms of service.
Issues & Support
Found a bug or have a feature request? Open an issue on the actor's Issues tab.
Related Actors
Looking for more job data? Check out our other scrapers:
Switzerland
Germany
Global
Enrich your job data
- Website Job Extractor -- Extract jobs directly from company career pages
- Website Contact Extractor -- Get emails and phone numbers from company websites
- Website Email & Phone Scraper -- Fast email and phone extraction
Part of the Santamaria Job Scrapers Suite - Professional-grade job data for the DACH region and beyond.
Need help with integration, aggregation, or custom scraping solutions? Contact us at contact@nanoscrape.com