# Jobware Scraper (`solidcode/jobware-de-scraper`) Actor

\[💰 $3.00 / 1K] Extract job listings from Jobware.de, a leading German job board for specialist roles. Search by keyword, location, and employment type to get titles, companies, salaries, descriptions, recruiter contacts, and apply links.

- **URL**: https://apify.com/solidcode/jobware-de-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Jobs, Developer tools
- **Features:** Limited permissions
- **Stats:** 8 total users, 2 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.
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

## Jobware Scraper

Pull job listings from Jobware.de at scale — titles, companies, salaries, full German-language descriptions, recruiter contacts (name, email, phone), company benefits, and apply links for specialist, IT, and Fach- und Führungskräfte roles across Germany. Built for recruiters, sourcing teams, relocation services, and labor-market analysts who need structured Jobware data without copy-pasting listings one ad at a time.

### Why This Scraper?

- **Recruiter contacts on every detailed ad** — pulls the contact person's name plus email and phone parsed straight from the posting body, so each row is a ready-to-action lead, not just a job title.
- **Up to ~2,248 jobs per keyword** — collects everything Jobware will surface for a single search keyword in one pass, the platform's own upper bound.
- **50 keywords and 100 URLs per run** — batch dozens of German job titles ("Softwareentwickler", "Pflegefachkraft", "Projektmanager") in one go, with results merged and de-duplicated across every query.
- **Six employment-type filters** — Full-time (Vollzeit), Part-time (Teilzeit), Working student (Werkstudent), Internship (Praktikum), Freelance / Freie Mitarbeit, and Home office / remote.
- **Five posted-within windows** — last 24 hours, 3, 7, 14, or 30 days, so you only collect fresh openings.
- **~30 structured fields per job** — title, company, the workplace city and postal code (where the job actually sits, not the employer's head office), annual salary, posted date, application deadline, requirements, benefits, company logo, and more.
- **Plain text, HTML, or both** — choose clean text for analysis, formatting-preserved HTML for republishing, or both fields side by side.
- **Paste any Jobware URL** — search-result links (your filters honored as-is) or individual job pages, both fully resolved.
- **Extracted contact fallbacks** — every email, phone, and external URL found in the ad body is captured as structured arrays alongside the parsed recruiter contact.

### Use Cases

**Recruitment & Sourcing**

- Build candidate-outreach lists with recruiter name, email, and phone
- Track which companies are actively hiring for a given role across Germany
- Monitor competitor job postings to spot team expansions
- Source openings by workplace city and postal code across Germany

**Lead Generation**

- Pull hiring-company contacts for recruitment-agency outreach
- Target employers posting specialist or IT roles in your region
- Identify firms scaling specific functions (engineering, nursing, project management)
- Feed verified company and contact data into your CRM

**Labor-Market Research**

- Measure demand for specialist roles across German cities
- Track salary text and benefits offered by sector
- Analyze full-time vs. part-time vs. working-student supply
- Monitor posting volume over rolling 7-, 14-, and 30-day windows

**Competitive Intelligence**

- Watch which roles a competitor advertises and how often
- Compare benefits and salary language across employers
- Detect new office locations from posting cities and addresses
- Benchmark job-description content against your own listings

### Getting Started

#### Search by Keyword

The simplest way to start — one German job title:

```json
{
    "searchQueries": ["Softwareentwickler"],
    "maxResults": 50
}
```

#### Keyword with Filters

Narrow to recent full-time roles in one city:

```json
{
    "searchQueries": ["Projektmanager", "Pflegefachkraft"],
    "location": "Berlin",
    "employmentType": "vollzeit",
    "datePosted": "7",
    "sortBy": "date",
    "maxResults": 200
}
```

#### Paste Jobware URLs (Advanced)

Mix search-result links, individual job pages, and full detail enrichment:

```json
{
    "startUrls": [
        { "url": "https://www.jobware.de/jobs--fuer-softwareentwickler--in-berlin" },
        { "url": "https://www.jobware.de/job/beispiel-softwareentwickler-m-w-d-063994828" }
    ],
    "includeJobDetails": true,
    "descriptionFormat": "both",
    "maxResults": 500
}
```

### Input Reference

#### Search — What to Find

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQueries` | array | `["Softwareentwickler"]` | Job titles or keywords to search for. Each keyword runs a separate search; results are merged and de-duplicated. Up to 50 keywords per run. |
| `startUrls` | array | `[]` | Paste search links (`https://www.jobware.de/jobs--fuer-softwareentwickler--in-berlin`) and/or job links (`https://www.jobware.de/job/sales-manager-m-w-d-064064750`). A job link returns exactly that one job, so any Job URL from your results can be pasted back in. Filters baked into a search link are honored as-is. Links that are neither are skipped and named in the run status. Up to 100 URLs per run. |

#### Filters & Limits

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `location` | string | `""` | A German city or region, such as Berlin, München, Hamburg, or Nordrhein-Westfalen. Leave empty to search all of Germany. |
| `employmentType` | select | `Any` | Filter by employment type: Any, Full-time (Vollzeit), Part-time (Teilzeit), Working student (Werkstudent), Internship (Praktikum), Freelance / contract (Freie Mitarbeit), or Home office / remote. |
| `datePosted` | select | `Any time` | Only show jobs published within: Any time, Last 24 hours, Last 3 days, Last 7 days, Last 14 days, or Last 30 days. |
| `sortBy` | select | `Relevance` | Order results by Relevance or Newest first. |
| `maxResults` | integer | `50` | Maximum jobs to collect per search keyword (1–2,248). Jobware returns at most about 2,200 jobs for any single keyword. |

#### Output Options

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `includeJobDetails` | boolean | `true` | Fetch the full description, salary, deadline, and recruiter contact from each job's detail page. Turn off for faster, lighter scans. |
| `descriptionFormat` | select | `Plain text` | How to return the description: Plain text, HTML, or Both text and HTML. |

### Output

Each job is one flat row. Here's a representative result with full details enabled:

```json
{
    "title": "Softwareentwickler Java (m/w/d)",
    "company": "Beispiel Technologie GmbH",
    "location": "Berlin",
    "city": "Berlin",
    "zipCode": "10115",
    "employmentType": "Vollzeit",
    "workHours": "37,5 Std./Woche",
    "isRemote": true,
    "salaryText": "60.000 € – 80.000 € pro Jahr (Schätzung)",
    "postedDate": "2026-06-12T00:00:00Z",
    "deadline": "2026-07-31T00:00:00Z",
    "descriptionSnippet": "Wir suchen einen erfahrenen Java-Entwickler...",
    "description": "Für unser Berliner Team suchen wir ab sofort einen Softwareentwickler...",
    "descriptionHtml": "<p>Für unser Berliner Team suchen wir ...</p>",
    "requirements": "Abgeschlossenes Studium der Informatik, mehrjährige Java-Erfahrung...",
    "companyBenefits": ["30 Tage Urlaub", "Flexible Arbeitszeiten", "Jobticket"],
    "contactName": "Anna Müller",
    "contactEmail": "bewerbung@beispiel-tech.de",
    "contactPhone": "+49 30 1234567",
    "extractedEmails": ["bewerbung@beispiel-tech.de"],
    "extractedPhones": ["+49 30 1234567"],
    "extractedUrls": ["https://www.beispiel-tech.de/karriere"],
    "applyUrl": "https://www.jobware.de/apply/beispiel-softwareentwickler-m-w-d-063994828",
    "companyUrl": "https://www.beispiel-tech.de",
    "companyLogo": "https://www.jobware.de/logos/beispiel-tech.png",
    "jobUrl": "https://www.jobware.de/job/beispiel-softwareentwickler-m-w-d-063994828",
    "jobId": "2045198555",
    "searchQuery": "Softwareentwickler",
    "scrapedAt": "2026-06-19T14:30:00Z"
}
```

#### Core Fields

| Field | Type | Description |
|-------|------|-------------|
| `title` | string | Job title (Stellentitel) |
| `company` | string | Hiring company / employer name |
| `location` | string | Location string as shown on the listing |
| `city` | string | City of the advertised workplace, taken from the job's own address rather than the employer's head office. Empty when the ad names no single workplace (e.g. Germany-wide or fully remote roles) |
| `zipCode` | string | Postal code (PLZ) of that same workplace, when the ad states one |
| `employmentType` | string | Vollzeit, Teilzeit, Werkstudent, etc. |
| `workHours` | string | Weekly hours stated in the ad, e.g. `37,5 Std./Woche` or `20–30 Std./Woche` (empty when the ad names no hours) |
| `isRemote` | boolean | `true` for remote / home-office roles, `false` when the listing states its work model and it is on-site |
| `salaryText` | string | Annual gross pay in euros, e.g. `60.000 € – 80.000 € pro Jahr`. Always annual: hourly and monthly figures are left out rather than shown as if they were a yearly salary, so student and internship roles usually show nothing here. Values ending in `(Schätzung)` are Jobware's own estimate for the role rather than a figure stated in the ad. Best-effort; many listings state no pay at all |
| `postedDate` | string | Publication date (ISO 8601) |
| `deadline` | string | Application deadline when present (ISO 8601) |

#### Description

| Field | Type | Description |
|-------|------|-------------|
| `descriptionSnippet` | string | Short teaser from the result card |
| `description` | string | Full plain-text description (when details are fetched) |
| `descriptionHtml` | string | Full HTML description (when format is HTML or Both) |
| `requirements` | string | Requirements / profile section when separable |
| `companyBenefits` | array | Listed benefits and perks when present |

#### Contacts

| Field | Type | Description |
|-------|------|-------------|
| `contactName` | string | Recruiter / contact-person name |
| `contactEmail` | string | Recruiter contact email |
| `contactPhone` | string | Recruiter contact phone |
| `extractedEmails` | array | All emails found in the ad body |
| `extractedPhones` | array | All phone numbers found in the ad body |
| `extractedUrls` | array | External application / company web addresses found in the ad. Addresses written the German way, without `https://` (`www.firma.de`), are picked up too and returned ready to click; the same address written twice appears once |

#### Company & Metadata

| Field | Type | Description |
|-------|------|-------------|
| `applyUrl` | string | Application URL |
| `companyUrl` | string | Company website / profile URL |
| `companyLogo` | string | Company logo image URL |
| `jobUrl` | string | Canonical Jobware job-page URL |
| `jobId` | string | Jobware listing identifier |
| `searchQuery` | string | Which keyword produced this row |
| `scrapedAt` | string | ISO timestamp of data extraction |

### Tips for Best Results

- **Use specific German keywords** — Jobware indexes German job titles, so "Softwareentwickler" or "Pflegefachkraft" return far more than English equivalents. Search the term a German job-seeker would type.
- **Batch related keywords for broad coverage** — because each keyword caps at about 2,248 results, splitting a wide search into several specific titles ("Java Entwickler", "Backend Entwickler", "Fullstack Entwickler") collects far more than one generic term.
- **Keep details on for lead data** — recruiter name, email, phone, salary, and benefits only populate when full details are fetched. Turn details off only when you need a fast title-and-company scan.
- **Start small, then scale** — set `maxResults` to 50 on a first run to confirm the data fits your needs before pulling thousands.
- **Sort by Newest first for monitoring** — pair `sortBy: "date"` with a 24-hour or 3-day window to capture only freshly posted openings on a recurring schedule.
- **Combine keywords and URLs** — mix search keywords with pasted Jobware URLs in a single run; everything is merged and de-duplicated automatically.
- **Choose Both formats for republishing** — request both text and HTML when you need clean text for analysis and formatted HTML for display in one pass.

### Pricing

**From $3.00 per 1,000 results** — undercuts comparable Jobware extractors while returning recruiter contacts and ~30 fields per job. Bronze, Silver, and Gold subscribers pay progressively less; the table below shows total cost at each discount tier.

| Results | No discount | Bronze | Silver | Gold |
|---------|-------------|--------|--------|------|
| 100 | $0.36 | $0.34 | $0.32 | $0.30 |
| 1,000 | $3.60 | $3.40 | $3.20 | $3.00 |
| 10,000 | $36.00 | $34.00 | $32.00 | $30.00 |
| 100,000 | $360.00 | $340.00 | $320.00 | $300.00 |

A "result" is any job row in the output dataset. No compute or time-based charges — you pay per result, plus a small fixed per-run start fee.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom APIs on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor is designed for legitimate recruitment research, labor-market analysis, and lead generation. Users are responsible for complying with applicable laws and Jobware's Terms of Service. Recruiter and contact details may constitute personal data under GDPR — handle them lawfully, honor opt-out requests, and never use extracted data for spam, harassment, or any unlawful purpose.

# Actor input Schema

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

Job titles or keywords to search for on Jobware, such as 'Softwareentwickler', 'Projektmanager', or 'Pflegefachkraft'. Each keyword runs a separate search and the results are merged and de-duplicated. Up to 50 keywords per run. Leave empty if you only want to use direct URLs below.

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

Paste links straight from Jobware.de. A job link (for example https://www.jobware.de/job/sales-manager-m-w-d-064064750) returns that one job, so you can copy any Job URL from your results back in here to re-fetch it. A search link (for example https://www.jobware.de/jobs--fuer-softwareentwickler--in-berlin) is scraped with its filters exactly as-is, and every matching listing is resolved in one pass. Links that are neither are skipped and named in the run status rather than turned into an unrelated search. Up to 100 URLs per run.

## `location` (type: `string`):

A German city or region, such as 'Berlin', 'München', 'Hamburg', or 'Nordrhein-Westfalen'. Matched to the nearest Jobware area. Leave empty to search all of Germany.

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

Filter by the type of employment. Leave on 'Any' for all types.

## `datePosted` (type: `string`):

Only show jobs published within this time period. Leave on 'Any time' for all listings.

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

Order the results by relevance to your keyword or by how recently the job was posted.

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

Maximum number of jobs to collect per search keyword. Use 50 for a quick scan or a higher number for deep research. Note: Jobware returns at most about 2,200 jobs for any single keyword search, so values above that will simply return everything available for that keyword.

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

Fetch the full description, salary, deadline, and recruiter contact details from each job's detail page. Leave on for the richest data. Turn off for faster, lighter scans — the description, salary, and contact fields will then be empty.

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

How to return the job description. 'Text' gives clean plain text, 'HTML' preserves formatting, 'Both' includes each in its own field.

## Actor input object example

```json
{
  "searchQueries": [
    "Softwareentwickler"
  ],
  "startUrls": [],
  "location": "",
  "employmentType": "",
  "datePosted": "",
  "sortBy": "relevance",
  "maxResults": 50,
  "includeJobDetails": true,
  "descriptionFormat": "text"
}
```

# Actor output Schema

## `overview` (type: `string`):

Table of scraped job listings with key fields.

## `detail` (type: `string`):

Complete job records including descriptions, salary, recruiter contact details, and company metadata.

# 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 = {
    "searchQueries": [
        "Softwareentwickler"
    ],
    "startUrls": [],
    "location": "",
    "employmentType": "",
    "datePosted": "",
    "sortBy": "relevance",
    "maxResults": 50,
    "includeJobDetails": true,
    "descriptionFormat": "text"
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/jobware-de-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 = {
    "searchQueries": ["Softwareentwickler"],
    "startUrls": [],
    "location": "",
    "employmentType": "",
    "datePosted": "",
    "sortBy": "relevance",
    "maxResults": 50,
    "includeJobDetails": True,
    "descriptionFormat": "text",
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/jobware-de-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 '{
  "searchQueries": [
    "Softwareentwickler"
  ],
  "startUrls": [],
  "location": "",
  "employmentType": "",
  "datePosted": "",
  "sortBy": "relevance",
  "maxResults": 50,
  "includeJobDetails": true,
  "descriptionFormat": "text"
}' |
apify call solidcode/jobware-de-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solidcode/jobware-de-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/ejsXvzEgVa8M6IMdT/builds/zVdS6tj0gLON48ELJ/openapi.json
