# Hiredly Jobs Scraper (Malaysia & Singapore) (`maxqim/hiredly-jobs-scraper`) Actor

Scrape job listings from Hiredly.com in Malaysia and Singapore: title, company, industry, company size, salary range (MYR/SGD), state, job type, skills, experience and full description. Fast API-based, no login. Pay per result.

- **URL**: https://apify.com/maxqim/hiredly-jobs-scraper.md
- **Developed by:** [miao qi](https://apify.com/maxqim) (community)
- **Categories:** Jobs
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 job listings

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

## Hiredly Jobs Scraper (Malaysia & Singapore)

Scrape job listings from **Hiredly** (hiredly.com, formerly WOBB), one of Malaysia's largest job platforms for young professionals, also live in Singapore. Get clean, structured data with **salary ranges in MYR / SGD, company industry and size, state, job type, career level, skills and full job description**.

- Malaysia (my.hiredly.com) and Singapore (sg.hiredly.com)
- No login, no browser: uses the same public JSON data the Hiredly website loads, 100 jobs per request
- About 250 jobs with full descriptions in ~10 seconds
- Pay only for the jobs you get

### What data do you get?

| Field | Example |
| --- | --- |
| `title`, `url`, `jobId` | "Senior Accountant", link to the job page |
| `companyName`, `companyUrl` | "LB ALUMINIUM BERHAD" |
| `companyIndustry`, `companySize` | "Manufacturing", "501-1000" |
| `companyVerified`, `companyIsRecruitmentAgency`, `companyOpenJobs` | hiring signals for lead generation |
| `jobType` | Full-Time, Part-Time, Internship, Contract, Freelance |
| `stateRegion`, `location` | "Selangor", street / area |
| `salaryText`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | "5000 - 6500" → 5000 / 6500 MYR per month |
| `careerLevel`, `minYearsExperience`, `maxYearsExperience` | "Senior Executive", 4, 7 |
| `skills`, `specialisations` | \["PHP Development", "Laravel"], \["Software Development & QA / Testing"] |
| `postedAt` | last posted / refreshed time |
| `descriptionText`, `requirementsText`, `aiSummary` | full text (optional) |
| `isAggregated`, `externalApplyUrl` | jobs Hiredly collects from company career sites |

### Use cases

- **Salary benchmarking in Malaysia and Singapore**: real advertised ranges by role, state, industry and seniority
- **Lead generation for recruiters, HR tech and B2B sales**: companies that are hiring right now, with industry, size and number of open jobs
- **Job aggregators and alert bots** for MY / SG
- **Labor market research**: demand for skills (e.g. Excel, Python, Mandarin) across industries
- **AI agents / RAG**: structured job data with full descriptions

### How to use

1. Enter **keywords** (job title, skill or company) or leave empty for all jobs.
2. Choose **countries** (Malaysia, Singapore or both) and, optionally, states, job types and minimum salary.
3. Set **Max jobs** and click Start. Export to JSON, CSV, Excel or use the API.

#### Input example

```json
{
  "keywords": "data analyst",
  "countries": ["MY", "SG"],
  "stateRegions": ["Kuala Lumpur", "Selangor"],
  "jobTypes": ["full-time"],
  "minMonthlySalary": 4000,
  "includeAggregatedJobs": true,
  "includeDescription": true,
  "maxItems": 500
}
```

#### Output example

```json
{
  "jobId": "b14bb073-8740-4348-ad4d-3bf01c6c2d09",
  "title": "Internship Accounts Payable/Accounts Receivable Accountant",
  "url": "https://my.hiredly.com/jobs/jobs-malaysia-lb-aluminium-berhad-job-internship-accounts-payable-accounts-receivable-accountant",
  "country": "MY",
  "companyName": "LB ALUMINIUM BERHAD",
  "companyUrl": "https://my.hiredly.com/companies/lb-aluminium-berhad",
  "companyIndustry": "Manufacturing",
  "companySize": "501-1000",
  "companyVerified": false,
  "companyIsRecruitmentAgency": false,
  "companyOpenJobs": 7,
  "jobType": "Internship",
  "stateRegion": "Selangor",
  "location": "Lot 11, Jalan Perusahaan 1,Kawasan Perusahaan Beranang,, Semenyih",
  "salaryText": "800",
  "salaryMin": 800,
  "salaryMax": 800,
  "salaryCurrency": "MYR",
  "salaryPeriod": "month",
  "careerLevel": "Internship",
  "minYearsExperience": 0,
  "maxYearsExperience": 0,
  "skills": ["Microsoft Excel"],
  "specialisations": ["General / Cost Accounting"],
  "postedAt": "2026-10-26T14:31:38+08:00",
  "isAggregated": false,
  "externalApplyUrl": null,
  "descriptionText": "LB Aluminium Berhad will allow you opportunities to gain valuable hands-on exposure ...",
  "requirementsText": "Experience & Personal Skills: ...",
  "aiSummary": "• Work hands-on in accounts payable and receivable ...",
  "scrapedAt": "2026-10-28T05:11:32+00:00"
}
```

More real records in `sample_output.json`.

### Pricing

Pay per result: **$1.50 per 1,000 jobs** (event `job`), full descriptions included. Set **Max jobs** or a maximum cost per run and the Actor stops exactly there.

### FAQ

**Why does a keyword search return more jobs than I expected?** Hiredly's own search is broad (it also matches related titles and skills), and results come sorted by relevance. The Actor returns exactly what the website returns. Use `maxItems` to keep the most relevant ones.

**What does "aggregated" mean?** Besides jobs posted directly on Hiredly, the site shows jobs it collects from company career pages (those have an `externalApplyUrl`). Set **Include aggregated jobs** to false to keep only direct postings.

**Is salary monthly?** Yes, Hiredly shows monthly salary in local currency. `Undisclosed` salaries have empty `salaryMin`/`salaryMax`.

**Does it collect personal data?** No. Only job advertisements and public company information. No recruiter names, emails or phone numbers.

**Is it legal?** The Actor reads publicly available job listings at a polite rate without logging in. You are responsible for how you use the data; check Hiredly's terms for your use case.

# Actor input Schema

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

Job title, skill or company, e.g. "data analyst", "accountant", "Shopee". Leave empty for all jobs.

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

Hiredly Malaysia (my.hiredly.com) and/or Hiredly Singapore (sg.hiredly.com).

## `stateRegions` (type: `array`):

Malaysia: Kuala Lumpur, Selangor, Penang, Johor, Perak, Sabah, Sarawak, Melaka... Singapore: North, South, East, West, Central.

## `jobTypes` (type: `array`):

Leave empty for all.

## `minMonthlySalary` (type: `integer`):

Keep only jobs whose advertised monthly salary range reaches this amount, in local currency (MYR or SGD). Jobs with undisclosed salary are skipped when this is set.

## `postedWithinDays` (type: `integer`):

Keep only jobs posted or refreshed in the last N days (0 = no filter).

## `includeAggregatedJobs` (type: `boolean`):

Hiredly also shows jobs it collects from company career sites. Turn off to keep only jobs posted directly on Hiredly.

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

Adds description, requirements and Hiredly's short AI summary.

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

Stop after this many jobs in total (0 = no limit). You pay per job saved.

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

Usually not needed.

## Actor input object example

```json
{
  "keywords": "data analyst",
  "countries": [
    "MY"
  ],
  "postedWithinDays": 0,
  "includeAggregatedJobs": true,
  "includeDescription": true,
  "maxItems": 200,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped job listings, one item per job.

# 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("maxqim/hiredly-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": "data analyst" }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maxqim/hiredly-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/5WRSpis8PAHOUxpch/builds/s3tg8MtZkdvaH7I9Y/openapi.json
