# SEEK Jobs Scraper \[$1💰] | JobsDB | JobStreet | APAC (`ahmed_jasarevic/jobsdb-scraper`) Actor

Scrape SEEK jobs across 6 APAC markets — JobsDB Hong Kong & Thailand, Jora Singapore, JobStreet Indonesia, Malaysia & Philippines. Get titles, companies, salary labels, locations, full descriptions and apply URLs for salary benchmarking, hiring intelligence and job market research.

- **URL**: https://apify.com/ahmed\_jasarevic/jobsdb-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## SEEK Jobs Scraper — JobsDB, JobStreet & Jora | 6 APAC Markets

Extract job listings from every SEEK-owned job board in Southeast Asia — JobsDB Hong Kong & Thailand, Jora Singapore, and JobStreet Indonesia, Malaysia & Philippines — via SEEK's own public JSON search API, with full job descriptions fetched through the SEEK GraphQL API. No browser, no login, no API key: clean, structured job, salary and hiring data at $0.001 per record.

Built for recruiters, staffing agencies, salary-benchmark researchers, job aggregators and labor-market analysts who need repeatable APAC job market data.

### Main Use Cases

- **Salary benchmarking** — aggregate advertised salary ranges by role, market and location for salary guides and compensation reviews (SEEK's own APAC salary reports are compiled from this same data).
- **Hiring & recruitment intelligence** — monitor job-post volumes, hiring demand and work-type trends across HK, TH, SG, ID, MY and PH.
- **Lead generation for recruiters** — build candidate-source lists by keyword, location, work type and posting date.
- **Job market research** — track job openings, classifications and salary disclosure rates across Southeast Asian markets.
- **Job aggregators & job boards** — feed a normalized, structured job feed for six APAC countries from one actor.
- **Talent & workforce analytics** — enrich dashboards and labor-market studies with current, structured job postings on a schedule.

### How the SEEK Jobs Scraper Works — Public JSON API, No Browser

The actor queries the same internal SEEK endpoints that the JobsDB, JobStreet and Jora websites themselves call:

1. **Search** — `GET https://{domain}/api/jobsearch/v5/search` returns clean JSON per page of 20 jobs: title, company, location, salary label, listing date, work types, classifications, teaser and bullet points.
2. **Detail (optional)** — `POST https://{domain}/graphql` with the `jobDetails(id:)` query returns the full description (HTML + plain text), salary label, advertiser and category for each job.

Both endpoints answer plain HTTPS with a realistic User-Agent and are not Cloudflare-walled (the HTML pages are), which keeps runs fast and cheap — no headless browser is used.

### Job Search Input Fields — Configure JobsDB, Jora & JobStreet Runs

| Field | Type | Required | Default | Notes |
| --- | --- | --- | --- | --- |
| `country` | string (select) | No | `hk` | SEEK market: `hk` (hk.jobsdb.com), `th` (th.jobsdb.com), `sg` (sg.jora.com — JobsDB Singapore is now served by Jora), `id` (id.jobstreet.com), `my` (my.jobstreet.com), `ph` (ph.jobstreet.com) |
| `keywords` | string | **Yes** | — | Job title or keyword, e.g. `software engineer`, `accountant`, `data analyst`. The only required field. |
| `location` | string | No | empty | City / region filter, e.g. `Central`, `Bangkok`, `Kowloon`. Empty = whole country. |
| `maxItems` | integer | No | `50` | Maximum jobs to scrape. Hard cap **1000**. |
| `includeDescription` | boolean | No | `true` | Fetch each job's full description via the SEEK GraphQL API (one extra request per job). Set `false` for faster, cheaper listing-only runs. |
| `sortMode` | string (select) | No | `relevance` | `relevance` (KeywordRelevance) or `date` (ListedDate, newest first). |
| `dateRange` | integer | No | `0` | Only jobs posted in the last N days. `0` = any time. Max 365. |
| `salaryMin` | integer | No | — | Minimum salary filter, local currency per month. Not all employers publish a salary. |
| `salaryMax` | integer | No | — | Maximum salary filter, local currency per month. |
| `workType` | string (select) | No | empty | `242` Full time, `243` Part time, `244` Contract / Temp, `245` Casual / Vacation. Empty = any. |
| `proxy` | object | No | `{ "useApifyProxy": false }` | Standard Apify proxy editor. Disabled by default; enable (e.g. a residential group) only if your IP gets blocked — the endpoints are usually reachable directly. |

### Job Listing Output Fields — Salary, Company & Description Data

Every search-API record (and the enriched detail record) contains:

| Field | Type | Description |
| --- | --- | --- |
| `jobId` | string | SEEK job ID |
| `title` | string | Job title |
| `company` | string | Company / advertiser name |
| `location` | string | Location label(s), joined with `\|` |
| `locations` | array | All location labels |
| `salary` | string | Advertised salary label, e.g. `HK$30,000 - HK$40,000 per month` (empty when not disclosed) |
| `postedDate` | string | ISO listing date |
| `postedDateDisplay` | string | Human-readable date, e.g. `4d ago` |
| `workTypes` | array | Work type labels |
| `workType` | string | Work types joined as text |
| `classification` | string | Top-level category |
| `category` | string | Alias of `classification` |
| `classifications` | array | Classification + sub-classification objects |
| `teaser` | string | Short listing summary |
| `bulletPoints` | array | Job highlights from the listing card |
| `isFeatured` | boolean | Featured-listing flag |
| `advertiserId` / `advertiserName` | string / null | Advertiser identity |
| `employerId` | string / null | Employer ID |
| `companyProfileStructuredDataId` | string / null | Company profile ID |
| `applyUrl` | string | Direct apply URL (`https://{domain}/job/{jobId}`) |
| `companyJobsUrl` | string / null | All jobs by this company |
| `country` | string | Market label, e.g. `Hong Kong` |
| `countryCode` | string | Market code, e.g. `hk` |
| `description` | string / null | Full description (HTML) — only when `includeDescription` is true |
| `descriptionText` | string / null | Full description as plain text — only when `includeDescription` is true |

### Example Input — Minimal JSON to Start Scraping

```json
{
  "country": "hk",
  "keywords": "software engineer",
  "location": "Central",
  "maxItems": 100,
  "includeDescription": true,
  "sortMode": "relevance",
  "dateRange": 30,
  "workType": "242"
}
```

### Example Output — One Scraped Job Record

```json
{
  "jobId": "92506170",
  "title": "Senior Software Engineer",
  "company": "Example Limited",
  "location": "Central, Hong Kong",
  "locations": ["Central, Hong Kong"],
  "salary": "HK$45,000 - HK$60,000 per month",
  "postedDate": "2026-09-17T04:33:51.000Z",
  "postedDateDisplay": "2d ago",
  "workTypes": ["Full time"],
  "workType": "Full time",
  "classification": "Information & Communication Technology",
  "category": "Information & Communication Technology",
  "teaser": "Build scalable backend services with Node.js.",
  "bulletPoints": ["5+ years experience", "Hybrid work"],
  "isFeatured": false,
  "applyUrl": "https://hk.jobsdb.com/job/92506170",
  "companyJobsUrl": "https://hk.jobsdb.com/jobs?companyprofilestructureddataid=408641",
  "country": "Hong Kong",
  "countryCode": "hk",
  "description": "<p>Who we are...</p>",
  "descriptionText": "Who we are..."
}
```

### Integrations & Automation — Schedule Job Market Monitoring

- **Apify API** — call the actor from any app with the Apify REST API or the `apify-client` SDK (JavaScript, Python).
- **Schedules** — recommended: run **daily** with `sortMode: "date"` and `dateRange` 1–7 for fresh-listing monitoring; run **weekly** with broad keywords and a high `maxItems` for salary benchmarks and market samples.
- **Webhooks** — push each finished run's data to your own endpoint automatically.
- **Zapier / Make** — trigger downstream workflows when a run finishes or new records land, via Apify's integration apps.
- **Data export** — download results as JSON, CSV, Excel, XML or RSS from the Apify dataset, or read them via API.

### Related Actors

- [LinkedIn Jobs Scraper](https://apify.com/curious_coder/linkedin-jobs-scraper) — the most-used job scraping actor on Apify; complements SEEK coverage with LinkedIn's global job feed.
- [Indeed Jobs Scraper](https://apify.com/valig/indeed-jobs-scraper) — high-volume Indeed coverage for comparing APAC job markets against the SEEK family.
- [JobStreet SEA Scraper — MY, SG, PH & ID](https://apify.com/ahmed_jasarevic/id-jobstreet-scraper) — sibling actor by the same developer, specialized in JobStreet's four Southeast Asian markets.
- [SEEK Job Scraper — Australia & New Zealand](https://apify.com/blackfalcondata/seek-scraper) — the same SEEK v5 API family for the Australian and New Zealand job boards.
- [Indeed Jobs + Company Enrichment Scraper](https://apify.com/memo23/apify-indeed-cheerio-ppr) — Indeed listings with employer emails and company firmographics for recruiter lead pipelines.

### FAQ — JobsDB, JobStreet & SEEK Data Extraction

#### Is there an official JobsDB API?

No. JobsDB (part of the SEEK Group) does not offer a public, self-serve API for job-search data. SEEK provides paid affiliate and partnership routes, but any tool that returns JobsDB search results does so by calling the same public JSON endpoints (`/api/jobsearch/v5/search` and `/graphql`) that the JobsDB website itself uses. This actor uses exactly those endpoints — no reverse engineering, no login.

#### How do I scrape JobsDB job listings?

Enter `keywords` and pick `country` (`hk` or `th`); optionally add `location`, `dateRange`, `workType` or salary filters, then start the run. Results land in the Apify dataset as clean JSON rows: title, company, salary label, location, posted date, category, apply URL and optional full description.

#### How do I scrape jobs in Singapore? JobsDB Singapore is gone — what now?

SEEK closed the Singapore JobsDB site — `sg.jobsdb.com` now redirects to Jora. The actor's `country: "sg"` therefore searches `sg.jora.com`, the successor brand, through the same SEEK v5 API — Singapore job data stays available without changing your pipeline.

#### How do I scrape Hong Kong and Thailand jobs?

Set `country: "hk"` for hk.jobsdb.com or `country: "th"` for th.jobsdb.com. Add `location` values like `Central`, `Kowloon` or `Bangkok`, and use `dateRange` to focus on fresh postings.

#### Can I use this for salary benchmarking?

Yes. Run broad keyword samples per market (e.g. `software engineer`, `accountant`) with `includeDescription: false` and a large `maxItems`, then aggregate the `salary` field. Advertised salary ranges on JobsDB/JobStreet are the same source SEEK uses to compile its own APAC salary reports, and salary-guide providers (e.g. Robert Half, Hays) benchmark from published job-ad data. Note that many employers don't publish a figure, so `salary` is empty on some records.

#### SEEK vs Indeed — which job board should I scrape?

Coverage overlaps, so it depends on the market. SEEK is the regional leader in Hong Kong, Thailand, Singapore, Malaysia, Indonesia and the Philippines (JobsDB, Jora, JobStreet) plus Australia and New Zealand; Indeed is stronger in many other countries (e.g. India, Vietnam, the Americas). For six-market Southeast Asia coverage in one actor, SEEK via this actor is the better fit — combine with an Indeed actor (see Related Actors) if you need cross-check coverage.

#### What are the alternatives to this actor?

Other Apify actors in the SEEK family mostly cover only Hong Kong and Thailand (e.g. `crawlerbros/jobsdb-scraper`, `khadinakbar/jobsdb-jobs-scraper`, `unfenced-group/jobsdb-scraper`) or only JobStreet markets (e.g. `blackfalcondata/jobstreet-scraper`). This is the only one that scrapes all six APAC markets — JobsDB HK, JobsDB TH, Jora SG, JobStreet ID/MY/PH — in a single run with one input schema.

#### Can I run this actor on a schedule?

Yes — every Apify actor can be scheduled from the Console or via the API. Schedules are the recommended way to keep job-market, salary-benchmark and fresh-listing datasets current.

### SEO Keywords

jobsdb scraper, jobsdb api, jobsdb hong kong jobs, jobsdb thailand jobs, scrape jobsdb, jobstreet scraper, jobstreet malaysia, jobstreet indonesia, jobstreet philippines, jobstreet singapore, jora singapore jobs, singapore jobs data, hong kong jobs data, salary benchmarking asia, salary data apac, job market data, job postings dataset, hiring intelligence, recruitment data extraction, labor market research, job board scraper, job aggregator data, seek api alternative, apac job listings, software engineer salary hong kong

### For AI Agents & LLM Apps

Purpose: returns structured SEEK-family job listings (JobsDB HK/TH, Jora SG, JobStreet ID/MY/PH) — one dataset item per job with title, company, salary label, location, posted date, work type, category, apply URL and optional full description.

Minimal working input:

```json
{ "country": "hk", "keywords": "software engineer", "maxItems": 50 }
```

Variant — listing-only, no detail requests (faster, half the per-job requests):

```json
{ "country": "my", "keywords": "accountant", "maxItems": 100, "includeDescription": false }
```

Output field names: `jobId`, `title`, `company`, `location`, `locations`, `salary`, `postedDate`, `postedDateDisplay`, `workTypes`, `workType`, `classification`, `category`, `classifications`, `teaser`, `bulletPoints`, `isFeatured`, `advertiserId`, `advertiserName`, `employerId`, `companyProfileStructuredDataId`, `applyUrl`, `companyJobsUrl`, `country`, `countryCode`, `description`, `descriptionText`.

Behaviors an agent should know:

- `keywords` is the only required field; an empty or missing value fails the run.
- `includeDescription` (default `true`) adds one GraphQL request per job — extra time and load. Set `false` for faster runs when descriptions aren't needed. A failed detail call never drops the listing record.
- `maxItems` has a hard cap of 1000 (soft default 50); values are clamped into `[1, 1000]`.
- `country` is an enum: `hk` | `th` | `sg` | `id` | `my` | `ph`. `sg` hits Jora, `id`/`my`/`ph` hit JobStreet, `hk`/`th` hit JobsDB — different domains behind the same API.
- `workType` is an enum: `""` (any) | `242` full time | `243` part time | `244` contract/temp | `245` casual/vacation.
- Free (non-paying) runs are limited to 10 items regardless of `maxItems`.
- Salary is frequently missing because employers don't publish a figure — `null` salary is normal, not an error.

Billing: pay-per-event — $0.00005 per actor start (one event per GB of memory) plus $0.001 per dataset item (lower on higher Apify plan tiers). A 100-job run with descriptions costs roughly $0.10 plus the start event.

### Legal & Compliance Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by SEEK Limited, JobsDB, JobStreet, Jora or any of their group companies. It accesses only publicly available JSON endpoints that the public job-search pages themselves use; it does not bypass logins, solve CAPTCHAs or access non-public data. Users are responsible for complying with the terms of service of the source sites and with applicable law, including data-protection rules such as the GDPR and the CCPA where relevant. Job postings are public advertisements, but descriptions may contain names or contact details of named individuals — do not use scraped data for unsolicited commercial outreach in violation of applicable law (e.g. CAN-SPAM, GDPR, TCPA). This section is informational, not legal advice.

# Actor input Schema

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

Which JobsDB (SEEK Group) site to search. HK and TH are served by jobsdb.com directly; SG now redirects to Jora, and ID/MY/PH to JobStreet (same SEEK v5 API).

## `keywords` (type: `string`):

Job title or keyword to search for, e.g. "software engineer", "accountant", "data analyst".

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

Optional city / region filter, e.g. "Central", "Bangkok", "Kowloon". Leave empty for the whole country.

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

Maximum number of jobs to scrape (hard cap 1000).

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

Fetch each job's full description via the SEEK GraphQL detail API (one extra request per job). Disable for faster, cheaper listing-only runs.

## `sortMode` (type: `string`):

Result ordering.

## `dateRange` (type: `integer`):

Only scrape jobs posted within the last N days. 0 = any time.

## `salaryMin` (type: `integer`):

Minimum salary filter (local currency per month). Optional.

## `salaryMax` (type: `integer`):

Maximum salary filter (local currency per month). Optional.

## `workType` (type: `string`):

Employment type filter.

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "country": "hk",
  "keywords": "software engineer",
  "location": "Central",
  "maxItems": 50,
  "includeDescription": true,
  "sortMode": "relevance",
  "dateRange": 0,
  "workType": "",
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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": "software engineer",
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/jobsdb-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 = {
    "keywords": "software engineer",
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/jobsdb-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 '{
  "keywords": "software engineer",
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/jobsdb-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/jobsdb-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/XoznAqLBCADQhNa0R/builds/pp9VPscSBWkXqXoiY/openapi.json
