# SEEK & JobStreet Jobs Scraper | Fast & Reliable | $0.80/1K (`codetr/seek-jobstreet-jobsdb-jobs-scraper`) Actor

Scrape job listings from SEEK, JobStreet and JobsDB in 8 countries (AU, NZ, MY, SG, ID, PH, HK, TH) with one Actor. Parsed salaries, full descriptions and incremental monitoring included, no proxy needed.

- **URL**: https://apify.com/codetr/seek-jobstreet-jobsdb-jobs-scraper.md
- **Developed by:** [Yusuf Barış](https://apify.com/codetr) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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.

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

### What does SEEK & JobStreet Jobs Scraper do?

**SEEK & JobStreet Jobs Scraper** is a fast **SEEK API alternative** that extracts job listings from every site on the SEEK platform — [SEEK](https://www.seek.com.au) (Australia, New Zealand), [JobStreet](https://www.jobstreet.com) (Malaysia, Singapore, Indonesia, Philippines) and [JobsDB](https://www.jobsdb.com) (Hong Kong, Thailand) — with **one Actor, one input and one flat price**.

**No login and no proxy needed**, so runs are quick and cheap. Salaries are parsed into numbers, full job descriptions are optional and free, and an **incremental mode** lets you monitor a search and receive only new jobs.

### Supported sites

| Code | Site | Country | Currency |
| --- | --- | --- | --- |
| `AU` | seek.com.au | Australia | AUD |
| `NZ` | seek.co.nz | New Zealand | NZD |
| `MY` | my.jobstreet.com | Malaysia | MYR |
| `SG` | sg.jobstreet.com | Singapore | SGD |
| `ID` | id.jobstreet.com | Indonesia | IDR |
| `PH` | ph.jobstreet.com | Philippines | PHP |
| `HK` | hk.jobsdb.com | Hong Kong | HKD |
| `TH` | th.jobsdb.com | Thailand | THB |

### Why use this scraper?

- **8 countries, 1 Actor** – switch the `site` field, or mix sites in one run by pasting start URLs from different domains.
- **Salary and description included** – `salaryMin` / `salaryMax` / `currency` / `salaryPeriod` are parsed for you and full descriptions cost nothing extra. No add-ons, no start fee.
- **Incremental monitoring** – turn on `onlyNew` and schedule the Actor to get only the listings you have not seen before.
- **Real filters** – keywords, location, listing date, work type, work arrangement (on-site / hybrid / remote), industry and salary range.
- **Large result sets** – ask for hundreds or thousands of jobs per keyword; duplicates are removed automatically.
- **Reliable** – built-in retries, so runs finish cleanly even when a site is busy.
- **Apify platform extras** – schedules, API access, webhooks, integrations (Make, Zapier, Google Sheets, Slack…) and dataset export to JSON, CSV, Excel, XML or HTML.

Typical use cases: recruitment and talent-market research, salary benchmarking, competitor hiring signals, lead generation for staffing agencies, job aggregators and alerting, labour-market dashboards.

### What data can you extract?

| Field | Type | Description |
| --- | --- | --- |
| `id`, `jobUrl` | string | Job id and link to the ad |
| `title`, `teaser`, `bulletPoints` | string / array | Title, short summary and the highlights shown in search |
| `companyName`, `advertiserId`, `advertiserName`, `employerId`, `employerName`, `companyUrl` | string | Advertiser / employer details |
| `classification`, `subclassification`, `classifications` | string / array | Industry and sub-industry |
| `location`, `locations`, `countryCode` | string / array | Where the job is |
| `listingDate` | string (ISO) | When the ad was listed |
| `salaryLabel` | string | Salary text exactly as shown |
| `salaryMin`, `salaryMax`, `currency`, `salaryPeriod` | number / string | Parsed salary (`hour`, `day`, `week`, `month` or `year`) |
| `workTypes`, `workArrangements`, `isRemote` | array / boolean | Full time / part time / contract / casual; on-site / hybrid / remote |
| `isFeatured`, `displayType`, `logoUrl`, `roleId` | mixed | Ad presentation details |
| `description`, `descriptionHtml`, `expiresAt` | string | Full ad text, HTML and closing date (when `includeDescription` is on) |
| `site`, `query`, `queryWhere`, `scrapedAt` | string | Which site and search produced the row, and when |

### How to scrape SEEK, JobStreet and JobsDB

1. Open the Actor and choose the **Site / country**.
2. Add one or more **Keywords** (each keyword is a separate search) and optionally a **Location**. Alternatively paste **Start URLs** — search pages or single job pages from any supported site.
3. Set **Max results** (default 100) and any filters you need.
4. Tick **Include full description** if you want the complete ad text.
5. Click **Start**, then download the dataset as JSON, CSV or Excel — or fetch it through the API.

### How much does it cost to scrape SEEK, JobStreet and JobsDB?

**$0.80 per 1,000 results** ($0.0008 per job) — pay only for jobs that are saved to the dataset.

- No start fee.
- Descriptions and parsed salaries are **included**, not billed separately.
- Runs are lightweight, so platform usage per run is minimal.

That is **2–3x cheaper than the most popular SEEK scrapers**, most of which charge $2–$2.70 per 1,000 jobs once descriptions and salary data are added, plus start fees.

| | This Actor | Typical alternatives |
| --- | --- | --- |
| Price per 1,000 jobs | **$0.80** | $2.00 – $2.70 |
| Description | included | sometimes billed extra |
| Salary parsing | included | sometimes billed extra |
| Start fee | none | $0.01 – $0.08 |
| Countries | 8 in one Actor | usually one Actor per site |

Use **Max results** to cap your spend: 100 jobs cost $0.08.

### Input

See the **Input** tab for every option. The ones worth knowing:

| Field | Notes |
| --- | --- |
| `site` | `AU`, `NZ`, `MY`, `SG`, `ID`, `PH`, `HK` or `TH` – default `AU`. |
| `keywords` | List of search terms, one search each. Empty = no keyword. |
| `where` | Location as typed on the site, e.g. `All Sydney NSW`, `Kuala Lumpur`. |
| `startUrls` | Search URLs (`…/software-engineer-jobs/in-All-Sydney-NSW?daterange=7`) or job URLs (`…/job/12345678`). The site is taken from the URL's domain. Filters in the URL win over the form. |
| `maxItems` / `maxItemsPerQuery` | Total cap, and an optional cap per keyword / URL so one search cannot use the whole budget. |
| `sortBy`, `dateRange` | Newest first; last 1 / 3 / 7 / 14 / 31 days. |
| `workType`, `workArrangement`, `classification` | Full time, part time, contract, casual; on-site, hybrid, remote; 30 industries. |
| `salaryMin`, `salaryMax`, `salaryType` | Range per year, month or hour (default: annual for AU/NZ, monthly elsewhere). |
| `includeDescription` | Adds `description`, `descriptionHtml`, `expiresAt`. No extra charge. |
| `onlyNew`, `seenStoreName` | Incremental mode, see below. |

#### Example input

```json
{
    "site": "AU",
    "keywords": ["data engineer", "analytics engineer"],
    "where": "All Sydney NSW",
    "maxItems": 100,
    "sortBy": "date",
    "dateRange": "7",
    "workArrangement": ["hybrid", "remote"],
    "salaryMin": 120000,
    "includeDescription": true
}
```

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Example (shortened):

```json
{
    "id": "95122888",
    "jobUrl": "https://my.jobstreet.com/job/95122888",
    "title": "General manager",
    "companyName": "Example Sdn Bhd",
    "classification": "CEO & General Management",
    "location": "Kuala Lumpur City Centre, Kuala Lumpur",
    "countryCode": "MY",
    "listingDate": "2026-10-11T02:14:09Z",
    "salaryLabel": "RM 15,000 per month",
    "salaryMin": 15000,
    "salaryMax": 15000,
    "currency": "MYR",
    "salaryPeriod": "month",
    "workTypes": ["Full time"],
    "workArrangements": ["On-site"],
    "isRemote": false,
    "description": "Responsibilities:\n\n• Lead the regional business …",
    "expiresAt": "2026-11-10T15:59:59.999Z",
    "site": "MY",
    "query": "manager",
    "queryWhere": "Kuala Lumpur",
    "scrapedAt": "2026-10-11T14:53:52.048Z"
}
```

### Monitor new jobs on a schedule

Switch on **Only new jobs** and create a [schedule](https://docs.apify.com/platform/schedules) (for example every 6 hours). The first run returns up to `maxItems` jobs and remembers their ids; every following run returns only listings it has not delivered before.

```json
{
    "site": "SG",
    "keywords": ["product manager"],
    "sortBy": "date",
    "dateRange": "3",
    "maxItems": 100,
    "onlyNew": true,
    "seenStoreName": "sg-product-manager-monitor"
}
```

- Give each monitor its own `seenStoreName` so they do not share history.
- Jobs are remembered per site and forgotten after 90 days without appearing in results.
- Connect the dataset to a [webhook or integration](https://docs.apify.com/platform/integrations) to get a Slack message, email or Google Sheets row for each new batch.

### Tips

- **Date-sort monitors.** For alerting, combine `onlyNew` with `sortBy: date` and a short `dateRange` – runs stay tiny and cheap.
- **Salary filtering.** Many ads show no salary. A salary range removes ads whose stated salary clearly lies outside it, but keeps ads without a stated salary, since they may match.
- **Large pulls.** For very large result sets, prefer several focused keywords or locations over one huge search.
- **Speed.** Leave `includeDescription` off if you only need the listing data – runs finish faster.

### FAQ

#### Do I need a proxy?

No. The Actor works out of the box. You can optionally choose an Apify Proxy in the input.

#### Can I scrape several countries in one run?

Yes: paste start URLs from different domains (for example one SEEK AU and one JobsDB HK search). Each URL is routed to its own site.

#### Why is `salaryMin` empty for some jobs?

Most advertisers do not publish a salary. When the label has no parseable amount (for example "Competitive package"), the numeric fields are `null`; `salaryLabel` is still returned when present. If the label gives an amount but no unit and the number is ambiguous (for example `$850 + super`), `salaryPeriod` is `null`.

#### What is `isRemote`?

`true` when the ad's work arrangement is Remote. Hybrid ads are `false`; see `workArrangements`.

#### Is it legal to scrape SEEK, JobStreet and JobsDB?

Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers. Review the target sites' terms of use for your use case. This Actor is not affiliated with SEEK, JobStreet or JobsDB.

#### Something is wrong or missing

Open an issue in the **Issues** tab and include the run link. Programmatic access is described in the **API** tab.

# Actor input Schema

## `site` (type: `string`):

Which job board to search. SEEK runs Australia and New Zealand; JobStreet runs Malaysia, Singapore, Indonesia and the Philippines; JobsDB runs Hong Kong and Thailand. Start URLs from other sites override this.

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

One search is run per keyword (e.g. "software engineer", "nurse"). Leave empty to search without a keyword.

## `where` (type: `string`):

Suburb, city or region as you would type it on the site (e.g. "Sydney NSW", "All Melbourne VIC", "Kuala Lumpur"). Empty = whole country.

## `startUrls` (type: `array`):

Optional. Search pages (e.g. https://www.seek.com.au/software-engineer-jobs/in-All-Sydney-NSW?daterange=7) or single job pages (https://www.seek.com.au/job/12345678) from any supported site.

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

Maximum number of jobs to save in total. You are only charged for saved results.

## `maxItemsPerQuery` (type: `integer`):

Optional cap for each keyword or start URL so one search cannot use up the whole budget. 0 = no per-search cap.

## `sortBy` (type: `string`):

Relevance is the site default. Date puts the newest listings first (promoted ads may still appear at the top).

## `dateRange` (type: `string`):

Only jobs listed within this time window.

## `workType` (type: `array`):

Leave empty for all work types.

## `workArrangement` (type: `array`):

On-site, hybrid or remote. Leave empty for all.

## `classification` (type: `array`):

Restrict to one or more industries. The ids are the same on all sites. Leave empty for all.

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

In the currency of the site, per the period selected below. Ads without a stated salary may still be returned because the site's own salary filter is loose; ads whose parsed salary lies outside the range are removed.

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

See minimum salary.

## `salaryType` (type: `string`):

Period that Minimum/Maximum salary refer to. Default: annual for AU/NZ, monthly for all other sites.

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

Adds description (plain text), descriptionHtml and expiresAt to every job. No extra charge, but runs take longer.

## `onlyNew` (type: `boolean`):

Skip jobs that were returned by a previous run that used the same store name. Schedule the Actor with this switched on to receive only fresh listings.

## `seenStoreName` (type: `string`):

Name of the key-value store that remembers seen job ids. Use different names for independent monitors.

## `autoSplit` (type: `boolean`):

Automatically collect very large result sets (more than a few hundred jobs per search) in several passes and remove duplicates.

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

Parallel requests. 3 is a safe default.

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

Not needed for normal use. Select Apify Proxy here only if you want to force one.

## `escalateProxy` (type: `boolean`):

If the site starts refusing requests, retry through Apify Proxy. Proxy usage is billed by Apify. Ignored when you pick a proxy above.

## Actor input object example

```json
{
  "site": "AU",
  "keywords": [
    "software engineer"
  ],
  "maxItems": 100,
  "maxItemsPerQuery": 0,
  "sortBy": "relevance",
  "dateRange": "any",
  "includeDescription": false,
  "onlyNew": false,
  "seenStoreName": "seek-jobs-seen",
  "autoSplit": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "escalateProxy": true
}
```

# Actor output Schema

## `jobs` (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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("codetr/seek-jobstreet-jobsdb-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 = { "keywords": ["software engineer"] }

# Run the Actor and wait for it to finish
run = client.actor("codetr/seek-jobstreet-jobsdb-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 '{
  "keywords": [
    "software engineer"
  ]
}' |
apify call codetr/seek-jobstreet-jobsdb-jobs-scraper --silent --output-dataset

```

## MCP server setup

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