# Work24 (고용24) Korea Job Postings Scraper (`ardent_fork/work24-korea-jobs`) Actor

Job postings from Korea's government job portal work24.go.kr: title, company, salary (structured KRW), region, deadline, employment type, hours, benefits, full description. Keyword and region filters. No login, no API key.

- **URL**: https://apify.com/ardent\_fork/work24-korea-jobs.md
- **Developed by:** [KF P](https://apify.com/ardent_fork) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Work24 (고용24) Korea Job Postings Scraper

Scrapes job postings from **work24.go.kr**, the Korean government's job portal (formerly WorkNet). It lists well over 100,000 open positions with the fields commercial boards often hide: exact salary, employment type, weekly hours, social insurance, address, application deadline. No login, no API key, no proxy needed. Pay-per-event: **one `job` event per posting saved**.

### What you get

One dataset item per posting. With `fetchDetails: true` (default):

| field | example |
|---|---|
| `id` | `K180612609010034` (구인인증번호) |
| `url` | link to the posting on work24.go.kr |
| `title`, `company` | `평택 성광요양원에서 … 요양보호사 …`, `성광요양원` |
| `salaryText`, `salaryType`, `salaryMin`, `salaryMax` | `월급 246만원 이상`, `월급`, `2460000`, `null` (KRW; type is 시급/일급/주급/월급/연봉) |
| `career`, `education` | `관계없음`, `학력무관` |
| `employmentType`, `workType`, `workHours`, `workDays` | `기간의 정함이 있는 근로계약 …`, `주 5일 근무`, `주 소정근로시간 : 40시간 …`, `주5일` |
| `address`, `regionShort`, `nearestStation` | full work address, the list's short `시/구/로` string, nearest subway station |
| `deadline`, `untilFilled`, `registeredDate`, `registeredAt` | `2026-09-30`, `false`, `2026-09-01`, `2026-09-01 14:45:55` |
| `openings`, `occupation`, `occupationKeywords`, `requiredLicenses` | `1`, `요양보호사(노인요양사)`, `요양보호사`, `필수\n요양보호사1급` |
| `socialInsurance`, `retirementBenefits`, `benefits` | `국민연금, 고용보험, 산재보험, 건강보험`, `퇴직금`, `["식사 제공 (1식)"]` |
| `description` | full 직무내용 text with line breaks |
| `descriptionUrl` | for 사람인 / 잡코리아 / 인크루트 syndicated postings, the URL of the source-site page that holds the 직무내용; `description` is fetched from it unless `fetchDescriptions` is off |
| `views`, `source` | page views, information provider (e.g. `고용24`) |
| `fields` | every label → value pair of the detail tables (모집 인원, 근무 예정지, 전공, 우대조건, 인증기관, …) so nothing is lost when the site adds a column |

With `fetchDetails: false` you get the list fields only (`id`, `url`, `title`, `company`, salary fields, `career`, `education`, `workDays`, `workHours`, `regionShort`, `deadline`, `untilFilled`, `registeredDate`, `source`) — one request per 50 postings.

### Input

| field | default | notes |
|---|---|---|
| `keyword` | *(empty)* | search term; matches title, company and description like the site's search box |
| `region` | *(empty)* | 5-digit Work24 region code — 11000 서울, 26000 부산, 27000 대구, 28000 인천, 29000 광주, 30000 대전, 31000 울산, 36110 세종, 41000 경기, 43000 충북, 44000 충남, 46000 전남, 47000 경북, 48000 경남, 50000 제주, 51000 강원, 52000 전북; district codes such as 11110 (종로구) also work |
| `maxItems` | 100 | stop after this many postings (max 5000); newest first |
| `fetchDetails` | true | open each posting for the full record |
| `fetchDescriptions` | true | for 사람인 / 잡코리아 / 인크루트 syndicated postings, also fetch the source-site page that holds the 직무내용 (one extra request each) |
| `maxConcurrency` | 5 | parallel fetches |
| `proxyConfiguration` | none | only needed if your IP is blocked |

Example: nurses in Seoul, list data only —

```json
{ "keyword": "간호사", "region": "11000", "fetchDetails": false, "maxItems": 500 }
```

### Pricing

Pay per event: one `job` event per posting saved to the dataset. Nothing is charged for list pages, failed pages or postings that disappeared between the list and the detail fetch. Set **Max total charge** on the run to cap spend; the actor stops cleanly at the budget and never over-charges.

### Notes

- Results are sorted newest first (the portal's `DATE DESC`). The unfiltered feed changes minute by minute, so two runs are not identical.
- `untilFilled` is `true` for 채용시까지 (open until filled) postings; `deadline` still carries the date the portal prints for them (sometimes a placeholder in year 2099).
- Syndicated postings from commercial boards (`source` = 사람인, 잡코리아, 원티드, 인크루트, …; `infoTypeCd` ≠ `VALIDATION`) show up mainly in keyword searches. Their detail pages use a different layout: `career`, `education`, `employmentType`, `address`, `workType`, `workHours`, `retirementBenefits` and `benefits` are filled when stated, `openings` / `registeredAt` are not stated, and the 직무내용 is inline for 원티드-style boards but only an iframe for 사람인 / 잡코리아 / 인크루트 — the actor follows that iframe (`descriptionUrl`, one extra request) to fill `description`; set `fetchDescriptions: false` to skip it, in which case `description` is null for those postings. Source-site text is flattened as-is: 잡코리아 / 인크루트 pages are table layouts, so their `description` may start with a table header line (e.g. `모집분야 및 자격요건`) or a `제공처` line; the run's `SUMMARY` record counts `descriptionsFetched` / `descriptionsFailed`. Postings entered directly on 고용24 (`source: "고용24"`) always have the full record.
- Postings removed between the list fetch and the detail fetch are skipped and not charged.
- Public data only. Nothing behind a login is touched; the actor makes the same requests a browser makes on the public search page.

# Actor input Schema

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

Optional search keyword (Korean works best, e.g. 간호사, 개발자, 용접). Matches the posting title, company name and job description, like the search box on work24.go.kr. Leave empty for the newest postings across the whole portal.

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

Optional 5-digit Work24 region code. Top level: 11000 서울, 26000 부산, 27000 대구, 28000 인천, 29000 광주, 30000 대전, 31000 울산, 36110 세종, 41000 경기, 43000 충북, 44000 충남, 46000 전남, 47000 경북, 48000 경남, 50000 제주, 51000 강원, 52000 전북. District codes (e.g. 11110 종로구) also work.

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

Stop after this many job postings have been saved. Results are newest first; each list page holds 50.

## `fetchDetails` (type: `boolean`):

Open every posting for the full description, exact address, employment type, working hours, insurance, benefits, openings and required licenses. Turn off to get only the list data (title, company, salary, region, deadline) — about 50× fewer requests.

## `fetchDescriptions` (type: `boolean`):

Postings syndicated from 사람인 / 잡코리아 / 인크루트 keep their 직무내용 on the source site (see descriptionUrl). When on (default), one extra request per such posting fetches that text into description. Ignored when Fetch detail pages is off.

## `maxConcurrency` (type: `integer`):

Parallel page fetches.

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

Optional. work24.go.kr serves these pages without a proxy; use one only if your IP is blocked.

## Actor input object example

```json
{
  "keyword": "간호사",
  "region": "11000",
  "maxItems": 500,
  "fetchDetails": true,
  "fetchDescriptions": true,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `postings` (type: `string`):

Dataset items, one per Work24 job posting (title, company, salary, region, deadline, 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 = {
    "keyword": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("ardent_fork/work24-korea-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 = { "keyword": "" }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ardent_fork/work24-korea-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/vA7iJLbg2Eh9nwt3W/builds/TxurgCcTe2GtAruha/openapi.json
