# Arbetsförmedlingen Jobs Scraper – Swedish Public Job Ads (`listingworks/arbetsformedlingen-jobs-scraper`) Actor

Extract Swedish public job ads from the official Arbetsförmedlingen JobTech API by keyword, municipality, region, occupation and employment type: employer, workplace, occupation, hours, salary type, posting and closing date. No contact details. JSON, CSV or Excel.

- **URL**: https://apify.com/listingworks/arbetsformedlingen-jobs-scraper.md
- **Developed by:** [Yusuke Suda](https://apify.com/listingworks) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 result items

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/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

## Arbetsförmedlingen Jobs Scraper — Swedish public job ads

Extract Swedish public job ads from the official Arbetsförmedlingen JobTech API by keyword, municipality, region, occupation and employment type: employer, workplace, occupation, hours, salary type, posting and closing date. No contact details.

### Three rows from a real run

| Title | Employer | Workplace | Occupation | Published |
| --- | --- | --- | --- | --- |
| Rekondchef till ledande aktör inom fordonsbranschen | Aura Personal AB | Strängnäs, Södermanlands län | Bilrekonditionerare | 2026-10-21 |
| Kundmottagare sökes till däcksäsong i Stockholm | Aura Personal AB | Stockholm, Stockholms län | Kundmottagare/Arbetsledare bilverkstad | 2026-10-21 |
| Kundmottagare sökes i Stockholm | Aura Personal AB | Stockholm, Stockholms län | Kundmottagare/Arbetsledare bilverkstad | 2026-10-21 |

The default run (no filter, `maxItems: 100`) on 21 October 2026 returned 100 ads in 11 seconds and costs $0.15 at $1.50 per 1,000 results. The API held 42,204 ads that day.

Arbetsförmedlingen, the Swedish Public Employment Service, publishes the ads of Platsbanken through its open JobTech JobSearch API. This Actor asks that API, not the website: no page is scraped and no key is needed. Places, occupations and employment types can be given by name; the Actor looks them up in the JobTech taxonomy.

Press Start. The defaults return the first 100 ads the API serves for all of Sweden (newest first when no keyword is given).

### What a row looks like

```json
{
  "id": "31623537",
  "title": "Rekondchef till ledande aktör inom fordonsbranschen",
  "employer_name": "Aura Personal AB",
  "employer_website": "https://www.aurapersonal.se",
  "workplace_city": "Strängnäs",
  "workplace_municipality": "Strängnäs",
  "workplace_region": "Södermanlands län",
  "workplace_country": "Sverige",
  "occupation": "Bilrekonditionerare",
  "occupation_group": "Bilrekonditionerare, fönsterputsare m.fl.",
  "occupation_field": "Sanering och renhållning",
  "employment_type": "Vanlig anställning",
  "working_hours": "Heltid",
  "duration": "Tills vidare",
  "salary_type": "Fast månads- vecko- eller timlön",
  "salary_description": "",
  "number_of_vacancies": 1,
  "published_at": "2026-10-21",
  "application_deadline": "2026-11-20",
  "remote": null,
  "url": "https://arbetsformedlingen.se/platsbanken/annonser/31623537",
  "source_url": "https://arbetsformedlingen.se/platsbanken/annonser/31623537"
}
```

No contact details are kept: the API returns each ad's contact persons, e-mail addresses and phone numbers, the ad text and the workplace street address, and the Actor drops them before anything is stored. The employer's name goes through the catalogue's person-name rule: where it is a person's own name (a sole trader), it is left empty and `employer_name_withheld` is true (0 of 100 in the example run).

Every row also carries `employer_name_withheld`, `source_site` and `scraped_at`.

| Field | What it holds | How often it is filled (example run, 100 rows) |
|---|---|---|
| `id`, `title` | The ad's id at Arbetsförmedlingen; its headline | Always |
| `employer_name` | Employer (organisation); empty where it is a person's own name | Always |
| `employer_website` | Employer's website where the ad gives one | Always |
| `workplace_city`, `workplace_municipality`, `workplace_region`, `workplace_country` | Where the job is | Always |
| `occupation`, `occupation_group`, `occupation_field` | Occupation, its SSYK group and field (JobTech taxonomy) | Always |
| `employment_type` | e.g. Vanlig anställning, Vikariat, Behovsanställning | Always |
| `working_hours` | Heltid / Deltid | 94 of 100 |
| `duration` | How long the job lasts | 94 of 100 |
| `salary_type` | How pay is set (fixed, commission, …) | Always |
| `salary_description` | Pay as the employer describes it | 0 of 100 |
| `number_of_vacancies` | Places to fill | Always |
| `published_at`, `application_deadline` | Day published; closing day | Always |
| `remote` | true when the ad marks remote work (or remote was asked for) | 0 of 100 |
| `url`, `source_url` | The ad on Platsbanken (both the same page) | Always |

### Input

| Field | What it does |
|---|---|
| `keyword` | Free text, searched in the headline, the ad text and the employer name, e.g. `sjuksköterska`, `lärare`, `developer`. |
| `municipality` | A municipality by name or code, e.g. `Stockholm`, `Göteborg`, `0180`. |
| `region` | A region (län) by name or code, e.g. `Stockholm` (Stockholms län), `Skåne`, `01`. |
| `country` | A country by Swedish name or ISO code, e.g. `Norge`, `NO` (ads for work abroad). |
| `occupationField`, `occupationGroup` | As the JobTech taxonomy names them, e.g. `Data/IT`, `Grundskollärare`. |
| `employmentType` | e.g. `Vanlig anställning`, `Vikariat`, `Behovsanställning`. |
| `publishedAfter` | Only ads published on or after this day. |
| `remote` | Only ads the API marks as likely to allow remote work (it matches phrases in the ad). |
| `maxItems` | Stop after this many ads (2,000 at most). |

A name the taxonomy does not know returns no rows and says so in the run's status.

### How it works

The Actor sends one search to the API and reads its results 100 at a time, waiting a second between pages; a "too many requests" answer is retried after a pause. The API serves the first 2,100 ads of any search, so a run returns 2,000 at most: narrow a broad search by place, occupation or date to reach the rest.

### Pricing

$1.50 per 1,000 results (event `result-item`), no start fee. Set a maximum charge per run in the run options to cap it.

### Good to know

- The data is what the API serves on the day of the run.
- Questions or a missing field: open an issue on this Actor.

# Actor input Schema

## `keyword` (type: `string`):

Free text, searched in the ad headline, text and employer name, e.g. sjuksköterska, lärare, developer. Empty: every ad.

## `municipality` (type: `string`):

A Swedish municipality by name or code, e.g. Stockholm, Göteborg, 0180.

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

A Swedish region by name or code, e.g. Stockholm (Stockholms län), Skåne, 01.

## `country` (type: `string`):

A country by Swedish name or ISO code, e.g. Norge or NO (ads for work abroad).

## `occupationField` (type: `string`):

An occupation field as the JobTech taxonomy names it, e.g. Data/IT, Pedagogik, Hälso- och sjukvård.

## `occupationGroup` (type: `string`):

An occupation group (SSYK level 4) as the taxonomy names it, e.g. Grundskollärare, Mjukvaru- och systemutvecklare m.fl.

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

An employment type as the taxonomy names it, e.g. Vanlig anställning, Vikariat, Behovsanställning.

## `publishedAfter` (type: `string`):

Only ads published on or after this day (YYYY-MM-DD).

## `remote` (type: `boolean`):

Only ads the API marks as likely to allow remote work (it matches phrases in the ad).

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

Stop after this many ads (2,000 at most: the API serves the first 2,100 of a search).

## Actor input object example

```json
{
  "keyword": "sjuksköterska",
  "municipality": "",
  "region": "",
  "country": "",
  "occupationField": "",
  "occupationGroup": "",
  "employmentType": "",
  "publishedAfter": "",
  "remote": false,
  "maxItems": 100
}
```

# Actor output Schema

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

The ads of the run.

## `runReport` (type: `string`):

Ads delivered, the API's total, filters and warnings.

# 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 = {
    "keyword": "sjuksköterska"
};

// Run the Actor and wait for it to finish
const run = await client.actor("listingworks/arbetsformedlingen-jobs-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 = { "keyword": "sjuksköterska" }

# Run the Actor and wait for it to finish
run = client.actor("listingworks/arbetsformedlingen-jobs-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 '{
  "keyword": "sjuksköterska"
}' |
apify call listingworks/arbetsformedlingen-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,listingworks/arbetsformedlingen-jobs-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/0KL9MrTnE80sQd0YQ/builds/mnoV1NBgHjOFYUkcw/openapi.json
