# Jobs.ch Scraper: Swiss Job Postings, Workload & Salary Estimate (`getascraper/jobs-ch-scraper`) Actor

Scrape jobs.ch Stellenangebote (Swiss jobs) by keyword, canton, city, postal code, field, contract and workload %. Rows give company, address with coordinates and benefits. Optional full details add description, apply link and CHF salary estimate. Monitor new postings on a schedule.

- **URL**: https://apify.com/getascraper/jobs-ch-scraper.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.05 / 1,000 job postings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 🇨🇭 Jobs.ch Scraper: Swiss Job Postings, Workload & Salary Estimate

<table width="100%" style="margin-bottom:0">
<tr>
<td style="padding:24px 28px;background:#FDF2F2;border:1px solid #F3C9C9;border-top:4px solid #D32F2F;border-radius:12px">
<span style="font-size:23px;font-weight:800;color:#1C1917;line-height:1.3">Swiss job postings from jobs.ch, filtered the way recruiters search</span><br>
<span style="font-size:15px;color:#57534E;line-height:1.6">Pick a canton, a city, an occupation, a contract type and a workload range. Get clean rows with company, address, coordinates, benefits and posting date, plus an optional deep layer with the full description, apply link and salary estimate.</span>
</td>
</tr>
</table>
<table width="100%" style="margin-top:0">
<tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #F3C9C9;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#B71C1C">📍 26 cantons</span><br>
<span style="font-size:12px;color:#57534E">Search by canton, city, postal code or job region.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #F3C9C9;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#B71C1C">⏱️ Workload range</span><br>
<span style="font-size:12px;color:#57534E">Find part-time friendly roles or full-time only.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #F3C9C9;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#B71C1C">💰 CHF salary estimate</span><br>
<span style="font-size:12px;color:#57534E">Yearly range per role where the site shows one.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #F3C9C9;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#B71C1C">🔔 Only new postings</span><br>
<span style="font-size:12px;color:#57534E">Name a search and each run returns what is new.</span>
</td>
</tr>
</table>

**Get Swiss job postings from jobs.ch (Stellenangebote), with canton, workload percentage, contract type and posting date, ready for your spreadsheet in under 60 seconds.** Search by keyword and narrow by place, occupation, seniority, required language and home office. Turn on full details to add the description, the direct application link, skills, language requirements and company facts. No login needed.

***

### 🔍 What can you do with it?

- **I am a recruiter in Zurich** pulling every new Java and cloud role from the last 7 days, with workload and apply link, so my team can call companies before anyone else does.
- **I am a staffing agency owner** tracking part-time nursing and care roles by canton to match open postings with the candidates on my list.
- **I run a job board or career newsletter** and need a daily feed of fresh Swiss postings, with company logos and addresses, without copying anything by hand.
- **I am a labour-market analyst** measuring how many roles offer home office, which cantons hire most, and which employers post the most openings, using salary estimates and workload ranges.
- **I am a job seeker or career coach** who wants an alert for new roles in one canton and one field, with the application link in the row.

***

<table width="100%">
<tr>
<td style="padding:12px 18px;background:#FDF2F2;border-left:4px solid #D32F2F">
<span style="font-size:15px;color:#1C1917">&#9889; <b>Built for repeat use.</b> Give a search a name and schedule it. Every run hands you only the postings you have not seen yet.</span>
</td>
</tr>
</table>

### 📥 Input

Every field is optional. Leave the form as it is for a quick test run.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `searchTerms` | array of strings | No | Job titles or skills to search for, one per row. Each keyword is searched on its own and duplicates are removed. Leave empty to browse by filters only. |
| `startUrls` | array of URLs | No | Search links copied from jobs.ch. Their keyword and filters are used as they are, in addition to the keywords above. |
| `cantons` | array of enums | No | One or more of the 26 Swiss cantons. A posting in any chosen canton matches. |
| `locations` | array of strings | No | Cities, towns or postal codes such as Zürich, Lausanne or 8001. A posting in any of them matches. |
| `regions` | array of enums | No | The site's own job regions, for example Region of Basel or Ticino. Handy for commuter areas that cross canton borders. |
| `categories` | array of enums | No | Broad occupational fields such as Information Technology, Medicine or Construction. |
| `employmentTypes` | array of enums | No | Permanent, temporary, freelance, internship, apprenticeship or supplementary income. |
| `positionLevels` | array of enums | No | Executive position, specialist or employee. |
| `workloadMin` | integer | No | Lowest workload percentage you accept, from 0 to 100. Roles offering a range that reaches it still match, so a 60 to 100 percent role matches a minimum of 80. |
| `workloadMax` | integer | No | Highest workload percentage you accept, from 0 to 100. Roles whose range starts at or below it still match, so a 60 to 100 percent role matches a maximum of 60. |
| `languageSkills` | array of enums | No | Keep postings that ask for German, French, English or Italian. A posting asking for any chosen language matches. |
| `homeOfficeOnly` | boolean | No | Keep only postings whose employer lists working from home as a benefit. |
| `postedWithin` | enum | No | Keep only postings published in the last 24 hours, 3, 7, 14 or 30 days. Empty means any time. |
| `sortBy` | enum | No | Newest first (best for monitoring) or best match. |
| `language` | enum | No | Language of the jobs.ch interface used for links. Posting texts keep the language the employer wrote. Labels in the output are always English. |
| `includeDetails` | boolean | No | Open every posting to add the full description, apply link, salary estimate, skills, language requirements, contact person and company profile. Slower, because each posting is one extra visit, and each posting with details is billed as a separate Job details event. Off by default. |
| `descriptionFormat` | enum | No | Plain text, HTML or both. Only used when full details are on. |
| `monitorName` | string | No | A short name that turns the run into a monitor. Later runs with the same name and searches return only new postings. Leave empty to always get everything. |
| `maxItems` | integer | No | Total number of postings to return across all keywords. With several keywords the budget is shared evenly. Defaults to 20. |
| `proxyConfiguration` | object | No | Connection settings. The default works for almost every run. |

### 📤 Output

Each posting is one row. Fields the site does not state are left out instead of being filled with placeholders.

```json
{
  "id": "e1051fdb-d899-4dd3-82b9-6a6c2dac5e57",
  "url": "https://www.jobs.ch/en/vacancies/detail/e1051fdb-d899-4dd3-82b9-6a6c2dac5e57/",
  "title": "Data Platform Engineer",
  "companyName": "Schweizerische Nationalbank",
  "companyUrl": "https://www.jobs.ch/en/companies/2004-schweizerische-nationalbank/",
  "location": "Zürich",
  "canton": "ZH",
  "workloadMin": 80,
  "workloadMax": 100,
  "employmentTypes": ["Permanent position"],
  "positionLevel": "Employee",
  "postedAt": "2026-10-19T18:02:04+02:00",
  "searchTerm": "software engineer",
  "applyUrl": "https://smahrt-consulting-ag.contactrh.com/jobs/4473/44518098/de_DE",
  "applyMethod": "external",
  "categories": ["Technical", "Information Technology / Telecom.", "System Engineering"],
  "salaryMin": 100000,
  "salaryMax": 140000,
  "salaryCurrency": "CHF",
  "salaryPeriod": "year",
  "salaryIsEstimate": true,
  "applicationDeadline": "2026-12-03",
  "companySize": "501 - 1 000",
  "companyRating": 2.63,
  "companyReviewCount": 8
}
```

#### Data table

Fields marked "details" appear when `includeDetails` is on.

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Unique posting ID. |
| `url` | string | Link to the posting on jobs.ch in the language you chose. |
| `title` | string | Job title as published. |
| `companyName` | string | Hiring company. |
| `companyId` | string | Company ID on jobs.ch. |
| `companyUrl` | string | Company page on jobs.ch. |
| `companyLogo` | string | Logo image link. |
| `location` | string | Place of work as shown on the posting. |
| `postalCode` | string | Postal code of the workplace. |
| `canton` | string | Two-letter canton code. |
| `street` | string | Street address of the workplace. |
| `country` | string | Country code of the workplace. |
| `latitude`, `longitude` | number | Coordinates of the workplace. |
| `regions` | array of strings | Job regions the posting belongs to. |
| `workloadMin`, `workloadMax` | integer | Workload range in percent. |
| `employmentTypes` | array of strings | Contract types such as Permanent position or Freelance. |
| `positionLevel` | string | Executive position, Specialist or Employee. |
| `postedAt` | string | Publication date and time. |
| `firstPostedAt` | string | First publication date and time. |
| `homeOfficeOffered` | boolean | True when the employer lists working from home. |
| `benefits` | array of strings | Employer benefits such as company restaurant or pension fund contribution. |
| `easyApply` | boolean | True when the posting can be applied to in a few taps. |
| `newSinceLastRun` | boolean | Monitor mode only: true for postings you have not received before. |
| `searchTerm` | string | The keyword that found the posting. |
| `scrapedAt` | string | When the row was collected. |
| `description`, `descriptionHtml` | string | Full description in plain text or HTML (details). |
| `applyUrl` | string | Direct application link when the employer uses its own form (details). |
| `applyMethod` | string | External site or jobs.ch form (details). |
| `skills` | array of strings | Skills listed by the employer (details). |
| `languageRequirements` | array of objects | Required languages with level, for example German, Fluent (details). |
| `categories` | array of strings | Occupational fields and subfields (details). |
| `salaryMin`, `salaryMax` | integer | Salary estimate range (details). |
| `salaryCurrency`, `salaryPeriod` | string | Currency and period of the estimate, for example CHF and year (details). |
| `salaryIsEstimate` | boolean | Always true. The figure is the site's estimate for the role, not an employer-stated salary (details). |
| `applicationDeadline` | string | Last day the posting is online (details). |
| `startDate` | string | Planned start date (details). |
| `workHours` | string | Weekly hours (details). |
| `contacts` | array of objects | Contact person named on the posting (details). |
| `companyWebsite` | string | Company website (details). |
| `companySize` | string | Employee range (details). |
| `companyOpenJobs` | integer | Open positions at the company (details). |
| `companyRating`, `companyReviewCount` | number | Employee rating and number of reviews, when reviews exist (details). |
| `companyDescription` | string | Company introduction (details). |
| `companySocialLinks` | array of objects | Company social profiles (details). |

### 🚀 How to use it

<table width="100%">
<tr>
<td style="padding:16px 14px;width:33%;background:#FDF2F2;border:1px solid #F3C9C9;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#D32F2F;letter-spacing:1px">STEP 1</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Describe the role</span><br>
<span style="font-size:12px;color:#57534E">Add keywords, then pick canton, field, contract type and workload.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#FDF2F2;border:1px solid #F3C9C9;border-left:none;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#D32F2F;letter-spacing:1px">STEP 2</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Run and review</span><br>
<span style="font-size:12px;color:#57534E">Start the run and check the Postings, Salary and Employers views.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#FDF2F2;border:1px solid #F3C9C9;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#D32F2F;letter-spacing:1px">STEP 3</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Export or schedule</span><br>
<span style="font-size:12px;color:#57534E">Download JSON, CSV or Excel, or add a monitor name and schedule it.</span>
</td>
</tr>
</table>

**Tips**

- Start with `includeDetails` off to see how many postings match, then switch it on for the final export.
- For a daily alert, set a monitor name, choose "Newest first" and schedule the run every morning.
- You can paste a search link from jobs.ch into `startUrls` instead of filling in the form.
- Several cantons, regions or fields in one search are combined, so you get postings from any of them.

### 💰 Pricing

Pricing is pay per event, with no subscriptions or monthly fees.

- **Job posting:** charged for each posting saved to your dataset.
- **Job details:** charged for each posting whose full details were fetched, only when `includeDetails` is on. Postings whose details could not be loaded are not charged for this event.

Runs that return nothing cost nothing. Paid plans get lower rates at higher plan levels. You can set a maximum cost per run, and the Actor stops cleanly when it is reached. Free plan runs are limited to 25 postings per run, 3 runs per day, and a short wait between runs.

### ⭐ Enjoying Jobs.ch Scraper?

<table width="100%" style="display:table;width:100%">
<tr>
<td style="padding:20px 24px 14px;background:#FDF2F2;border:1px solid #F3C9C9;border-left:5px solid #D32F2F;border-radius:10px 10px 0 0">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">Saved your team hours of copying Swiss job ads into a spreadsheet?</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps other recruiters and job board owners find it. Your feedback also tells us what to build next.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#D32F2F;border:1px solid #F3C9C9;border-top:none;border-radius:0 0 10px 10px;text-align:center">
<a href="https://apify.com/getascraper/jobs-ch-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### ❓ FAQ

##### Does it need a login or an account on jobs.ch?

No. It collects the public postings that anyone can see on jobs.ch. You never enter a password, key or cookie.

##### Can I scrape jobs.ch for one canton only?

Yes. Choose one or more cantons, or type a city or postal code, and only postings from those places are returned.

##### Wie kann ich Stellenangebote von jobs.ch exportieren?

Run the Actor with your keywords and filters, then download the dataset as Excel, CSV or JSON. You can also schedule the run and send the results to Google Sheets or your own tools.

##### Does it show the salary?

Many Swiss postings state no salary. Where the site shows its own yearly salary estimate in CHF, the Actor returns it with the flag `salaryIsEstimate`. It is never an employer-stated figure, and it is left out when the site shows none.

##### How do I only get new postings?

Enter a monitor name and schedule the run. The first run remembers what it saw. Each later run with the same name and searches returns only postings that are new since then.

##### How fresh is the data?

Every run reads the live site, so you see what is online at that moment. Use the "Posted within" filter and "Newest first" for the freshest results.

##### Is there a radius search around a city?

The site matches places by name and postal code, so there is no distance radius. Combine several cities, postal codes or job regions to cover a commuter area.

##### Does it find every posting on the site?

Broad searches can match thousands of postings, and the site only lists a limited number per search. Add filters such as canton, field or "Posted within" and run several searches to cover everything.

### 🔗 Other actors

- [Carmarket.ch Scraper: Swiss Dealer Cars with Real Search Filters](https://apify.com/getascraper/carmarket-ch-scraper) ↗ - Swiss dealer cars with real search filters, a good match if you also track the Swiss market.
- [Canada Job Bank Scraper: Jobs, LMIA, NOC Codes & Salary Monitor](https://apify.com/getascraper/jobbank-scraper) ↗ - Canadian job postings with salary bands and a monitor for new roles.
- [EURAXESS Scraper: PhD, Postdoc and Research Jobs Across Europe](https://apify.com/getascraper/euraxess-jobs-scraper) ↗ - Research positions across Europe, including Switzerland.
- [Eurofirms Portugal Jobs Scraper: Ofertas de Emprego Change Feed](https://apify.com/getascraper/eurofirms-portugal-jobs-scraper) ↗ - A change feed of job offers in Portugal.

# Changelog

This Actor's version history is a separate document: https://apify.com/getascraper/jobs-ch-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

Job titles or skills to search for, one per row, for example "software engineer" or "Pflegefachperson". Each keyword is searched separately and duplicates are removed. Leave empty to browse by filters only.

## `startUrls` (type: `array`):

Optional jobs.ch search links copied from your browser. Their keyword and filters are used as they are, in addition to the keywords above.

## `cantons` (type: `array`):

Limit results to one or more of the 26 Swiss cantons. Several cantons are combined, so a posting in any of them matches.

## `locations` (type: `array`):

Cities, towns or postal codes such as "Zürich", "Lausanne" or "8001". Several entries are combined, so a posting in any of them matches.

## `regions` (type: `array`):

The site's own job regions, for example "Region of Basel" or "Ticino". Useful for commuter areas that cross canton borders.

## `categories` (type: `array`):

Broad fields such as Information Technology, Medicine or Construction. Several fields are combined.

## `employmentTypes` (type: `array`):

Permanent, temporary, freelance, internship, apprenticeship or supplementary income. Several types are combined.

## `positionLevels` (type: `array`):

Executive position, specialist or employee. Several levels are combined.

## `workloadMin` (type: `integer`):

Lowest workload (Pensum) you accept, from 0 to 100. Roles that offer a range reaching this level still match, so a 60 to 100 percent role matches a minimum of 80. 0 means no lower limit.

## `workloadMax` (type: `integer`):

Highest workload (Pensum) you accept, from 0 to 100. Roles whose range starts at or below this level still match, so a 60 to 100 percent role matches a maximum of 60. 100 means no upper limit.

## `languageSkills` (type: `array`):

Keep postings that ask for German, French, English or Italian. Several languages are combined, so a posting asking for any of them matches.

## `homeOfficeOnly` (type: `boolean`):

Keep only postings whose employer lists working from home as a benefit.

## `postedWithin` (type: `string`):

Keep only postings published in this time window. Pair it with a monitor name to follow fresh postings on a schedule.

## `sortBy` (type: `string`):

Newest first returns the most recently published postings and is the right choice for monitoring. Relevance follows the site's own keyword ranking.

## `language` (type: `string`):

Language of the jobs.ch interface used for links and site texts. Posting texts keep the language the employer wrote them in. Labels in the dataset are always English.

## `includeDetails` (type: `boolean`):

Open every posting to add the full description, the direct application link, jobs.ch's salary estimate in CHF, skills, language requirements, contact person and company profile (size, website, rating). Slower, because each posting is one extra request.

## `descriptionFormat` (type: `string`):

Plain text is easiest to read and search. HTML keeps the employer's formatting. Both returns two fields. Only used when full posting details are on.

## `monitorName` (type: `string`):

Give this search a short name to turn the run into a monitor. The first run remembers what it saw, and each later run with the same name and searches returns only postings that are new since then. Leave empty to always return everything.

## `maxItems` (type: `integer`):

Total number of postings to return across all keywords. With several keywords the budget is shared evenly between them. Raise it for bigger exports.

## `proxyConfiguration` (type: `object`):

The Actor connects directly first and only switches to the datacenter proxy when the site refuses a request. The default works for almost every run.

## Actor input object example

```json
{
  "searchTerms": [
    "software engineer"
  ],
  "startUrls": [],
  "cantons": [],
  "locations": [],
  "regions": [],
  "categories": [],
  "employmentTypes": [],
  "positionLevels": [],
  "workloadMin": 0,
  "workloadMax": 100,
  "languageSkills": [],
  "homeOfficeOnly": false,
  "postedWithin": "",
  "sortBy": "newest",
  "language": "en",
  "includeDetails": false,
  "descriptionFormat": "text",
  "monitorName": "",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "software engineer"
    ],
    "startUrls": [],
    "cantons": [],
    "locations": [],
    "regions": [],
    "categories": [],
    "employmentTypes": [],
    "positionLevels": [],
    "workloadMin": 0,
    "workloadMax": 100,
    "languageSkills": [],
    "homeOfficeOnly": false,
    "postedWithin": "",
    "sortBy": "newest",
    "language": "en",
    "includeDetails": false,
    "descriptionFormat": "text",
    "monitorName": "",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/jobs-ch-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["software engineer"],
    "startUrls": [],
    "cantons": [],
    "locations": [],
    "regions": [],
    "categories": [],
    "employmentTypes": [],
    "positionLevels": [],
    "workloadMin": 0,
    "workloadMax": 100,
    "languageSkills": [],
    "homeOfficeOnly": False,
    "postedWithin": "",
    "sortBy": "newest",
    "language": "en",
    "includeDetails": False,
    "descriptionFormat": "text",
    "monitorName": "",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/jobs-ch-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "software engineer"
  ],
  "startUrls": [],
  "cantons": [],
  "locations": [],
  "regions": [],
  "categories": [],
  "employmentTypes": [],
  "positionLevels": [],
  "workloadMin": 0,
  "workloadMax": 100,
  "languageSkills": [],
  "homeOfficeOnly": false,
  "postedWithin": "",
  "sortBy": "newest",
  "language": "en",
  "includeDetails": false,
  "descriptionFormat": "text",
  "monitorName": "",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call getascraper/jobs-ch-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/jobs-ch-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Oqj6YrZ4o9N2JsudZ/builds/hjLFZtbe4vXUINNUv/openapi.json
