Jobs.ch Scraper — Swiss Jobs, CHF Salary & Workload
Pricing
from $1.20 / 1,000 results
Jobs.ch Scraper — Swiss Jobs, CHF Salary & Workload
Scrape job listings from Jobs.ch — Switzerland's leading German-language job board. Structured output with CHF salary ranges, employment type, workload percentage, company details & full descriptions in HTML, text and Markdown. Repost detection. No API key required.
Pricing
from $1.20 / 1,000 results
Rating
0.0
(0)
Developer
Unfenced Group
Maintained by CommunityActor stats
1
Bookmarked
31
Total users
6
Monthly active users
3 days ago
Last modified
Categories
Share
Jobs.ch Scraper

Extract job listings from jobs.ch at scale, in a clean, consistent structure ready for analysis, job boards, recruiting tools and market research. No API key required.
Why this scraper?
🎯 Built for Switzerland
A dedicated Swiss scraper, not a global tool with a country dropdown. Search, locations and currency (CHF) are tuned for jobs.ch.
📄 Complete job data
Full job title and description, direct listing URL and publish date for every record.
🏢 Company details
Hiring company name plus the profile details the source publishes, such as logo and company page.
📍 Precise location
City, region and country plus latitude/longitude for mapping and radius analysis.
🔁 Repost & change detection
Every record carries isRepost and changeStatus, so daily feeds return genuinely new jobs instead of reposted duplicates.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
searchQuery | array | ["developer"] | One or more search keywords (e.g. 'developer', 'nurse'). Each keyword runs as a separate search. Leave empty to scrape all jobs. |
locations | array | (empty) | One or more locations to filter by (e.g. 'Zürich', 'Geneva', 'Bern'). Each location is combined with every keyword. Leave empty for all of Switzerland. |
language | string | "de" | Language of the job detail page. Affects the description language and the detail URL in the output. |
contractTypeFilter | string | "all" | Filter by contract type: all, permanent, temporary, freelance, internship, apprenticeship, supplementary. Applied server-side by jobs.ch. |
workloadMin | integer | 0 | Minimum workload (Pensum) percentage. Use 0 for no minimum. |
workloadMax | integer | 100 | Maximum workload (Pensum) percentage. Use 100 for no maximum. |
daysOld | integer | (empty) | Only include jobs published within this many days. Leave empty for no limit. Useful for incremental daily/weekly runs. |
fetchDetails | boolean | false | ON: fetches the full job description, industry, apply link and company website from each job page. OFF: returns listing data only (faster, lower cost). |
skipReposts | boolean | false | Skip jobs that have been seen in a previous run (cross-run deduplication via KeyValueStore fingerprinting, 90-day TTL). |
maxItems | integer | 100 | Maximum number of job listings to save. Leave empty to collect all available results. |
Output schema
Every field below is present on every record. Fields the source does not publish for a given job are returned as null rather than omitted.
| Field | Type | Description |
|---|---|---|
id | string | Jobs.ch internal listing ID |
url | string | Direct link to the listing |
title | string | Job title |
company | string | Hiring company name |
companyLogo | string | Company logo image URL |
isAnonymous | boolean | true when the employer publishes the listing without a company name |
companyWebsite | string | Company website. |
location | string | Location as displayed |
canton | string | Swiss canton, e.g. Bern, Zurich |
postalCode | string | Postal code of the workplace |
country | string | Country of the position. |
industry | string | Industry, or the occupational category jobs.ch assigns |
contractType | string | permanent, temporary, freelance, internship, apprenticeship, supplementary, or multiple when the listing accepts several |
contractTypeIds | array | Raw jobs.ch employment type ids behind contractType |
workload | string | Workload as displayed, e.g. 80–100% |
workloadMin | number | — |
workloadMax | number | — |
publishDate | string | Date posted |
initialPublishDate | string | Initial publish date. |
daysOld | number | — |
isRepost | boolean | true if seen in a previous run |
description | string | Full job description in plain text. |
descriptionText | string | Full job description in plain text. |
descriptionMarkdown | string | Description markdown. |
applyUrl | string | Application link as published by jobs.ch — the employer's own form, or the jobs.ch apply page for direct-apply listings. null when the listing names no apply target. |
directApply | boolean | true when the application runs through jobs.ch rather than the employer's site |
employerRating | object | null when the employer has no reviews |
employerRating.average | number | Average. |
employerRating.totalReviews | number | Total reviews. |
employerRating.leadership | number | Leadership. |
employerRating.salaryAndBenefits | number | Salary and benefits. |
employerRating.careerOpportunities | number | Career opportunities. |
employerRating.workAtmosphere | number | Work atmosphere. |
contentHash | string | Stable hash of the listing content, used for repost and change detection. |
scrapedAt | string | Timestamp when this record was scraped. |
latitude | number | Latitude of the workplace. |
longitude | number | Longitude of the workplace. |
changeStatus | string | NEW, CHANGED or UNCHANGED compared to the previous time this job was seen. |
Example record
{"id": "0c1e9ec0-c417-411e-8049-ffbc39390bd8","url": "https://www.jobs.ch/de/stellenangebote/detail/0c1e9ec0-c417-411e-8049-ffbc39390bd8/","title": "Pflegefachfrau/-mann Dialyse (60 -100%)","company": "Dialyse Bern AG","companyLogo": "https://media.jobs.ch/images/8c3de367-3f4a-452e-925f-4bbf1a349680/248x88.png","isAnonymous": false,"companyWebsite": "https://www.dialyse-bern.ch","location": "Ittigen","canton": "Bern","postalCode": "3063","country": "CH","industry": "Dienstleistung / Medizin / Pflege / Therapie / Akutpflege","contractType": "permanent","contractTypeIds": ["5"],"workload": "60-100%","workloadMin": 60,"workloadMax": 100,"publishDate": "2026-08-05","initialPublishDate": "2026-08-05","daysOld": 23,"isRepost": false,"description": "<p>Wir suchen ab sofort eine/n Pflegefachfrau/-mann Dialyse …</p>","descriptionText": "Wir suchen ab sofort eine/n Pflegefachfrau/-mann Dialyse …","descriptionMarkdown": "Wir suchen ab sofort eine/n Pflegefachfrau/-mann Dialyse …","applyUrl": null,"directApply": false,"employerRating": null,"contentHash": "8dc3fb5f0c89ef12","scrapedAt": "2026-08-28T07:34:32.881Z","latitude": 46.9723,"longitude": 7.4795,"changeStatus": "NEW"}
Examples
Search for Buchhalter roles in Zürich:
{"searchQuery": "Buchhalter","maxItems": 100}
Only jobs from the last 3 days:
{"searchQuery": "Buchhalter","maxItems": 100,"daysOld": 3}
Larger run with a hard cap:
{"searchQuery": "Buchhalter","maxItems": 500}
Daily feed (run on a schedule):
{"searchQuery": "Buchhalter","daysOld": 1,"skipReposts": true,"maxItems": 500}
Schedule this input to run once a day in the Apify Scheduler — each run returns only jobs posted in the last 24 hours.
💰 Pricing
$1.5 per 1,000 results — you only pay for successfully retrieved listings. Failed retries are never charged.
| Results | Cost |
|---|---|
| 100 | ~$0.15 |
| 1,000 | ~$1.5 |
| 10,000 | ~$15 |
| 100,000 | ~$150 |
Flat-rate alternatives typically charge $29–$49/month regardless of usage.
Subscription tiers lower the rate further, down to $0.9 per 1,000 at the highest tier. Use the Max results cap in the input to control your spend exactly.
Performance
Measured 28 August 2026 with full job details enabled.
| Run size | Typical time |
|---|---|
| 20 results | under 15 seconds |
| 100 results | under 1 minute |
| 1,000 results | 5–8 minutes |
Known limitations
- Salary is not returned. Jobs.ch publishes almost no salary figures in machine-readable form, so the scraper does not promise a field it cannot fill. Use
workloadandworkloadMin/workloadMaxfor the Pensum percentage. industry,applyUrl,directApplyand the full description requirefetchDetails: true; listing-only runs return them asnull.- Coordinates come from jobs.ch for most listings and are geocoded from the city for the rest.
- Company details vary per listing; the scraper returns what the source publishes and never invents data.
- Very large result sets are bounded by the source's own paging limits.
- Listings can be removed by the source at any time, so a small share of URLs may expire shortly after scraping.
Technical details
- Source: jobs.ch — Switzerland job listings
- Push notifications: get new results delivered to Telegram, Discord, Slack, WhatsApp or any webhook the moment a scheduled run finds them
- Coverage: everything the public search exposes, filterable via the input parameters above
- Retry: automatic retry on network errors with exponential backoff
Rate this actor
If this scraper does its job, a short review on the Reviews tab helps other users find it. Something not working? Open an issue on the Issues tab instead — issues get fixed.
Need a custom scraper?
Unfenced Group builds Apify actors for any website — for free.
If the site you need isn't in our portfolio yet, just ask. We scope, build, and publish it at no cost to you. You only pay for results — we absorb the compute and proxy costs ourselves. Same pay-per-result pricing, same quality, same standards as every actor in this portfolio.
Get in touch: www.unfencedgroup.nl