jobs.ch Switzerland Job Listings Scraper avatar

jobs.ch Switzerland Job Listings Scraper

Pricing

from $0.96 / 1,000 item extracteds

Go to Apify Store
jobs.ch Switzerland Job Listings Scraper

jobs.ch Switzerland Job Listings Scraper

Search jobs.ch and export complete Swiss vacancy records with employers, locations, workload, descriptions, posting dates, and application URLs.

Pricing

from $0.96 / 1,000 item extracteds

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Search jobs.ch and export complete Swiss vacancy records for recruiting feeds, hiring research, and labor-market analysis. The Actor accepts occupation keywords, a Swiss location, pre-filtered jobs.ch search URLs, and individual vacancy URLs.

Each result includes the job title, employer, structured location, workload range, employment classifications, posting context, full description, canonical jobs.ch URL, and direct application destination when the employer publishes one.

What can this jobs scraper do?

  • Search current jobs.ch vacancies by one or more keywords.
  • Apply one location to generated searches.
  • Preserve filters from supplied jobs.ch search URLs.
  • Process individual public vacancy detail URLs.
  • Follow result pagination up to a configurable safety limit.
  • Export full text and HTML descriptions.
  • Deduplicate vacancies by their stable jobs.ch UUID.
  • Produce JSON, CSV, Excel, XML, RSS, or another Apify dataset export.
  • Run on an Apify Schedule to refresh a recruiting feed.

The Actor reads server-rendered public jobs.ch pages over HTTP. It does not require a jobs.ch account, browser, or automatic residential proxy fallback.

Who is this Actor for?

Recruiting teams can build focused candidate-market and vacancy feeds for roles they hire repeatedly.

Job aggregators can normalize current Swiss listings into a downstream search index or spreadsheet.

Labor-market analysts can compare employers, locations, workload percentages, and posting dates over repeated dataset snapshots.

Data engineers can send scheduled run results to a warehouse, webhook, Make, Zapier, Google Sheets, or another Apify Actor.

Job seekers and career services can collect a bounded set of relevant vacancies for review without copying pages manually.

What data does it extract?

FieldMeaning
jobIdStable jobs.ch vacancy UUID
titleAdvertised job title
company, companyId, companyUrlEmployer identity and public jobs.ch profile
locationPrimary display location
locationsStructured address, canton, country, and coordinates when published
workloadMin, workloadMaxAdvertised workload percentage range
employmentTypeIdsjobs.ch employment-type classifications
employmentPositionIdsjobs.ch employment-level classifications
languageSkillsRequested languages and source proficiency levels
skillsSkill labels when jobs.ch publishes them
descriptionTextNormalized plain-text vacancy description
descriptionHtmlOriginal description HTML
publicationDateCurrent publication timestamp
initialPublicationDateInitial posting timestamp, useful for repost analysis
isActiveWhether the source marks the job as active
applicationUrlDirect application destination when available
applicationMethodSource application-method classification
canonicalUrlCanonical public jobs.ch detail URL
searchContextSearch URL that discovered the job
scrapedAtTimestamp when this Actor produced the row

Source fields can be null when an employer does not publish them. Employment IDs are preserved as source values rather than given speculative labels.

How to scrape jobs.ch vacancies

  1. Open the Actor input page.
  2. Enter one or more values in Search terms, such as software engineer or data analyst.
  3. Optionally enter a location such as Zurich, Bern, or Basel.
  4. Set Maximum jobs to the number of complete records you need.
  5. Click Start.
  6. Open the Dataset tab to review or export the results.

For an existing jobs.ch filter combination, paste its search URL into jobs.ch search or vacancy URLs. For one known vacancy, paste its detail URL instead.

Input parameters

InputTypeDefaultDescription
searchTermsstring arraysoftware engineerOccupations, titles, or keywords searched on jobs.ch
locationstringoptionalCity, canton, or region applied to generated searches
startUrlsrequest listoptionalPublic jobs.ch search or vacancy detail URLs
maxItemsinteger50Maximum complete vacancy rows across all inputs
maxPagesinteger20Maximum result pages fetched per search seed
proxyConfigurationobjectdirectOptional Apify Proxy settings

Provide at least one search term or start URL. Only public jobs.ch vacancy search and detail URLs are accepted. Unsupported domains fail with a clear non-zero error.

Example input

{
"searchTerms": ["data analyst"],
"location": "Zurich",
"maxItems": 10,
"maxPages": 2
}

Use a filtered jobs.ch URL

{
"startUrls": [
{ "url": "https://www.jobs.ch/en/vacancies/?term=project%20manager&location=Bern" }
],
"maxItems": 20,
"maxPages": 3
}

Output example

This shortened example reflects the current output shape; values vary with live vacancies.

{
"jobId": "11111111-2222-4333-8444-555555555555",
"title": "Software Engineer",
"company": "Example Technology AG",
"location": "Zurich",
"locations": [
{ "postalCode": "8000", "city": "Zurich", "cantonCode": "ZH", "countryCode": "CH" }
],
"workloadMin": 80,
"workloadMax": 100,
"employmentTypeIds": ["5"],
"languageSkills": [{ "language": "de", "level": 3 }],
"descriptionText": "Join our engineering team...",
"publicationDate": "2026-08-20T09:00:00+02:00",
"initialPublicationDate": "2026-08-15T09:00:00+02:00",
"isActive": true,
"applicationUrl": "https://careers.example.org/jobs/engineering-role/apply",
"applicationMethod": "APPLICATION_METHOD.EXTERNAL",
"canonicalUrl": "https://www.jobs.ch/en/vacancies/detail/11111111-2222-4333-8444-555555555555/",
"scrapedAt": "2026-08-31T12:00:00.000Z"
}

How much does it cost to scrape jobs.ch job listings?

The Actor uses pay-per-event pricing:

  • Actor start: $0.005 once per run.
  • Job listing: the active tier price for each complete vacancy saved. The BRONZE reference price is $0.0016 per job, with lower per-item rates on higher Apify tiers.

At the BRONZE reference rate, calculate a run as the $0.005 start event plus the number of complete jobs multiplied by $0.0016. For example, use 0.005 + (10 × 0.0016) for 10 jobs, 0.005 + (100 × 0.0016) for 100 jobs, or 0.005 + (1000 × 0.0016) for 1,000 jobs.

Only complete saved vacancies produce job-listing events. Duplicate, rejected, or failed records do not. Apify plan tier and platform rounding can affect the final amount shown in Console.

Build a recurring Swiss recruiting feed

Create an Apify Task with a stable keyword/location combination or a pre-filtered jobs.ch URL. Attach a Schedule, then consume each run's default dataset through the API or an integration.

A common workflow is:

  1. Run daily with a bounded maxItems.
  2. Save jobId, publicationDate, and initialPublicationDate in your database.
  3. Upsert by jobId.
  4. Flag IDs first seen in the newest run as new vacancies.
  5. Compare changed posting fields without treating an updated timestamp as a new identity.

The Actor does not maintain a hidden cross-run history or send alerts itself. Your dataset consumer owns comparison, retention, and notification logic.

Export to spreadsheets and data pipelines

From the Dataset tab, choose JSON, CSV, Excel, XML, or RSS. For automation, use the dataset API URL returned with the run.

Useful integrations include:

  • Google Sheets for recruiter review queues.
  • Make or Zapier for workflow routing.
  • Webhooks for triggering an ETL job after a successful run.
  • Snowflake, BigQuery, PostgreSQL, or object storage for longitudinal analysis.
  • Another Actor for deduplication, enrichment, or delivery.

Keep the stable jobId as your primary source key. Use scrapedAt as collection metadata, not as the vacancy publication date.

Run through the Apify API

Replace YOUR_APIFY_TOKEN with your token.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~jobs-ch-listings-scraper/runs?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms":["software engineer"],"location":"Zurich","maxItems":10}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/jobs-ch-listings-scraper').call({
searchTerms: ['software engineer'],
location: 'Zurich',
maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("automation-lab/jobs-ch-listings-scraper").call(run_input={
"searchTerms": ["software engineer"],
"location": "Zurich",
"maxItems": 10,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Use with MCP and AI assistants

Claude Code

Add the Actor to Claude Code through Apify's MCP server:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/jobs-ch-listings-scraper"

Claude Desktop, Cursor, and VS Code

Claude Desktop, Cursor, and VS Code can use equivalent MCP JSON:

{
"mcpServers": {
"apify": {
"type": "http",
"url": "https://mcp.apify.com?tools=automation-lab/jobs-ch-listings-scraper"
}
}
}

Example prompts:

  • “Find 20 current data analyst jobs in Zurich and summarize the advertised workload ranges.”
  • “Export project manager vacancies from this jobs.ch search URL and group them by employer.”
  • “Run my saved Swiss software engineering feed and return IDs that are absent from yesterday's table.”

An assistant can run the Actor, but it needs your Apify authorization and remains subject to your chosen limits and charges.

Reliability, limits, and failure behavior

  • jobs.ch is a live third-party source; fields and availability can change.
  • Search relevance and location interpretation are controlled by jobs.ch.
  • Some employers do not publish an external application URL, structured skills, or a complete address.
  • The Actor uses direct HTTP by default and does not download vacancy images or videos.
  • Transient network, HTTP 429, and upstream 5xx failures receive up to three bounded attempts.
  • A missing expected page-state object or mismatched detail ID fails loudly instead of returning a misleading empty success.
  • maxPages bounds discovery work; maxItems bounds the number of saved records.
  • Multiple seeds are deduplicated by vacancy UUID.

If a run unexpectedly returns no jobs, open the source search URL in a browser and confirm the same filters currently have results.

Responsible use and legality

Use this Actor only for lawful purposes and public data you are entitled to process. Respect jobs.ch terms, applicable copyright and database rights, privacy rules, and the rights of employers and applicants.

Do not use vacancy data for discriminatory decisions, spam, impersonation, or intrusive profiling. Avoid collecting more data than your workflow needs, set reasonable schedules, and define retention and deletion rules for exported datasets.

This Actor is an independent automation tool and is not affiliated with or endorsed by jobs.ch or JobCloud.

FAQ and troubleshooting

Why did my URL fail immediately?

The Actor accepts only public jobs.ch vacancy search and detail URLs. Company, account, application-form, and third-party URLs are intentionally rejected. Use a search URL under /vacancies/ or a public vacancy detail URL.

Why is applicationUrl null?

The employer may not publish a direct external destination in the public detail record. canonicalUrl still points to the jobs.ch vacancy page.

Why are there fewer rows than maxItems?

maxItems is a ceiling, not a promise. The search can exhaust its available pages, duplicate IDs can appear across seeds, or a source record can be skipped if it lacks a valid title.

Can it monitor changes automatically?

Schedule the Actor and compare stable IDs in your own destination. The Actor exports fresh records but does not keep hidden historical state or send alerts.

Does it need a Swiss proxy?

Not currently. The required public server-rendered data works through direct HTTP. You can supply an Apify proxy configuration if your environment requires one; there is no automatic residential fallback.

Support

If jobs.ch changes its public page shape or a valid vacancy URL fails, open an issue from the Actor page. Include a redacted input, run ID, expected behavior, and the first relevant error line. Do not include Apify tokens or private applicant information.