# ICTjobs.ch Scraper - Swiss IT & Tech Jobs (`santamaria-automations/ictjobs-ch-scraper`) Actor

Scrapes IT and tech job listings from ICTjobs.ch, Switzerland's dedicated ICT job board. Filter by category, region, and employment type. Exclude recruitment agencies. Optional LLM contact extraction.

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

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Ictjobs.ch Job Scraper

Scrapes job listings from [ictjobs.ch](https://ictjobs.ch), the leading IT job portal for Switzerland.

### Three Scraping Modes

This scraper supports three distinct modes for different use cases:

| Mode | Input | Output | Use Case |
|------|-------|--------|----------|
| **SEARCH MODE** | Search query + category + region | Basic job data from listings | Fast discovery of new IT jobs |
| **SEARCH + DETAILS MODE** | `includeJobDetails: true` (default) | Full job data with descriptions | Complete data collection in one run |
| **DIRECT URLS MODE** | `directUrls: [...]` | Full job data + `job_status` | Still-alive checks, re-scraping specific jobs |

### Use with AI Agents (MCP)

Connect this actor to any MCP-compatible AI client — Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, or custom agents.

**Apify MCP server URL:**

```
https://mcp.apify.com?tools=santamaria-automations/ictjobs-ch-scraper
```

**Example prompt once connected:**

> "Use `ictjobs-ch-scraper` to scrape job listings from ictjobs ch. Return results as a table."

Clients that support dynamic tool discovery (Claude.ai, VS Code) will receive the full input schema automatically via `add-actor`.

### Features

- **WordPress API-based scraping** - Uses the official WordPress REST API for fast, reliable data extraction
- **JSON-LD schema extraction** - Extracts structured data from job detail pages using schema.org JobPosting format
- **Category filtering** - Filter by IT job categories (Software Development, DevOps, Data Science, etc.)
- **Region filtering** - Filter by Swiss regions and cantons
- **Employment type filter** - Filter by full-time, part-time, internship, contract, temporary
- **Comprehensive job data** - Extracts title, company, location, contact details, and more
- **HR company filtering** - Filter out recruitment agencies to get direct employer postings
- **Standardized output** - Returns data in the `JobListing` schema format
- **Rate-limited** - Respectful 2-second delays between API requests
- **Proxy support** - Built-in proxy rotation for reliability

### Input

| Field | Type | Description | Default |
|-------|------|-------------|---------|
| `directUrls` | array | Direct job URLs to scrape (skips search mode) | `[]` |
| `searchQuery` | string | Job title, skills, or keywords to search for | `""` (all jobs) |
| `category` | string | Job category/field (e.g., "Software Development", "DevOps") | `""` (all categories) |
| `region` | string | Swiss region or canton (e.g., "Zürich", "Bern", "Basel") | `""` (all Switzerland) |
| `employmentType` | string | Employment type: `all`, `full-time`, `part-time`, `internship`, `contract`, `temporary` | `all` |
| `maxResults` | integer | Maximum number of job listings to scrape | `500` |
| `includeJobDetails` | boolean | Fetch full job descriptions from detail pages (slower but more data) | `true` |
| `companyFilter` | string | Filter by company type: `all`, `exclude-hr`, `only-hr` | `all` |
| `proxyConfiguration` | object | Apify proxy settings | Residential |

#### Mode 1: SEARCH MODE (Fast)

Quick search without visiting detail pages:

- **Use case**: Fast IT job discovery, broad collection
- **Speed**: Fast - only scrapes listing pages
- **Output**: Basic job data (title, company, location, posted date)

```json
{
  "searchQuery": "DevOps",
  "region": "Zürich",
  "maxResults": 200,
  "includeJobDetails": false
}
```

#### Mode 2: SEARCH + DETAILS MODE (Complete Data)

Default mode with `includeJobDetails: true`:

- **Use case**: Complete data collection in one run
- **Speed**: Moderate - visits detail pages for each job
- **Output**: Full descriptions, JSON-LD data, contact details

```json
{
  "searchQuery": "Data Scientist",
  "region": "Zürich",
  "maxResults": 100
}
```

#### Mode 3: DIRECT URLS MODE (Still Alive Checks)

When `directUrls` is provided, the scraper operates in **direct mode**:

- **Skips search phase** - Goes directly to provided job URLs
- **Job status detection** - Returns `online`, `offline`, `expired`, or `unknown`
- **Full data extraction** - Same as detail page scraping
- **Use case**: Periodic "still alive" checks, re-scraping specific jobs after deduplication

```json
{
  "directUrls": [
    "https://ictjobs.ch/job/senior-software-engineer-zurich-12345/",
    "https://ictjobs.ch/job/devops-engineer-bern-67890/",
    "https://ictjobs.ch/job/data-scientist-geneva-24680/"
  ]
}
```

**Direct URLs mode workflow:**

1. Provide array of Ictjobs.ch job detail URLs
2. Scraper visits each URL directly
3. Detects if job is still online or has been removed
4. Extracts JSON-LD structured data if available
5. Returns `job_status` field indicating availability

#### Categories

Ictjobs.ch has 157+ job categories including:

- Software Development / Engineering
- DevOps / Cloud / Infrastructure
- Data Science / Analytics / BI
- Cybersecurity / Information Security
- IT Project Management
- System Administration
- Quality Assurance / Testing
- UX/UI Design
- Database Administration
- Network Engineering
- And many more...

Leave the `category` field empty to get all IT jobs across all categories.

#### Regions

Filter jobs by Swiss regions or cantons:

- Zürich
- Bern
- Basel
- Ostschweiz (Eastern Switzerland)
- Zentralschweiz (Central Switzerland)
- Romandie (French-speaking Switzerland)
- Ticino
- Individual cantons (ZH, BE, AG, etc.)

#### HR Company Filtering

Filter jobs by company type to focus on direct employer postings or recruitment agencies:

| Option | Description |
|--------|-------------|
| `all` | Include all companies (default) |
| `exclude-hr` | Remove HR/recruitment agencies |
| `only-hr` | Show only HR/recruitment agency postings |

The filter detects HR companies by matching company names against common patterns like "Personal", "Recruiting", "Staffing", "Job", "Vermittlung", etc.

### Example Input

#### Basic Search

```json
{
  "searchQuery": "DevOps",
  "region": "Zürich",
  "employmentType": "full-time",
  "maxResults": 200
}
```

#### Category Filter

```json
{
  "category": "Software Development",
  "region": "Bern",
  "maxResults": 100,
  "companyFilter": "exclude-hr"
}
```

#### Direct URLs - Still Alive Check

```json
{
  "directUrls": [
    "https://ictjobs.ch/job/senior-software-engineer-zurich-12345/",
    "https://ictjobs.ch/job/devops-engineer-bern-67890/"
  ]
}
```

### Output

Each job listing follows the standardized `JobListing` schema:

```json
{
  "id": "12345",
  "title": "Senior DevOps Engineer (m/w/d)",
  "company": "Tech Innovations AG",
  "location": "Zürich, 8001, ZH",
  "canton": "ZH",
  "job_status": "online",
  "top_listing": null,
  "employment_type": "full-time",
  "workload_min": null,
  "workload_max": null,
  "remote_option": null,
  "salary_text": null,
  "description_snippet": "We are looking for an experienced DevOps Engineer...",
  "description_full": "Job Description: ...\n\nRequirements: ...\n\nWe offer: ...",
  "requirements": [],
  "posted_at": "2024-01-15T00:00:00.000Z",
  "expires_at": "2024-02-28T00:00:00.000Z",
  "source_url": "https://ictjobs.ch/job/senior-devops-engineer-12345",
  "source_platform": "ictjobs.ch",
  "contact_salutation": "Herr",
  "contact_firstname": "Thomas",
  "contact_lastname": "Müller",
  "contact_email": "jobs@techinnovations.ch",
  "contact_phone": "+41442345678",
  "contact_position": null,
  "contact_raw": "<p>Kontakt: Herr Thomas Müller<br/>E-Mail: jobs@techinnovations.ch<br/>Tel: +41 44 234 56 78</p>",
  "apply_url": "https://ictjobs.ch/job/senior-devops-engineer-12345",
  "apply_email": "jobs@techinnovations.ch",
  "company_url": "https://www.techinnovations.ch",
  "company_description": null,
  "company_social_urls": null,
  "company_benefits": null,
  "scraped_at": "2024-01-16T12:00:00.000Z"
}
```

#### Output Fields

| Field | Description |
|-------|-------------|
| `id` | Unique job posting ID |
| `title` | Job title |
| `company` | Company name |
| `location` | City/location with postal code and canton |
| `canton` | Swiss canton code (ZH, BE, AG, etc.) |
| `job_status` | Job availability: `online`, `offline`, `expired`, `unknown` (Direct URLs mode only) |
| `top_listing` | Boolean - if job is a paid promotion (always null for ictjobs.ch) |
| `employment_type` | full-time, part-time, contract, temporary, internship |
| `workload_min` | Minimum workload percentage (extracted from title if available) |
| `workload_max` | Maximum workload percentage (extracted from title if available) |
| `remote_option` | remote, hybrid, or null |
| `salary_text` | Salary as displayed (if available) |
| `description_snippet` | First 500 characters of description |
| `description_full` | Complete job description |
| `requirements` | Array of job requirements (usually empty) |
| `posted_at` | Publication date |
| `expires_at` | Expiration date (from JSON-LD if available) |
| `source_url` | Link to job posting |
| `source_platform` | Always "ictjobs.ch" |
| `contact_salutation` | "Herr" or "Frau" |
| `contact_firstname` | First name |
| `contact_lastname` | Last name |
| `contact_email` | Email address - extracted via regex |
| `contact_phone` | Phone number - extracted via regex |
| `contact_position` | Contact person's position (usually null) |
| `contact_raw` | Raw HTML/text contact block from the job posting |
| `apply_url` | Application URL (usually same as source\_url) |
| `apply_email` | Application email address |
| `company_url` | Company website (from JSON-LD if available) |
| `company_description` | Company description (usually null) |
| `company_social_urls` | Social media URLs (usually null) |
| `company_benefits` | Array of benefits (usually null) |
| `scraped_at` | Timestamp when job was scraped |

**Notes on `job_status` field:**

- Only populated in **Direct URLs mode** (Mode 3)
- In **Search modes** (Mode 1 & 2), this field is `null` since jobs from search results are assumed to be online
- Values:
  - `online` - Job page loaded successfully with content
  - `offline` - Job page returns 404 or "not found"
  - `expired` - Job explicitly marked as expired
  - `unknown` - Unable to determine status (page loaded but no clear job data)

### Usage

#### Via Apify Console

1. Go to the [actor page](https://apify.com/santamaria/ictjobs-ch-scraper)
2. Configure input parameters
3. Click "Start"
4. Download results from the Dataset tab (JSON, CSV, Excel)

#### Via API

```bash
curl -X POST "https://api.apify.com/v2/acts/santamaria~ictjobs-ch-scraper/runs" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchQuery": "Python Developer",
    "region": "Zürich",
    "maxResults": 100
  }'
```

#### Via Apify SDK (Node.js)

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('santamaria/ictjobs-ch-scraper').call({
  searchQuery: 'Cloud Engineer',
  region: 'Zürich',
  employmentType: 'full-time',
  maxResults: 150,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Found ${items.length} jobs`);
```

### Performance

- **Speed**: ~50-100 jobs/minute (with detail fetching enabled)
- **Cost**: ~0.02-0.04 CU per 500 jobs
- **Reliability**: Built-in retry logic and error handling

### Coverage

Ictjobs.ch focuses on IT jobs across all of Switzerland:

| Region | Major Cities |
|--------|-------------|
| Zürich | Zürich, Winterthur |
| Bern | Bern, Thun |
| Basel | Basel, Liestal |
| Romandie | Geneva, Lausanne, Fribourg |
| Ostschweiz | St. Gallen, Chur |
| Ticino | Lugano, Bellinzona |

### Common Use Cases

1. **IT job market analysis**: Track hiring trends in the Swiss IT sector
2. **Competitive intelligence**: Monitor competitors' IT hiring
3. **Job aggregation**: Build specialized IT job search platforms
4. **Still-alive monitoring**: Check if previously scraped jobs are still active (Direct URLs mode)
5. **Post-deduplication enrichment**: Scrape basic data first, then fetch details for new jobs only
6. **Tech talent sourcing**: Find IT candidates via company postings
7. **Salary research**: Analyze compensation ranges for IT roles

### Data Source

This actor scrapes data from the leading Swiss IT job portal:

- **Website**: [ictjobs.ch](https://ictjobs.ch)
- **API**: WordPress REST API
- **Coverage**: All of Switzerland, IT jobs only
- **Jobs**: 157+ categories, thousands of active listings

### Legal Notice

This actor accesses publicly available job listings through the WordPress API and public web pages. Please ensure your use case complies with the ictjobs.ch terms of service.

### Related Actors

Looking for more job data? Check out our other scrapers:

**Switzerland**

- [Jobs.ch Scraper](https://apify.com/santamaria-automations/jobs-ch-scraper)
- [JobScout24 Scraper](https://apify.com/santamaria-automations/jobscout24-ch-scraper)
- [SwissDevJobs Scraper](https://apify.com/santamaria-automations/swissdevjobs-ch-scraper)
- [Arbeit.Swiss Scraper](https://apify.com/santamaria-automations/arbeit-swiss-scraper)

**Germany**

- [StepStone.de Scraper](https://apify.com/santamaria-automations/stepstone-de-scraper)
- [Stellenanzeigen.de Scraper](https://apify.com/santamaria-automations/stellenanzeigen-de-scraper)

**Global**

- [LinkedIn Jobs Scraper](https://apify.com/santamaria-automations/linkedin-scraper)
- [Indeed Scraper](https://apify.com/santamaria-automations/indeed-scraper)

**Enrich your job data**

- [Website Job Extractor](https://apify.com/santamaria-automations/website-job-extractor) -- Extract jobs directly from company career pages
- [Website Contact Extractor](https://apify.com/santamaria-automations/website-contact-extractor) -- Get emails and phone numbers from company websites
- [Website Email & Phone Scraper](https://apify.com/santamaria-automations/website-email-scraper) -- Fast email and phone extraction (no AI needed)

***

**Part of the Santamaria Job Scrapers Suite** - Professional-grade job data for the DACH region and beyond.
Need help with integration, aggregation, or custom scraping solutions? Contact us at **contact@nanoscrape.com**

# Actor input Schema

## `directUrls` (type: `array`):

List of job detail page URLs to scrape directly (skips search). Use this for 'still alive' checks or re-scraping specific jobs.

## `searchQueries` (type: `array`):

One or more search keywords. Each keyword runs as a separate search. Results are deduplicated across queries.

## `searchQuery` (type: `string`):

Single search keyword (backward compatible). Use 'searchQueries' for multiple keywords.

## `category` (type: `string`):

Job category/field (e.g., 'Software Development', 'DevOps', 'Data Science'). Leave empty for all categories.

## `region` (type: `string`):

Swiss region or canton (e.g., 'Zurich', 'Bern', 'Basel', 'Ostschweiz'). Leave empty for all of Switzerland.

## `employmentType` (type: `string`):

Filter by employment type

## `maxResultsPerQuery` (type: `integer`):

Per-keyword cap. Total possible results = maxResultsPerQuery × number of searchQueries (deduplicated). Example: 100 × 8 queries = up to 800 results. Set to 0 for unlimited per query (only maxResults caps the total).

## `maxResults` (type: `integer`):

Total cap across all queries. Set to 0 for unlimited (each query limited by maxResultsPerQuery).

## `includeJobDetails` (type: `boolean`):

Fetch full job descriptions from detail pages (slower but more data)

## `companyFilter` (type: `string`):

Filter jobs by company type: 'all' includes all companies, 'exclude-hr' removes HR/recruitment agencies, 'only-hr' shows only HR/recruitment agencies

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

Apify proxy settings

## Actor input object example

```json
{
  "directUrls": [],
  "searchQueries": [
    "DevOps"
  ],
  "searchQuery": "",
  "category": "",
  "region": "",
  "employmentType": "",
  "maxResultsPerQuery": 100,
  "maxResults": 0,
  "includeJobDetails": true,
  "companyFilter": "all",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `jobListings` (type: `string`):

Dataset containing scraped job listings

# 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 = {
    "directUrls": [],
    "searchQueries": [
        "DevOps"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/ictjobs-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 = {
    "directUrls": [],
    "searchQueries": ["DevOps"],
}

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

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

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

```

## CLI example

```bash
echo '{
  "directUrls": [],
  "searchQueries": [
    "DevOps"
  ]
}' |
apify call santamaria-automations/ictjobs-ch-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=santamaria-automations/ictjobs-ch-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0zoLkO4iMIZgrE3VW/builds/Asl8p0vU4xhoihJHe/openapi.json
