# Sweden Jobtech Jobs Scraper (`zerobreak/sweden-jobtech-jobs-scraper-202610120341`) Actor

Sweden JobTech Jobs Scraper is a Python tool designed to extract job listings, employer details, geographic locations, requirements, and posting dates from the Swedish JobTech (Arbetsförmedlingen) API. It exports structured labor market data into clean CSV or JSON formats for career analysis.

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

## Pricing

from $2.99 / 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

### Sweden JobTech Jobs Scraper — Collect Swedish Platsbanken Job Ads

### Overview

Sweden JobTech Jobs Scraper collects publicly available job advertisements from Sweden's Platsbanken job service and saves them as structured dataset records. Search by keyword, filter by municipality concept ID, or retrieve a specific advertisement using its job ID.

The collected data includes job titles, descriptions, employers, employment types, occupations, application deadlines, and other available listing details. Export your dataset in JSON, CSV, or Excel format.

### Features

- **Keyword search:** Find job advertisements matching terms such as Python, Django, or software development.
- **Municipality filtering:** Narrow search results using a municipality concept ID.
- **Single-ad retrieval:** Retrieve a specific job advertisement using its Platsbanken ID.
- **Structured job data:** Collect employer details, job descriptions, vacancy counts, and application deadlines.
- **HTML cleanup:** Convert job description content into plain text.
- **Duplicate removal:** Prevent duplicate records based on advertisement IDs.
- **Configurable result limits:** Control the number of records saved per run, up to 1,000.
- **Multiple export formats:** Download results as JSON, CSV, or Excel.

### Use Cases

- **Hiring research:** Find current Swedish vacancies and organize them by title, employer, and application deadline.
- **Local job lists:** Collect opportunities associated with a specific municipality.
- **Individual vacancy lookup:** Retrieve a particular advertisement when its Platsbanken ID is known.
- **Technology job research:** Search for roles involving Python, web development, data engineering, and other skills.
- **Recruitment analysis:** Compare employers, employment types, occupations, and vacancy counts.
- **Scheduled data collection:** Refresh job datasets periodically to track newly available opportunities.

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | String | `search` | Select `search` to find advertisements or `ad` to retrieve one advertisement by ID. |
| `query` | String | `python` | Search phrase matched against job headlines, advertisement text, and employer names. |
| `municipality` | String | Empty | Optional municipality taxonomy concept ID used to filter search results. |
| `adId` | String | Empty | Platsbanken advertisement ID required when using `ad` mode. |
| `maxItems` | Integer | `100` | Maximum number of dataset rows to save, including any error records. Maximum: 1,000. |
| `timeoutSecs` | Integer | `300` | Overall run time limit in seconds. Records already saved are retained when the run stops. |
| `requestTimeoutSecs` | Integer | `30` | Maximum time to wait for an individual request, in seconds. |

### Example Input

#### Search for Python jobs

```json
{
  "mode": "search",
  "query": "python",
  "municipality": "",
  "adId": "",
  "maxItems": 100,
  "timeoutSecs": 300,
  "requestTimeoutSecs": 30
}
```

#### Search within a municipality

```json
{
  "mode": "search",
  "query": "python",
  "municipality": "qk8Y_2b6_82D",
  "maxItems": 100
}
```

Replace the municipality concept ID with the identifier for the area you want to search.

#### Retrieve a specific advertisement

```json
{
  "mode": "ad",
  "adId": "31579964",
  "maxItems": 1
}
```

Use the advertisement's Platsbanken ID in `adId` to retrieve a specific job listing.

### What Data Does This Actor Extract?

Each collected advertisement becomes a dataset row. The actor stores the job description under `jobDescription` and removes HTML markup from its text fields where applicable.

#### Extracted Data Fields

| Field | Type | Description |
|---|---|---|
| `relevance` | Number | Search relevance score when provided. |
| `id` | String | Platsbanken advertisement ID. |
| `external_id` | String or null | External identifier when available. |
| `original_id` | String or null | Original advertisement identifier when available. |
| `label` | Array | Labels associated with the advertisement. |
| `webpage_url` | String | Public page for the job advertisement. |
| `logo_url` | String | Employer logo location when available. |
| `headline` | String | Job advertisement headline. |
| `application_deadline` | String | Application deadline supplied with the advertisement. |
| `number_of_vacancies` | Number | Number of vacancies listed. |
| `jobDescription` | Object | Job description content, including available text fields. |
| `employment_type` | Object | Employment type concept and label. |
| `employer` | Object | Employer information, such as name, workplace, and organization number. |
| `occupation` | Object | Occupation concept and label. |
| `scrapedAt` | String | UTC timestamp indicating when the record was saved. |

Some fields may be absent or null depending on the information available for an individual advertisement.

#### Example Output

```json
{
  "relevance": 1.0,
  "id": "31579964",
  "external_id": null,
  "original_id": null,
  "label": [],
  "webpage_url": "JOB_LISTING_URL",
  "logo_url": "EMPLOYER_LOGO_URL",
  "headline": "Python Developer Team Lead",
  "application_deadline": "2026-11-08T23:59:59",
  "number_of_vacancies": 2,
  "jobDescription": {
    "text": "Vi soker en Senior Teamledare / Tech Lead",
    "text_formatted": "Vi soker en Senior Teamledare / Tech Lead"
  },
  "employment_type": {
    "concept_id": "sTu5_NBQ_udq",
    "label": "Tidsbegransad anstallning"
  },
  "employer": {
    "name": "Hykmann Global Business Solutions AB",
    "workplace": "Lantmateriet",
    "organization_number": "5594904012"
  },
  "occupation": {
    "concept_id": "FC86_VDF_rqB",
    "label": "Teamledare"
  },
  "scrapedAt": "2026-10-12T03:00:00+00:00"
}
```

The example demonstrates the expected record structure. Actual values depend on the selected search criteria and the information available for each advertisement.

### Working with Your Dataset

Once collection is complete, you can:

- Export records as JSON, CSV, or Excel.
- Sort advertisements by application deadline or publication-related information when available.
- Group vacancies by employer, occupation, or employment type.
- Search job descriptions for relevant technologies and skills.
- Analyze vacancies by municipality when using municipality filters.
- Import the results into spreadsheets, recruitment workflows, or data analysis tools.

### Important Notes

- Search mode uses the `query` parameter to find matching advertisements.
- The `municipality` parameter accepts a municipality concept ID rather than a municipality name.
- Single-ad mode uses `adId` to identify the requested advertisement.
- The default maximum is 100 records per run, with a hard maximum of 1,000.
- Search results are collected in pages, and the actor stops when the item limit or available result range is reached.
- Duplicate advertisements are identified using their `id` field.
- Some fields may be missing because the original advertisement does not provide them.
- Job availability, descriptions, and application deadlines can change over time.
- Review the applicable data license before redistributing or republishing collected information.

### FAQ

**How many advertisements can one run collect?**

The default limit is 100 records per run. You can increase `maxItems` to 1,000.

**Can I search for jobs in a particular municipality?**

Yes. Provide the appropriate municipality concept ID in the `municipality` parameter.

**Can I retrieve just one job advertisement?**

Yes. Set `mode` to `ad` and provide the advertisement ID through `adId`.

**What happens if my search returns no matching advertisements?**

The actor may produce an error record instead of job records. Check the run output and your search parameters if no advertisements are returned.

**Why is the job description field called `jobDescription`?**

The actor stores the original description content under `jobDescription` to maintain a compatible dataset schema and removes HTML markup from its text content.

**Can I export the results to a spreadsheet?**

Yes. The collected dataset supports JSON, CSV, and Excel exports.

**Will every run return the same advertisements?**

Not necessarily. The results depend on the search query, municipality filter, available listings, and time of collection.

### Disclaimer

This is an independent tool and is not affiliated with, endorsed by, sponsored by, or officially associated with Sweden JobTech, Arbetsförmedlingen, or their respective owners. Users are responsible for ensuring that their collection, storage, redistribution, and use of collected information comply with applicable laws and licensing conditions.

### Is Web Scraping Legal?

Collecting information that is already public is generally legal. Scraping is not the same thing as hacking, and there is no single law that bans it. The limits are the usual ones: do not break into accounts, do not take private or confidential data, and be careful with personal data and copyrighted works. A site's terms can also restrict how you access it. Facts such as a public name, price, or rating are not the same thing as republishing someone's article or photo.

This actor collects information from public pages. It does not log in and it does not bypass access controls.

For a longer explanation, see Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

# Actor input Schema

## `mode` (type: `string`):

search lists Platsbanken ads from the JobTech search endpoint. ad loads one full ad by id.

## `query` (type: `string`):

Free-text query sent as q on the search endpoint. Matches headline, ad text, and employer name. Default is python.

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

Optional municipality concept id from the JobTech taxonomy, sent as the municipality query parameter. Example qk8Y_2b6_82D is Gavle. Leave blank to search all of Sweden.

## `adId` (type: `string`):

Platsbanken ad id used only when mode is ad. Example 31579964 loads that vacancy from the ad endpoint.

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

Free cap on dataset rows this run, including error rows. Hard max 1000.

## `timeoutSecs` (type: `integer`):

Stop the run after this many seconds and keep rows already saved.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for a single JobTech response before retrying.

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

Optional proxy for JobTech requests. Default is no proxy.

## Actor input object example

```json
{
  "mode": "search",
  "query": "python",
  "municipality": "qk8Y_2b6_82D",
  "adId": "31579964",
  "maxItems": 100,
  "timeoutSecs": 300,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset of Platsbanken ads and error rows.

## `datasetItems` (type: `string`):

JSON items from the default dataset.

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

Table of relevance, job id, external id, webpage, and source URL.

# 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 = {
    "query": "python",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zerobreak/sweden-jobtech-jobs-scraper-202610120341").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 = {
    "query": "python",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("zerobreak/sweden-jobtech-jobs-scraper-202610120341").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 '{
  "query": "python",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call zerobreak/sweden-jobtech-jobs-scraper-202610120341 --silent --output-dataset

```

## MCP server setup

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

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/eDDUeK4L1pbrrDiWS/builds/1usWa5du3ZQHZOlYJ/openapi.json
