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
77
Total users
30
Monthly active users
0.63 hours
Issues response
2 days ago
Last modified
Categories
Features
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. Within a single run, a job matched by several keywords or locations is returned and charged once. With skipReposts on, jobs your search already returned in an earlier run are left out and not charged.
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 | Leave out jobs that the same search returned in a previous run (90-day history). Skipped jobs are not charged. |
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 the same search returned this job in a previous run (90-day history) |
isRepublished | boolean | true if the employer republished the listing on jobs.ch (publishDate later than initialPublishDate) |
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,"isRepublished": 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 that earlier runs of the same search have not already returned.
💰 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.
- Repost history is kept per search (same keywords, locations and filters) in your own Apify account for 90 days. Changing the search starts a fresh history.
- 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