jobup.ch Scraper 🇨🇭 Romandie Jobs (Search + Detail) avatar

jobup.ch Scraper 🇨🇭 Romandie Jobs (Search + Detail)

Pricing

from $2.00 / 1,000 results

Go to Apify Store
jobup.ch Scraper 🇨🇭 Romandie Jobs (Search + Detail)

jobup.ch Scraper 🇨🇭 Romandie Jobs (Search + Detail)

Scrape jobup.ch — the #1 job board for French-speaking Switzerland (Geneva, Lausanne, Romandie). Search + full detail: title, company, location, canton, workload %, contract type, salary (CHF), full description, posted date. Fast JSON-API scraping, no browser. Pay-per-result.

Pricing

from $2.00 / 1,000 results

Rating

0.0

(0)

Developer

Crow Lee

Crow Lee

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

jobup.ch Scraper 🇨🇭 — Scrape French-Swiss Jobs / Romandie (no login, no API key)

Scrape job postings from jobup.ch, the #1 job board of French-speaking Switzerland (Geneva, Lausanne, and all of Romandie), into clean structured data — title, company, company logo, location, canton, workload percentage (the Swiss 80-100% convention), contract type, salary in CHF when published, full job description, remote-work flag, and ISO posted date. A practical jobup API alternative: no login and no API key required; export to JSON, CSV, Excel (XLSX), XML, or an HTML table, or pull results straight from the Apify API. Your $5 free Apify credit ≈ 3,300 full-detail jobs — enough to test seriously before spending a cent.

🔍 What does the jobup.ch Scraper do?

You give it a search (a keyword like infirmier or comptable plus a location like Genève or Lausanne, or any jobup.ch search URL) and it returns every matching job posting as a structured record. Built-in filters narrow the search server-side: publication date (last 24h / 3 / 7 / 30 days), employment types (durée indéterminée, temporaire, indépendant, stage, revenu complémentaire, apprentissage), and workload range (e.g. only 80-100% roles). It runs in two layers:

  • Search cards — fast list of jobs from the results pages (title, company, location, workload %, contract type, snippet, posted date).
  • Full detail (default) — fetches each job's detail record for the complete description, published salary (CHF), canton code, and the direct application URL.

Under the hood it talks to jobup.ch's own public JSON API over plain HTTP through a Swiss residential proxy — no browser rendering, so runs are fast and cheap. It paginates page by page and stops cleanly at your item budget or the API's 2,000-results-per-search ceiling.

👤 Who is it for?

  • Recruiters & staffing agencies — track open roles, hiring companies, and workloads across Romandie; build outreach lists by role, canton (GE, VD, VS, NE, FR, JU), and pensum.
  • Labour-market & HR analysts — measure demand by skill, contract type (permanent vs. temporary), and region; benchmark published CHF salaries in French-speaking Switzerland.
  • Job boards & aggregators — supplement your own inventory with Romandie coverage from the region's market leader.
  • Founders & sales teams — find companies that are actively hiring (a strong buying/growth signal) in Geneva, Lausanne, or a target sector.

⭐ Why use this scraper?

  • Romandie-focused — jobup.ch is where French-speaking Switzerland hires: Geneva, Vaud, Valais, Neuchâtel, Fribourg, Jura. Swiss conventions built in: workload as 80-100%, salaries in CHF, canton codes, searches in French or English.
  • API-grade data quality — records come from jobup.ch's own JSON API, not brittle HTML parsing: stable IDs, exact timestamps with timezone, structured salary ranges. Since jobup.ch offers no public developer API, this actor is the pragmatic jobup API alternative for programmatic access.
  • Server-side filters — publication date (24h/3d/7d/30d), employment types, and workload (pensum / taux d'occupation) range are applied in the jobup.ch API query itself, so you only pay for jobs that match.
  • No login, no API key — just a search or a URL.
  • Full job descriptions — the complete job-ad text as clean plain text, not just the snippet.
  • Budget-safemaxItems cap, dedup (you never pay twice for the same job), anti-runaway pagination caps.
  • All export formats — JSON, CSV, Excel, XML, HTML table, plus API and webhooks.

📊 What data can you extract from jobup.ch?

Data pointExample
titleInfirmier diplômé
companyFondation Résidence du Léman
companyUrlhttps://www.jobup.ch/fr/societes/33953-fondation-nos-penates/
companyLogohttps://media.jobup.ch/media/12bc0580-…?dimensions=320x0
locationCorseaux
canton (detail mode)VD
isRemotetrue when the title/description mentions télétravail / remote / home office
workloadPercent80-100%
contractTypeDurée indéterminée
salaryRawCHF 5200+ per month
salaryMin / salaryMax5200 / 6500
salaryCurrencyCHF
salaryPeriodmonth
descriptionSnippetLa Fondation Résidence du Léman à Corseaux, établissement médico-social…
description (detail mode)Full job-ad text as clean plain text
applicationUrl (detail mode)Direct apply link when the employer uses an external ATS
postedDate2026-07-04T00:02:35.000Z
publishedRaw2026-07-04T02:02:35+02:00
jobKeyb5e947c1-d42c-4352-8144-d4f3afaa6571
urlhttps://www.jobup.ch/fr/emplois/detail/b5e947c1-…/

Note: salaryRaw/salaryMin/salaryMax appear only when the employer publishes pay — most Swiss postings don't (salary transparency is not mandatory in Switzerland). description and applicationUrl are only populated when Scrape full detail pages is on.

💰 How much does it cost to scrape jobup.ch?

This actor uses Apify's pay-per-event pricing:

EventWhen it firesPrice (USD)Per 1,000
Actor startOnce per run$0.02
Job (search card)Per unique job, when Scrape full detail pages = off$0.0008$0.80
Job (full detail)Per unique job, when Scrape full detail pages = on (full description + salary + application URL)$0.0015$1.50

Your first results are free: the $5 free credit on Apify's free plan covers roughly 3,300 full-detail jobs (or ~6,200 search cards) — no credit card needed to start. Duplicates are never charged. Real-world cost examples:

RunItemsModeApprox. cost
Quick scan100 jobssearch cards only$0.02 + 100 × $0.0008 = $0.10
Standard100 jobsfull detail$0.02 + 100 × $0.0015 = $0.17
Deep pull500 jobsfull detail$0.02 + 500 × $0.0015 = $0.77
Max search2,000 jobsfull detail$0.02 + 2,000 × $0.0015 = $3.02

With the $5/month free Apify plan you can scrape roughly 3,300 full-detail jobs or 6,200 search cards per month at no cost. (Proxy traffic is included in your Apify plan's usage; the API-based approach keeps it minimal.)

🚀 How to scrape jobup.ch

  1. Open the actor on Apify and click Try for free.
  2. Enter a Search query (e.g. infirmier) and a Location (e.g. Genève) — or paste one or more jobup.ch search URLs into Search URLs.
  3. (Optional) Narrow with Posted within, Employment types, and Min/Max workload; set Max items and toggle Scrape full detail pages.
  4. Leave the proxy on RESIDENTIAL / Switzerland.
  5. Click Start, then Export results as JSON, CSV, Excel, XML, or HTML.

🧩 Input examples

Minimal — keyword + city:

{
"searchQuery": "infirmier",
"location": "Lausanne",
"maxItems": 100,
"scrapeDetails": true,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "CH" }
}

Filtered — fresh permanent 80-100% roles only:

{
"searchQuery": "comptable",
"location": "Genève",
"publicationDateFilter": "7d",
"employmentTypes": ["5"],
"workloadMin": 80,
"workloadMax": 100,
"maxItems": 200,
"scrapeDetails": true,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "CH" }
}

Multiple filtered searches — paste jobup.ch URLs (any language; filters like employment type, region, or publication date are preserved):

{
"startUrls": [
{ "url": "https://www.jobup.ch/fr/emplois/?term=ing%C3%A9nieur%20logiciel&location=Gen%C3%A8ve&employment-types=5" },
{ "url": "https://www.jobup.ch/fr/emplois/?term=infirmier&location=Lausanne" }
],
"maxItems": 300,
"scrapeDetails": true,
"maxConcurrency": 5,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "CH" }
}

⚙️ Input parameters

ParameterTypeDefaultDescription
startUrlsarrayjobup.ch search URLs (website or API form, any language). Overrides the query/location fields. All URL filters are preserved.
searchQuerystringJob keyword (the jobup.ch term), e.g. infirmier, comptable. Empty with no startUrls = browse all jobs.
locationstringCity, canton, or region, e.g. Genève, Lausanne, Fribourg. Empty = all of Switzerland.
publicationDateFilterstringanyOnly jobs posted within: 1d, 3d, 7d, 30d, or any. Applied server-side in the API query and re-checked on each record's postedDate.
employmentTypesarrayContract-type filter: "5" Durée indéterminée (permanent), "1" Temporaire, "2" Indépendant (freelance), "3" Stage, "4" Revenu complémentaire, "6" Apprentissage. Empty = all.
workloadMin / workloadMaxintegerWorkload (pensum) range 0-100, e.g. 80/100 for 80-100% roles. Maps to the jobup.ch employment-grade filter.
maxItemsinteger100Stop after this many jobs (0 = unlimited, capped at 2,000 per search by the jobup.ch API).
scrapeDetailsbooleantrueFetch each job's detail record for full description, salary, and application URL.
maxConcurrencyinteger5Parallel requests (capped at 10 internally to stay polite).
proxyConfigurationobjectRESIDENTIAL / CHRequired. Apify residential proxy, country Switzerland.

📤 Output example

A real record from query=infirmier (full-detail mode):

{
"url": "https://www.jobup.ch/fr/emplois/detail/b5e947c1-d42c-4352-8144-d4f3afaa6571/",
"jobKey": "b5e947c1-d42c-4352-8144-d4f3afaa6571",
"title": "Infirmier diplômé",
"company": "Fondation Résidence du Léman - Etablissement médico-social",
"companyUrl": "https://www.jobup.ch/fr/societes/bab63906-b9c5-43f1-b328-e7f6b25b492d-fondation-residence-du-leman-etablissement-medico-social/",
"companyLogo": "https://media.jobs.ch/media/6020d277-d0cb-4b6d-8cbe-9f37dc403bf9",
"location": "Corseaux",
"canton": "VD",
"isRemote": false,
"workloadPercent": "80-100%",
"contractType": "Durée indéterminée",
"salaryRaw": null,
"salaryMin": null,
"salaryMax": null,
"salaryCurrency": null,
"salaryPeriod": null,
"descriptionSnippet": "Infirmier diplômé \nLa Fondation Résidence du Léman à Corseaux, établissement médico-social de 46 lits à mission gériatrique et ...",
"description": "La Fondation Résidence du Léman à Corseaux, établissement médico-social de 46 lits à mission gériatrique et psychogériatrique compatible, est à la recherche d'un/e\n\nInfirmier / infirmière à 80-100%\nVos missions :\n• Assurer, développer et garantir la qualité des soins infirmiers…",
"applicationUrl": null,
"postedDate": "2026-07-08T08:37:00.000Z",
"publishedRaw": "2026-07-08T10:37:00+02:00",
"scrapedAt": "2026-07-11T15:06:44.081Z",
"source": "detail"
}

In search-card mode (scrapeDetails: false), description, canton, and applicationUrl are null and source is "search-card".

💡 Tips for best results

  • Start small. Run with maxItems: 20 first to validate your query, then scale up.
  • Use startUrls for precise filters. Build the exact search you want on jobup.ch (employment type, region, publication date, category…), then paste the URL — every filter is respected.
  • Beat the 2,000-result ceiling. The API caps one search at 2,000 results. Split broad queries into several startUrls (per canton, per employment type) to cover more.
  • Schedule it. Run daily with publicationDateFilter: "1d" to capture only postings from the last 24 hours — perfect for a fresh-jobs feed.
  • Search cards are half the requests. If you don't need full descriptions, turn scrapeDetails off: same jobs at almost half the cost and double the speed.
  • Cover both Swiss job markets. jobup.ch and its German-Swiss sibling jobs.ch share the JobCloud platform but have separate inventories — run the jobs.ch Scraper alongside for national coverage.

⚠️ Error items

When a request permanently fails after all retries, the actor pushes an error item (no charge) so a run is never silently lossy:

{ "error": "BLOCKED_OR_FAILED", "errorDescription": "Non-JSON response from https://www.jobup.ch/api/…", "url": "https://www.jobup.ch/api/v1/public/search?query=…", "scrapedAt": "2026-07-11T15:12:00.000Z" }
Error codeMeaning
BLOCKED_OR_FAILEDThe request failed after 5 retries (network error, rate limit, or an HTML error page instead of JSON). Re-run later or lower concurrency.
RUN_ABORTEDThe whole run hit an unrecoverable error (e.g. proxy pool exhaustion). Results scraped before the abort are kept.

🔌 Integrations

Push results anywhere Apify connects: Google Sheets, Slack, Discord, Make, Zapier, BigQuery, Snowflake, Airbyte, plain webhooks, and the scheduler. Configure these from the actor's Integrations tab.

🛠️ API usage

Run the actor and fetch the dataset via the Apify API.

Node.js (apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('crowley/jobup-ch-scraper').call({
searchQuery: 'infirmier',
location: 'Genève',
maxItems: 100,
scrapeDetails: true,
proxyConfiguration: { useApifyProxy: true, apifyProxyGroups: ['RESIDENTIAL'], apifyProxyCountry: 'CH' },
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python (apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("crowley/jobup-ch-scraper").call(run_input={
"searchQuery": "infirmier",
"location": "Genève",
"maxItems": 100,
"scrapeDetails": True,
"proxyConfiguration": {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "CH"},
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

cURL:

curl -X POST "https://api.apify.com/v2/acts/crowley~jobup-ch-scraper/runs?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchQuery":"infirmier","location":"Genève","maxItems":100,"scrapeDetails":true,"proxyConfiguration":{"useApifyProxy":true,"apifyProxyGroups":["RESIDENTIAL"],"apifyProxyCountry":"CH"}}'

🤖 Use with AI agents via MCP

This actor is callable from AI agents through the Apify MCP server. Example setup for Claude Desktop / Claude Code / Cursor:

{
"mcpServers": {
"apify": {
"command": "npx",
"args": ["-y", "@apify/actors-mcp-server", "--actors", "crowley/jobup-ch-scraper"],
"env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
}
}
}

Example prompts: "Find nursing jobs in Lausanne with at least an 80% workload" or "List accounting jobs in Geneva posted this week, with company and application link."

❓ FAQ

Do I need a jobup.ch login or API key? No. Just a search or URL and an Apify residential proxy.

Where does the data come from? From jobup.ch's own public JSON API — the same one the jobup.ch website itself uses. That means stable job IDs, exact timestamps, and structured fields instead of fragile HTML scraping.

What's the difference between jobup.ch and jobs.ch? Both belong to JobCloud, Switzerland's largest job-ad group. jobup.ch is the French-Swiss (Romandie) board — Geneva, Vaud, Valais, Neuchâtel, Fribourg, Jura — while jobs.ch leads in German-speaking Switzerland. Their inventories differ; scrape both for national coverage.

What does workloadPercent mean? Swiss job ads state the pensum (French: taux d'occupation) — the employment percentage. 100% is full-time, 80-100% means the employer accepts anything from 4 days a week to full-time. The scraper collapses the API's grade list (e.g. [80, 85, 90, 95, 100]) into that familiar range.

Why are most salaries empty? Swiss employers rarely publish pay — there is no salary-transparency mandate in Switzerland. When a posting does include it, you get salaryRaw, salaryMin/salaryMax, salaryCurrency (CHF), and salaryPeriod.

Can I search in French or English? Yes. The search index covers all of jobup.ch, and queries work in the site's languages (infirmier, comptable, software engineer…). You can also paste /fr/emplois/ or /en/jobs/ URLs as startUrls.

How many results can I get per search? The jobup.ch API caps a single search at 2,000 results. Use more specific queries/locations or several startUrls to cover more.

Can I get only new jobs? Yes — set publicationDateFilter to 1d (last 24 hours), 3d, 7d, or 30d and schedule the actor. Website URLs with publication-date=N pasted as startUrls are translated to the equivalent API filter too.

Can I find remote jobs? jobup.ch has no structured remote field, so the actor sets an isRemote heuristic flag when the title or description mentions télétravail, remote, or home office. Filter your export on isRemote = true.

Can I use this for salary benchmarking? Yes, with the caveat that only a minority of Swiss postings publish pay. Aggregate salaryMin/salaryMax/salaryPeriod (already normalized to CHF) across a role and region for directional benchmarks.

Is it legal? See the Legality section below.

⚖️ Legality

This scraper collects publicly available job-posting data only. It does not log in, bypass paywalls, or collect personal data of job applicants. You are responsible for using it in compliance with jobup.ch's Terms of Service and robots.txt, the EU GDPR, and the Swiss Federal Act on Data Protection (FADP/nDSG). Scrape responsibly: keep concurrency modest, do not overload the site, and use the data lawfully (e.g. recruiting and market research, not spam). Job postings may contain a contact name — treat any personal data per the FADP and GDPR (lawful basis, minimisation, retention limits). When in doubt, consult a lawyer. Background reading: Is web scraping legal?

💬 Your feedback

Found a bug or want a new field? Open an issue on the actor's Issues tab — we actively maintain it.

Other Switzerland-focused scrapers from the same author:

📝 Changelog

1.0 — 2026-07-11

  • Initial release: jobup.ch search + full job-detail scraping via the public JSON API (no browser — fast, cheap HTTP).
  • Swiss workload parsing (80-100%), French contract-type mapping (Durée indéterminée, Temporaire, Indépendant, Stage, Revenu complémentaire, Apprentissage), CHF salary ranges (min/max/period), canton codes, ISO posted dates, clean plain-text descriptions, direct application URLs.
  • Server-side filters: publicationDateFilter (1d/3d/7d/30d, with a client-side postedDate double-check), employmentTypes, and workloadMin/workloadMax (pensum range).
  • startUrls support for any jobup.ch search URL (fr/en/de) with all filters preserved; website publication-date=N and employment-types=N params are translated to their API equivalents.
  • Remote-work heuristic flag isRemote (télétravail / remote / home office).
  • Pay-per-event pricing with dedup and error items; maxItems budget cap and anti-runaway pagination caps (2,000-result API ceiling, matchless-streak guard).