# JobStreet Scraper - Jobs, Salaries & Employers (`goat255/jobstreet-scraper`) Actor

Search job listings across Singapore, Malaysia, Philippines and Indonesia. One clean row per job with title, employer, salary range, location, work type and listing date. Filter by pay, work type or city.

- **URL**: https://apify.com/goat255/jobstreet-scraper.md
- **Developed by:** [Goutam Soni](https://apify.com/goat255) (community)
- **Categories:** Automation, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 job scrapeds

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/platform/actors/running/actors-in-store#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

## JobStreet Scraper

Search job listings across Singapore, Malaysia, the Philippines and Indonesia. One clean row per job with employer, pay, location and listing date. No login and no API key.

### What it does

- **Pay parsed into numbers** - the stated pay range is turned into `salaryMin`, `salaryMax` and a period, so you can sort and filter instead of reading text. Listings that do not state pay return `null` rather than a guess.
- **Four countries** in one actor, all returning the same fields.
- **Employer details** - company name and logo, plus the job category and sub category.
- **Filters** for minimum pay, work type, city or region.
- **Sort** by relevance, newest first or highest pay.
- **Listing date** on every row, so you can measure how fast a market moves.

Listings turn over daily, so schedule the run to build a hiring dataset over time.

Common uses: salary benchmarking, hiring and market research, recruitment lead lists, tracking which employers are growing, and building a jobs dataset.

### Input

| Field | Type | Description |
|---|---|---|
| `searchTerms` | array | Job titles, skills or keywords. One search per entry. |
| `country` | string | `sg`, `my`, `ph` or `id`. |
| `location` | string | Optional city or region to narrow the search. |
| `sort` | string | `relevance`, `date` or `salary`. |
| `workType` | string | `any`, `full_time`, `part_time`, `contract`, `casual`. |
| `minSalary` | integer | Only listings that state pay of at least this amount. |
| `maxResultsPerTerm` | integer | Cap per term. Default 100, up to 5000. |
| `proxyConfiguration` | object | Optional. Enable to spread requests across IPs. |

#### Example input

```json
{
  "searchTerms": ["data analyst", "software engineer"],
  "country": "sg",
  "sort": "date",
  "workType": "full_time",
  "minSalary": 4000,
  "maxResultsPerTerm": 300
}
```

### Output

Each item is one job listing.

```json
{
  "id": "90000001",
  "title": "Data Analyst",
  "teaser": "A short summary of the role as shown in the listing.",
  "company": "Acme Co",
  "advertiserId": "60000001",
  "companyLogo": "https://example.com/logo.png",
  "salaryLabel": "$5,000 - $7,000 per month",
  "salaryMin": 5000.0,
  "salaryMax": 7000.0,
  "salaryPeriod": "month",
  "currency": null,
  "location": "Central Region",
  "locations": ["Central Region"],
  "country": "sg",
  "workTypes": ["Full time"],
  "workArrangement": null,
  "categories": ["Information & Communication Technology", "Business/Systems Analysts"],
  "highlights": ["Hybrid working", "Career development"],
  "listedAt": "2026-07-18T07:28:21.000Z",
  "listedAgo": "14h ago",
  "isFeatured": false,
  "url": "https://sg.jobstreet.com/job/90000001",
  "searchTerm": "data analyst"
}
```

### Notes

- No login and no API key. Enter your search terms and run.
- Many employers do not publish pay. Those rows keep every other field and return `null` for the pay numbers.
- Pay written in short form, such as `$5k - $7k p.m.`, is read correctly as 5000 to 7000 per month.
- Allowances and bonuses listed after the pay range are not counted as part of it.
- Results are deduplicated across all your search terms, so a job matching two terms is delivered once and charged once.
- A pay range counts as a match when the top of the range reaches your `minSalary`, so a role paying 50,000 to 65,000 is returned for a 60,000 filter.

### Privacy

To improve our actors we collect anonymized usage telemetry (run stats and input patterns). No personal account data is collected.

# Actor input Schema

## `searchTerms` (type: `array`):

Job titles, skills or keywords. One search per entry.

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

Which country site to search.

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

Optional city or region to narrow the search, for example Central Region.

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

How to order results.

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

Filter by employment type.

## `minSalary` (type: `integer`):

Only return listings that state pay reaching at least this amount. A range counts when its top reaches the figure. Listings that do not state pay are left out when this is set.

## `maxResultsPerTerm` (type: `integer`):

Cap per term. Default 100, up to 5000.

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

Optional. Enable to spread requests across IP addresses.

## Actor input object example

```json
{
  "searchTerms": [
    "data analyst",
    "software engineer"
  ],
  "country": "sg",
  "sort": "relevance",
  "workType": "any",
  "maxResultsPerTerm": 100
}
```

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

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

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

```

## MCP server setup

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