# Sweden Jobs, Czech & Belgium: Public Employment (`maliksaid/public-employment-jobs`) Actor

Job vacancies from official public employment services in one schema: Sweden Arbetsförmedlingen (Platsbanken), Czech Labour Office (Úřad práce ČR) and Belgium Le Forem. Keyword, location and date filters. Monitor mode returns only new jobs. Contact details removed.

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

## Pricing

from $0.80 / 1,000 jobs

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

## Public Employment Jobs: Sweden, Czechia, Belgium

Get job vacancies from official public employment services in one schema. The Actor reads Sweden's Arbetsförmedlingen (Platsbanken), the Czech Labour Office (Úřad práce ČR) and Belgium's Le Forem (Wallonia). Each job has the same fields, whatever the country. Contact person names, emails and phone numbers are removed.

Use it for labour market research, job boards, recruitment leads and hiring trend tracking.

### What it covers

| Country | Service | Jobs on 22 Oct 2026 | Source |
|---|---|---|---|
| Sweden | Arbetsförmedlingen, Platsbanken | 43,066 | JobTech JobSearch API (open data, CC0) |
| Czechia | Úřad práce ČR (Czech Labour Office) | 39,782 | MPSV open data, daily file |
| Belgium (Wallonia) | Le Forem | 24,564 | Open Data Wallonie-Bruxelles (CC BY-SA 4.0) |

A full run on 22 Oct 2026 saved 107,412 jobs.

### What you get

The main fields have the same names as in [Career Site Jobs](https://apify.com/maliksaid/career-site-jobs), which reads company career sites (Greenhouse, Lever, Ashby, Workable, Recruitee). You can merge both datasets without mapping.

| Field | Meaning |
|---|---|
| `title`, `company`, `companyId` | Job title, employer and registration number (Sweden, Czechia) |
| `occupation` | Occupation in the source's classification |
| `location`, `locations`, `region`, `postalCode`, `country` | Where the job is |
| `latitude`, `longitude` | Workplace coordinates (Sweden, Belgium) |
| `employmentType`, `workingHours`, `contractDuration`, `vacancies` | Contract details |
| `remote`, `workplaceType` | Remote, hybrid or on-site, when the source states it (Sweden) |
| `postedAt`, `updatedAt`, `expiresAt` | First published, last changed (Czechia), closing date |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salaryText` | Pay. Czechia gives numbers in CZK. Sweden gives the pay type as text |
| `jobUrl`, `applyUrl` | Link to the job on the official site, and the employer's application page |
| `descriptionSnippet`, `description` | Start of the posting text, or the full text when you turn it on |
| `source`, `sourceName`, `sourceCountry`, `language` | Where the record comes from |
| `occupationField` | Broad occupation field (Sweden) |
| `experienceRequired`, `drivingLicenseRequired` | Whether experience or a driving licence is required (Sweden, Belgium). null when the source does not say |
| `skillsRequired`, `skillsPreferred` | Skills the employer requires or would like (Sweden) |
| `languagesRequired` | Languages the employer requires (Sweden, Belgium) |
| `changeType` | `listed`, or `new` in monitor mode. `closed` for a job that is gone, when you turn on closed jobs |

Sample record (Sweden):

```json
{
    "id": "se:31631381",
    "changeType": "listed",
    "source": "se-platsbanken",
    "sourceName": "Arbetsförmedlingen Platsbanken (Sweden)",
    "sourceCountry": "SE",
    "jobId": "31631381",
    "title": "Skiftchefer – ABB Machines",
    "company": "ABB AB",
    "companyId": "5591930903",
    "department": "Västerås, Elmotorgatan 2",
    "occupation": "Gruppchef, teknik",
    "location": "Västerås, Västmanlands län, Sweden",
    "locations": ["Västerås, Västmanlands län, Sweden"],
    "region": "Västmanlands län",
    "postalCode": "72136",
    "country": "Sweden",
    "latitude": 59.6359535868983,
    "longitude": 16.58664403649,
    "remote": false,
    "workplaceType": "on-site",
    "employmentType": "Permanent (may start with a trial period)",
    "workingHours": "Full-time",
    "contractDuration": "Tills vidare",
    "vacancies": 2,
    "postedAt": "2026-10-22T11:30:45",
    "updatedAt": null,
    "expiresAt": "2026-11-14T23:59:59",
    "salaryMin": null,
    "salaryMax": null,
    "salaryCurrency": null,
    "salaryPeriod": null,
    "salaryText": "Fast månads- vecko- eller timlön",
    "applyUrl": "https://careers.abb/sweden/se/job/JR00038454/Skiftchefer-ABB-Machines",
    "jobUrl": "https://arbetsformedlingen.se/platsbanken/annonser/31631381",
    "language": "sv",
    "descriptionSnippet": "På ABB hjälper vi industrier att bli mer resurseffektiva och renare – och varje person här bidrar till resultaten. Du kommer att få möjlighet att leda, få stöd att växa och kunna vara stolt över den påverkan vi skapar tillsammans. Gå med oss och hjälp till att driva det som driver världen. Denna...",
    "scrapedAt": "2026-10-22T09:32:11.094Z"
}
```

A Czech record from the same run: "Dělník/pekař" at Merhautovo pekařství, s.r.o., Milovice, "25000 to 28000 CZK per month", "38 hours per week".

Empty fields: a field is `null` when the source does not publish it. Belgium's open data has no description, salary or company number. Its `descriptionSnippet` lists the sector, experience, education and languages instead. Czech salary numbers are copied as the employer entered them.

### How to use it

1. Pick the countries, or leave the list empty for all three.
2. Add keywords in the posting language, for example "sjuksköterska", "kuchař" or "soudeur". English words also work for jobs posted in English.
3. Add locations and a date limit if you need them.
4. Set **Maximum jobs** to 0 to get every match.
5. Turn on **Monitor mode** and schedule the Actor daily to receive only new jobs. Also turn on **Monitor mode: report closed jobs** and set **Maximum jobs** to 0 to see which jobs were filled or withdrawn. Closed rows are free.

### Input

| Option | Default | Meaning |
|---|---|---|
| Keywords | None | Keep jobs whose title, occupation or company contains a keyword. Whole words, case and accents ignored |
| Exclude keywords | None | Drop jobs whose title contains one of these words |
| Countries | All | SE, CZ, BE |
| Locations | None | Keep jobs in these towns, regions, postal codes or countries |
| Posted within (days) | 0 (any) | Keep jobs first published in the last N days |
| Include full description | Off | Add the posting text, up to 8,000 characters (Sweden, Czechia) |
| Monitor mode | Off | Return only jobs not returned before under the same monitor name |
| Monitor mode: report closed jobs | Off | Also return jobs seen before that are gone now, as free `closed` rows. Needs Maximum jobs 0 |
| Monitor name (`monitorName`) | `default` | Name of the monitor memory. The old field name `stateKey` still works |
| Maximum jobs | 100 | Stop after this many jobs, shared across countries. Set 0 for no limit |

Example: new nursing jobs in Stockholm from the last 7 days.

```json
{
    "countries": ["SE"],
    "keywords": ["sjuksköterska"],
    "locations": ["Stockholm"],
    "postedWithinDays": 7,
    "maxItems": 0
}
```

### Pricing

You pay a small fee per run and a fee for each job saved. Jobs skipped by your filters cost nothing.

| Event | Free plan | GOLD plan and higher |
|---|---|---|
| Run start | $0.012 | $0.012 |
| Job | $0.001 ($1.00 per 1,000) | $0.0008 ($0.80 per 1,000) |

| Jobs in one run | Free plan | GOLD plan and higher |
|---|---|---|
| 100 | $0.112 | $0.092 |
| 1,000 | $1.012 | $0.812 |

Costs include the run start fee.

### Data sources and use

- Sweden: JobTech JobSearch API by Arbetsförmedlingen. Ads are published under CC0.
- Czechia: Ministry of Labour and Social Affairs (MPSV) open data. The terms state no copyright and no database right.
- Belgium: Le Forem job offers on Open Data Wallonie-Bruxelles, licence CC BY-SA 4.0. If you republish this data, credit Le Forem and keep the same licence.
- The Actor reads each official open data service once per run. It needs no login and no key.
- The Actor saves job fields only. It never saves contact person names, emails or phone numbers. Lines in the posting text that hold contact details are removed.
- Germany (Bundesagentur für Arbeit), France (France Travail), Norway (NAV) and the US (USAJOBS) are not included. Their terms or key rules do not allow this kind of reuse without each user's own registration.

### Support

Report a problem in the Issues tab. Include the run link.

# Actor input Schema

## `keywords` (type: `array`):

Keep jobs whose title, occupation or company contains at least one keyword, for example "nurse", "sjuksköterska", "kuchař" or "soudeur". Keywords match whole words and ignore case and accents. Postings are in the local language. Leave empty to keep every job.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words, for example "intern" or "praktik".

## `countries` (type: `array`):

Which public employment services to read. Leave empty for all three.

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

Keep jobs in any of these places. Use a city, region, postal code or country as the source writes it, for example "Göteborg", "Praha", "Namur" or "Stockholms län". Accents are optional. Leave empty for every location.

## `postedWithinDays` (type: `integer`):

Keep only jobs first published in the last N days. 0 means any date.

## `includeDescription` (type: `boolean`):

Add a description field with the posting text, up to 8,000 characters. Lines with contact details are removed. Sweden and Czechia only; Belgium has no description in its open data.

## `monitorMode` (type: `boolean`):

Return only jobs that earlier monitor-mode runs with the same monitor name did not return. The first run returns every matching job. Schedule the Actor with this on to get a daily feed of new jobs.

## `reportClosed` (type: `boolean`):

With monitor mode, also return jobs seen in an earlier run that are gone now. Closed rows are free. Works only with maximum jobs set to 0.

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

Name of the memory that monitor mode uses. Use a different name for each separate search. Inputs that still send the old field `stateKey` keep working.

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

Stop after saving this many jobs. The limit is shared across the selected countries. The default keeps test runs short and cheap. Set 0 for no limit.

## Actor input object example

```json
{
  "keywords": [
    "engineer"
  ],
  "excludeKeywords": [],
  "countries": [],
  "locations": [],
  "postedWithinDays": 0,
  "includeDescription": false,
  "monitorMode": false,
  "reportClosed": false,
  "monitorName": "default",
  "maxItems": 100
}
```

# 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 = {
    "keywords": [
        "engineer"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("maliksaid/public-employment-jobs").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 = {
    "keywords": ["engineer"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("maliksaid/public-employment-jobs").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 '{
  "keywords": [
    "engineer"
  ],
  "maxItems": 100
}' |
apify call maliksaid/public-employment-jobs --silent --output-dataset

```

## MCP server setup

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

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/y5UAF54CtfZ09qsNo/builds/LQLolgNcjeDtLSOV6/openapi.json
