# SEEK Job Scraper: Australia, NZ, JobStreet & JobsDB (`precious_bathmat/seek-job-scraper`) Actor

Scrape jobs from SEEK (Australia, New Zealand), JobStreet (Malaysia, Philippines, Singapore, Indonesia) and JobsDB (Hong Kong, Thailand): title, employer, salary, location, work type, full description. Plus a salary and hiring report per search. No login.

- **URL**: https://apify.com/precious_bathmat/seek-job-scraper.md
- **Developed by:** [Mariam Ahmed](https://apify.com/precious_bathmat) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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?

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 Job Scraper: Australia, NZ, JobStreet & JobsDB

Scrape **jobs from SEEK, JobStreet and JobsDB**, the leading job boards of Australia, New Zealand and Southeast Asia, with no login, and get a **salary and hiring report for every search**:

- **8 countries**: Australia and New Zealand (SEEK), Malaysia, Philippines, Singapore and Indonesia (JobStreet), Hong Kong and Thailand (JobsDB)
- **Every job**: title, employer, location, salary, work type, work arrangement (on-site, hybrid, remote), category, posted date and link
- **Salary parsed** into minimum, maximum and period (hour, day, month, year), in the right currency
- **Full details** (optional): the whole job description, expiry date, verified employer, company size, industry and rating, and the salary from the ad text when the salary field is empty
- **Past the 500-job limit**: big searches are read category by category, up to 20,000 jobs per search
- **Report per search**: salary range and salary by role, top employers, recruitment agency share, categories, locations, work types and arrangements

### What does this SEEK scraper do?

```
SEEK Australia · "registered nurse" · last 14 days · 4,655 jobs on SEEK
 Salary shown in 65% of ads · median A$120,000 a year (A$94,788 to A$161,713)
 Top employer: SA Health - Flinders and Upper North Local Health Network
 Recruitment agencies: 8% of ads

JobStreet Singapore · "data analyst" · last 14 days · 1,924 jobs
 Salary shown in 26% · median S$57,000 a year (S$48,750 to S$68,880)
 Top employers: Abeam Consulting, OCBC, UOB · agencies 18%
```

1. Enter **keywords** (or leave empty for all jobs) and pick **countries**.
2. Optionally set a **location**, **posted within**, **work type** and **work arrangement**, and turn on **full details**.
3. You get **one row per job** in the dataset and **one report per keyword and country**.

```mermaid
flowchart LR
    A[Keywords,<br/>countries, filters] --> B[SEEK · JobStreet<br/>· JobsDB search]
    B -->|over 500 jobs| C[Category by<br/>category]
    B --> D[Jobs<br/>salary parsed]
    C --> D
    D --> E[Full details<br/>description, company]
    D --> F[Report<br/>salaries, employers,<br/>agencies, arrangements]
```

### Who is it for?

- **Recruiters and staffing agencies**: who is hiring for which roles, where, and at what pay; new roles every day
- **Job seekers and career coaches**: real advertised salaries by role and city, and how many roles are remote or hybrid
- **HR and compensation teams**: salary benchmarks from live ads across Australia, New Zealand and Asia
- **Sales teams selling to employers**: companies with open roles, excluding recruitment agencies
- **Researchers and analysts**: labour-market data across eight countries in one format

### What data do you get?

**Jobs** (dataset, one row per job)

| Field | What it tells you |
|---|---|
| `id`, `title`, `url`, `site`, `country` | The job and where it is listed |
| `employer`, `employerId`, `companyName`, `companyProfileUrl`, `isAgency` | Who advertises it, and whether it is a recruitment agency |
| `location`, `category`, `subcategory` | Where and what kind of role |
| `workType`, `workArrangement` | Full time, part time, contract, casual; on-site, hybrid, remote |
| `salary`, `salaryMin`, `salaryMax`, `salaryPeriod`, `currency`, `salarySource` | Pay as advertised, parsed |
| `postedAt`, `postedAgo`, `isFeatured` | When it was posted, and whether it is a paid featured ad |
| `teaser`, `bulletPoints`, `logoUrl` | The ad's summary |
| `description`, `expiresAt`, `employerVerified`, `appliesOnEmployerSite` | With details on |
| `companySize`, `companyIndustry`, `companyRating`, `companyReviews` | With details on, when the employer has a company profile |

**Report** (`REPORTS`, one per keyword and country)

| Field | What it tells you |
|---|---|
| `totalOnSite`, `jobsRead` | How many jobs the site has, and how many were read |
| `salaryShownPercent`, `salary` | Share of ads with a salary; yearly median and range, hourly median |
| `salaryByCategory` | Yearly median pay per sub-category |
| `topEmployers`, `agencySharePercent`, `privateAdvertiserPercent` | Who hires most (agencies left out), and how many ads come from agencies or hide the employer |
| `topCategories`, `topSubcategories`, `topLocations` | What and where |
| `workTypes`, `workArrangements`, `freshness` | Contract mix, remote and hybrid share, how new the ads are |
| `highestPaid`, `topTitleWords` | The best-paid ads and the words in job titles |

### Example: 2 October 2026

Twelve searches (three roles in four countries, last 14 days), 100 jobs each **with full details**: **1,200 jobs in 2 minutes 25 seconds**.

| Search | Jobs on site | Salary shown | Median yearly pay (middle half) |
|---|---|---|---|
| SEEK Australia: data analyst | 2,283 | 33% | A$120,000 (A$97,111 – A$152,512) |
| SEEK Australia: registered nurse | 4,655 | 65% | A$120,000 (A$94,788 – A$161,713) |
| SEEK Australia: electrician | 3,949 | 33% | A$120,000 (A$100,401 – A$167,960) |
| SEEK New Zealand: data analyst | 648 | 21% | NZ$100,000 (NZ$86,732 – NZ$127,000) |
| SEEK New Zealand: registered nurse | 434 | 39% | NZ$97,485 (NZ$84,331 – NZ$118,795) |
| SEEK New Zealand: electrician | 714 | 24% | NZ$87,360 (NZ$80,855 – NZ$118,125) |
| JobStreet Singapore: data analyst | 1,924 | 26% | S$57,000 (S$48,750 – S$68,880) |
| JobStreet Singapore: registered nurse | 384 | 27% | S$51,000 (S$38,925 – S$62,632) |
| JobStreet Singapore: electrician | 2,358 | 35% | S$48,000 (S$36,750 – S$60,000) |

- **Details filled in for 1,187 of the 1,200 jobs** (the rest had just closed), and **34 more salaries** were found in the ad text.
- A run over **all Australian jobs from the last 3 days** (24,167 on SEEK) read **3,000 in 59 seconds**, shared across categories in proportion to their size. Another read 5,000 in 50 seconds.
- **"Software engineer" in Melbourne, remote or hybrid, full time**: 305 jobs, median A$132,500, 93% hybrid.
- On JobStreet Philippines, 12 of 300 data-analyst ads paid in US dollars. They are marked `currency: "USD"` and kept out of the peso figures.

### Pricing

**$0.001 per job**, **$0.001 per job for full details** (when turned on), and **$0.02 per search report**.

- 100 jobs with a report: **$0.12**
- The same with full details: **$0.22**
- 5,000 jobs with a report: **$5.02**

Turn off reports to pay for jobs only.

### Good to know

- **Salary**: about a quarter to two thirds of ads show one. Ranges are parsed into `salaryMin`, `salaryMax` and `salaryPeriod`. When an ad gives no period, Australia and New Zealand are read as yearly (or hourly or daily for small amounts) and Asia as monthly, flagged with `salaryPeriodGuessed`. Text without numbers ("Attractive package") is left out, as are leave days, percentages and "salary packaging" tax benefits.
- **Report salaries** use the midpoint of each range, converted to yearly at each country's usual working week. Ads paying in other currencies are left out of the figures.
- **The 500-job limit**: the site shows at most 500 jobs per query. Bigger searches are read category by category and, where needed, work type by work type. If some still cannot be reached, `RUN_SUMMARY` says how many.
- **Locations must be in the chosen country.** The site would quietly search somewhere else ("Melbourne" on JobStreet Malaysia), so such searches are skipped and listed in `RUN_SUMMARY`.
- **Recruitment agencies** are flagged by name and by ad wording ("our client is..."), and left out of the top employers.
- **No contact details**: emails and phone numbers in ad text are hidden.
- Data comes from the **public job search** of SEEK, JobStreet and JobsDB, which share one platform. Not affiliated with SEEK.

### Input

| Field | Meaning |
|---|---|
| **Keywords** | One search each; empty = all jobs |
| **Countries** | AU, NZ, MY, PH, SG, ID, HK, TH |
| **Location** | City, region or suburb in that country |
| **Posted within** | 24 hours, 3, 7, 14 or 31 days |
| **Work type / Work arrangement** | Full time, part time, contract, casual / on-site, hybrid, remote |
| **Sort** | Newest first or most relevant |
| **Jobs per search** | 1 to 20,000 (default 200) |
| **Add full job details** | Off by default |
| **Reports** | On by default |

### Integrations

Export to JSON, CSV, Excel or Google Sheets, or connect through the Apify API, webhooks, Make, Zapier and n8n. **Schedule it daily** with "Last 24 hours" for a feed of new jobs.

# Actor input Schema

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

Job titles or skills, one search each, e.g. "data analyst", "registered nurse". Empty = all jobs.

## `countries` (type: `array`):

Each keyword is searched in each country.

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

Optional city, region or suburb, e.g. "Sydney", "Auckland", "Kuala Lumpur". Must be in the chosen country.

## `postedWithinDays` (type: `string`):

Only jobs posted in this period.

## `workTypes` (type: `array`):

Optional: only these work types.

## `workArrangements` (type: `array`):

Optional: only these arrangements.

## `sort` (type: `string`):

Order in which jobs are read.

## `maxJobsPerSearch` (type: `integer`):

Most jobs to read per keyword and country (1 to 20,000). The site shows 500 per query; bigger searches are read category by category.

## `includeDetails` (type: `boolean`):

Full description, expiry date, verified employer, company size, industry and rating, and the salary from the ad text when the salary field is empty. One extra charge per job.

## `includeReports` (type: `boolean`):

One report per search: salary range, salary by role, top employers, agency share, categories, locations, work types and arrangements.

## Actor input object example

```json
{
  "keywords": [
    "data analyst"
  ],
  "countries": [
    "AU"
  ],
  "postedWithinDays": "any",
  "sort": "date",
  "maxJobsPerSearch": 200,
  "includeDetails": false,
  "includeReports": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

One row per job: title, employer, location, salary (parsed), work type and arrangement, category, posted date, link; with details the full description and company profile.

## `reports` (type: `string`):

Per search: salary range and by role, top employers, agency share, categories, locations, work types, arrangements, freshness.

## `reportsCsv` (type: `string`):

One flat row per search.

## `summary` (type: `string`):

Requests, problems and the limits of the data.

# 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": [
        "data analyst"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("precious_bathmat/seek-job-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": ["data analyst"] }

# Run the Actor and wait for it to finish
run = client.actor("precious_bathmat/seek-job-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": [
    "data analyst"
  ]
}' |
apify call precious_bathmat/seek-job-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,precious_bathmat/seek-job-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/Z2CUXYgeOhlnvunPh/builds/Npfby0qqUSazvDPMb/openapi.json
