# Jobstreet & JobsDB Scraper — SEA & Hong Kong Jobs | $0.9/1k (`glasswing/jobstreet-scraper`) Actor

Scrape Jobstreet (Malaysia, Singapore, Philippines, Indonesia) and JobsDB (Hong Kong, Thailand) jobs by keyword, city, category or URL: company, salary parsed to min/max/currency, work type, remote, posting date and full description. CSV, JSON, Excel.

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

## Pricing

from $0.90 / 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 Jobstreet & JobsDB Scraper do?

Jobstreet & JobsDB Scraper extracts **job ads from Jobstreet and JobsDB**, the largest job boards in Southeast Asia and Hong Kong, and delivers them as clean JSON, CSV or Excel. One run covers six country sites: **Jobstreet Malaysia, Singapore, the Philippines and Indonesia**, and **JobsDB Hong Kong and Thailand**. Type keywords such as `software engineer` or `accountant` and cities such as `Kuala Lumpur`, `Makati City` or `Kowloon`, or paste search and job URLs from your browser, and get one row per job: title, company, location, salary (the displayed text plus parsed minimum, maximum, currency and period), work type, remote/hybrid/on-site, job category, posting and closing dates, and the full job description.

It works as a **Jobstreet API and JobsDB API alternative**: no account, no login, no browser and no residential proxy. It reads the same public, logged-out job search the sites show to every visitor.

### Use cases for this Jobstreet and JobsDB scraper

- **Recruiting and staffing agencies:** see which companies are hiring for the roles you place in Malaysia, Singapore, the Philippines, Indonesia, Hong Kong or Thailand, with company names, industries, sizes and websites for lead lists.
- **Salary benchmarking across Asia:** collect advertised salary ranges per role and city, already split into `salaryMin`, `salaryMax`, `salaryCurrency` (MYR, SGD, PHP, IDR, HKD, THB, USD) and `salaryPeriod`.
- **Labour-market research and job boards:** track postings per category, city, work type or remote option, or feed fresh listings into your own product.
- **AI agents and automations:** a daily scheduled run with `postedWithinDays: 1` and `sortBy: "date"` gives a clean "new today" feed per country.

### What data you get from every Jobstreet / JobsDB job ad

| Field | Type | Description |
|---|---|---|
| `jobId` | string | The job's numeric id (the number in `/job/<id>`) |
| `url` | string | Public job page on the site that found it |
| `title` | string | Job title as published by the employer |
| `companyName` | string | Hiring company. Left out on ads posted as "Private Advertiser" (the placeholder is never returned as a name) |
| `companyProfileUrl` | string | The company's profile page on the site, when it has one |
| `companyIndustry`, `companySize`, `companyWebsite` | string | From the company profile (with full descriptions on) |
| `logo` | string | Advertiser logo image URL |
| `location` | string | Location as the site shows it, e.g. "Mid Valley City, Kuala Lumpur" |
| `suburb`, `region` | string | Parts of the location (district or suburb, then state or region) |
| `country` | string | Country of the job, e.g. "Malaysia" |
| `countryCode` | string | ISO code of the job's country: `MY`, `SG`, `PH`, `ID`, `HK`, `TH`, ... |
| `workType` | string | Full time, Part time, Contract/Temp or Casual/Vacation |
| `workArrangement` | string | On-site, Hybrid or Remote |
| `isRemote` | boolean | True when the ad is marked Remote |
| `salary` | string | Salary exactly as displayed, e.g. "RM 3,000 – RM 4,500 per month" |
| `salaryMin`, `salaryMax` | number | Parsed salary range (Indonesian "5.500.000" style and "315k" style amounts included) |
| `salaryCurrency` | string | ISO code: `MYR`, `SGD`, `PHP`, `IDR`, `HKD`, `THB`, `USD`, ... |
| `salaryPeriod` | string | `hour`, `day`, `week`, `month` or `year` |
| `classification` | string | Job category, e.g. "Information & Communication Technology" |
| `subClassification` | string | Sub-category, e.g. "Developers/Programmers" |
| `postedAt` | string | ISO 8601 time the ad was listed |
| `expiresAt` | string | ISO 8601 time the ad closes (with full descriptions on) |
| `listingStatus` | string | Active or Expired (with full descriptions on) |
| `isLinkOut` | boolean | True when applying happens on the employer's own site |
| `teaser` | string | The short summary shown in search results |
| `bulletPoints` | array | Up to three selling points the advertiser highlighted |
| `tags` | array | Badges such as "Urgently hiring" or "Be an early applicant" |
| `isFeatured` | boolean | True for featured (promoted) ads |
| `descriptionText` | string | Full job description as plain text; e-mail addresses and phone numbers are removed |
| `site` | string | `jobstreet` or `jobsdb` |
| `siteDomain` | string | The site the row came from, e.g. `my.jobstreet.com`, `hk.jobsdb.com` |
| `searchKeyword`, `searchLocation` | string | The search that found the job |
| `detailError` | string | Only when the full description could not be added; the row still has the search-result data |
| `status` | string | `ok`, `not_found` or `error` (see below) |
| `error` | string | Reason when `status` is not `ok` |
| `scrapedAt` | string | ISO 8601 time of extraction |

Optional fields are left out when the ad does not publish them; for example about half of all ads hide the salary. Labels are in English; the job texts stay in the language the employer wrote them in (English, Bahasa, Thai, Chinese).

#### Result status (tri-state output)

| `status` | Meaning | Billed? |
|---|---|---|
| `ok` | The job was found and extracted. | Yes |
| `not_found` | The site answered, but the search has no jobs, or the pasted job no longer exists. The row names the search or job. | No |
| `error` | The site could not be read after retries. `error` says why. | No |

A run that finds nothing still ends successfully with its free `not_found` rows, so a scheduled search that is empty today does not show up as a failed run.

### How to scrape Jobstreet and JobsDB jobs

1. Open the Actor in Apify Console and click **Try for free**.
2. Choose the **Country sites** (Malaysia, Singapore, the Philippines and Hong Kong are preselected; Indonesia and Thailand are one click away).
3. Type **Keywords** and, optionally, **Locations**; or paste search and job URLs from the sites into **Search or job URLs**.
4. Optionally narrow the search: work type, work arrangement or remote only, job category, posted within, salary range, sort order.
5. Set **Maximum results** (start with the default 20) and click **Start**. The default run takes under 10 seconds.
6. Open the **Output** tab or **Export** the dataset as JSON, CSV, Excel, XML or HTML.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | four example searches | Search or job URLs from any of the six sites (path style `/software-engineer-jobs/in-Kuala-Lumpur`, `?keywords=` style, category pages `/jobs-in-...`), or bare job ids |
| `countries` | array | `MY`, `SG`, `PH`, `HK` | Country sites for keyword searches: `MY`, `SG`, `PH`, `ID` (Jobstreet), `HK`, `TH` (JobsDB) |
| `keywords` | array | - | Search terms; each is searched on every selected site |
| `locations` | array | - | Cities, states or districts, e.g. `Kuala Lumpur`, `Penang`, `Makati City`, `Kowloon`, `Bangkok` |
| `workTypes` | array | - | `fullTime`, `partTime`, `contract`, `casual` |
| `workArrangements` | array | - | `onsite`, `hybrid`, `remote` |
| `remoteOnly` | boolean | `false` | Shortcut for remote jobs only |
| `classifications` | array | - | The sites' 30 job categories, e.g. `Information & Communication Technology`, `Accounting`, `Sales` |
| `postedWithinDays` | integer | - | Only jobs listed in the last N days |
| `salaryMin`, `salaryMax` | integer | - | The sites' salary filter, in each site's local currency |
| `salaryPeriod` | string | `month` | What the salary filter means: `month`, `year` or `hour` |
| `sortBy` | string | `relevance` | `relevance` or `date` (newest first) |
| `fetchDetails` | boolean | `true` | Add the full description, closing date and company profile (one extra request per job) |
| `maxItems` | integer | `20` | Stop after this many rows in total |
| `maxItemsPerSearch` | integer | - | Cap per search (site x keyword x location, or per pasted URL) |
| `proxyConfiguration` | object | off | Not needed; datacenter proxy only if you ever see blocking |

Filters apply to keyword searches and fill in whatever a pasted search URL does not already set. The four example URLs are skipped automatically as soon as you set keywords, locations, other country sites or any filter. With no keywords, locations or URLs of your own, the Actor lists the newest jobs of each selected site.

Example input:

```json
{
    "countries": ["MY", "SG", "ID"],
    "keywords": ["data analyst", "accountant"],
    "locations": ["Kuala Lumpur", "Singapore", "Jakarta Raya"],
    "workTypes": ["fullTime"],
    "postedWithinDays": 7,
    "maxItems": 500,
    "maxItemsPerSearch": 100
}
```

### Output

You can download the dataset in various formats such as JSON, HTML, CSV or Excel. Real rows from runs on Apify on 2026-09-30 (the description is shortened):

```json
[
    {
        "url": "https://my.jobstreet.com/job/94976161",
        "status": "ok",
        "scrapedAt": "2026-09-30T14:28:46.185Z",
        "jobId": "94976161",
        "title": "Inside Sales Executive",
        "companyName": "JP Asia Capital",
        "companyProfileUrl": "https://my.jobstreet.com/companies/jp-asia-capital-168556216578142",
        "logo": "https://image-service-cdn.seek.com.au/9fd43ddbe19786e6f694b2fbc50a18c339a2325c/f3c5292cec0e05e4272d9bf9146f390d366481d0",
        "location": "Mid Valley City, Kuala Lumpur",
        "suburb": "Mid Valley City",
        "region": "Kuala Lumpur",
        "country": "Malaysia",
        "countryCode": "MY",
        "workType": "Full time",
        "workArrangement": "On-site",
        "isRemote": false,
        "salary": "RM 3,000 – RM 4,500 per month",
        "salaryMin": 3000,
        "salaryMax": 4500,
        "salaryPeriod": "month",
        "salaryCurrency": "MYR",
        "classification": "Call Centre & Customer Service",
        "subClassification": "Sales - Outbound",
        "postedAt": "2026-09-30T08:39:19.023Z",
        "teaser": "Sales and customer relationship management role converting leads into confirmed registrations for JP Asia's programmes and services.",
        "bulletPoints": [
            "Attractive Salary + Sales Commission",
            "Career Growth & Business Exposure",
            "Training & Proven Sales Leads"
        ],
        "tags": ["Be an early applicant"],
        "isFeatured": false,
        "site": "jobstreet",
        "siteDomain": "my.jobstreet.com",
        "searchKeyword": "sales",
        "companyIndustry": "Education, Training & Professional Development",
        "companySize": "11-50 employees",
        "companyWebsite": "http://www.jpasia.co",
        "expiresAt": "2026-10-30T12:59:59.999Z",
        "listingStatus": "Active",
        "isLinkOut": false,
        "descriptionText": "About the role\n\nThis is a sales and customer relationship management role focused on converting leads into confirmed registrations and customers for JP Asia's programmes, workshops and consulting services. You will manage the full sales cycle from initial ..."
    },
    {
        "url": "https://my.jobstreet.com/jobs?keywords=zqxjvw+nonexistentjobtitle",
        "status": "not_found",
        "error": "my.jobstreet.com has no jobs for this search (keywords \"zqxjvw nonexistentjobtitle\") with the chosen filters.",
        "scrapedAt": "2026-09-30T14:33:38.881Z",
        "countryCode": "MY",
        "searchKeyword": "zqxjvw nonexistentjobtitle"
    }
]
```

### How much does it cost to scrape Jobstreet and JobsDB?

This Actor uses **pay-per-event** pricing. Platform usage (compute, storage, data transfer) is included in these prices:

| Event | Price | Charged when |
|---|---|---|
| Actor start | $0.005 per run | Once when the run starts (one event per GB of memory; the Actor runs on 1 GB). |
| Job ad | $0.0009 per job | One job with `status: ok` was saved to the dataset. |

**1,000 jobs cost about $0.91** ($0.005 to start plus 1,000 x $0.0009), full descriptions included. Rows with `status` `not_found` or `error` are never billed, and a job found by several of your searches or sites is saved and billed once. The free Apify plan's monthly credit covers several thousand jobs.

You can cap spending per run with **Maximum results** and with the run's **Max total charge** option; the Actor stops gracefully when either limit is reached and keeps everything it has already saved.

### How it compares

- **Six country sites in one run and one schema**, Jobstreet and JobsDB together, with duplicates across sites and searches removed.
- **Single job URLs work**, not only search pages: paste `https://hk.jobsdb.com/job/<id>` or just the id and get the full ad.
- **Salaries are parsed per market**: Indonesian dot-separated rupiah, "315k p.a." style Hong Kong ranges, hourly pesos, USD-paid remote roles; the displayed text is kept next to the numbers.
- **Fast:** one search call returns up to 100 jobs; with full descriptions a 600-job run across six sites took 98 seconds on Apify.

It is not for you if you need candidate profiles, recruiter contact data, applicant counts or anything inside a Jobstreet or JobsDB account; those are out of scope by design.

### Integrations, exports and API access

Results export to **CSV, JSON, Excel**, XML and HTML from the **Output** tab or the dataset API. Apify integrations and webhooks push the same rows into **Google Sheets, Airtable or a CRM**, Slack, Amazon S3 or your own endpoint, directly or through Zapier, Make and n8n. Call the Actor from the **Apify API** (snippets on the **API** tab), from the **Apify MCP server**, or from any AI agent: inputs are plain strings and numbers, and every row carries `status` and `error`.

### Tips

- Keep `maxItems` small while testing, then raise it. The budget is first shared evenly between your searches, so a multi-country run returns a mix of countries.
- Put all keywords and countries in one run instead of many small runs: you pay the start fee once and duplicates are removed.
- Set `fetchDetails` to `false` for the fastest list-level runs (title, company, location, salary, category, teaser and dates, but no full description).
- Search in the site's language too: Thai and Bahasa keywords work as typed.

### Limitations

- **Locations are shared across sites.** The six sites use one SEEK job pool, so a Kuala Lumpur search on the Hong Kong site also returns Kuala Lumpur jobs. Pick only the matching country when you search by city; duplicates are removed either way.
- **The sites' search is broad.** Like on the websites, a keyword also returns related jobs, and the salary filter keeps ads that hide their salary.
- **No apply link.** The employer's own application page is not published to logged-out visitors; `isLinkOut` tells you whether applying happens off-site, and `url` opens the ad.
- **Vietnam and the former Jobstreet Thailand site are not covered**: they no longer exist as SEEK sites.
- **Undocumented data source.** The Actor reads the public job search the sites' own pages use. The sites can change it at any time; rows then come back as `error` with a reason and the Actor is updated (report it in the **Issues** tab).
- **Descriptions are the employer's own text.** E-mail addresses and phone numbers are removed, and recruiter phone numbers and contacts are never requested, but a description may still mention a person by name.

### FAQ

**Do I need a Jobstreet or JobsDB account or API key?** No. You only need an Apify account. The Actor uses the sites' public, logged-out job search.

**Can I paste a search from the website?** Yes. Set your filters on the site, copy the address bar URL (for example `https://my.jobstreet.com/software-engineer-jobs/in-Kuala-Lumpur?worktype=242`) and paste it. Keywords, location, category, work type, date and salary filters in the URL are kept.

**Which currency is `salaryMin` in?** The one in `salaryCurrency`, per `salaryPeriod`. Most ads in these markets state a monthly salary in the local currency; some remote roles pay in USD or AUD.

**Why is `companyName` empty on some rows?** Those ads are posted as "Private Advertiser"; the site does not disclose the employer, so the field is left out rather than filled with the placeholder.

**Why did I get fewer rows than `maxItems`?** The searches had fewer matches, duplicates across sites and searches were removed, or the run hit your **Max total charge** limit. Check the run log for "Stopping gracefully".

**Is it legal to scrape Jobstreet and JobsDB?** Scraping publicly available data is generally legal, but you are responsible for how you use the output. Read the legal notice below and the sites' terms of use, and do not collect personal data without a legitimate reason.

**Can I use this Actor from an AI agent or MCP client?** Yes. Called with no arguments it returns 20 current software engineer jobs from four countries in a few seconds. Every row is self-describing (`status` plus `error`), inputs are plain strings, and results can be fetched via the dataset API or the Apify MCP server.

### Related Actors

- [Seek Jobs Scraper](https://apify.com/glasswing/seek-jobs-scraper) - the same row shape for Seek Australia and New Zealand.
- [LinkedIn Jobs Scraper](https://apify.com/glasswing/linkedin-jobs-scraper) - use it for LinkedIn job postings worldwide.
- [XING Jobs Scraper](https://apify.com/glasswing/xing-jobs-scraper) - use it for job postings in Germany, Austria and Switzerland.

### Legal and data-protection notice

This Actor extracts only job ads that Jobstreet and JobsDB publish publicly to logged-out visitors; it does not extract private user data such as candidate profiles, recruiter names, e-mail addresses, phone numbers, gender or precise location (e-mail addresses and phone numbers found in free-text job descriptions are removed before the row is saved, and the ads' contact phone numbers are never requested), and it does not log in or work around access controls. However, your results could still contain personal data. Personal data is protected by the GDPR in the European Union, by the PDPA in Malaysia, Singapore and Thailand, by the Data Privacy Act in the Philippines, by the PDP Law in Indonesia, by the PDPO in Hong Kong and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with the sites' terms of use and applicable law when using the extracted data.

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by SEEK, Jobstreet or JobsDB. All trademarks belong to their respective owners.

# Changelog

This Actor's version history is a separate document: https://apify.com/glasswing/jobstreet-scraper/changelog.md

# Actor input Schema

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

Search or job pages from any of the six sites, one per line, copied from your browser: https://my.jobstreet.com/software-engineer-jobs/in-Kuala-Lumpur, https://hk.jobsdb.com/jobs?keywords=accountant\&worktype=242, https://sg.jobstreet.com/jobs-in-information-communication-technology, or a single job such as https://ph.jobstreet.com/job/94979838 (a bare job id also works). Every filter in a pasted search URL is kept; the filters below fill in the rest. With URLs of your own, keyword searches run only if you also type keywords or locations.

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

Which sites the keyword/location searches run on; pasted URLs always run on their own site. Jobs found on several sites or searches are returned once. Jobstreet: MY (my.jobstreet.com), SG (sg.jobstreet.com), PH (ph.jobstreet.com), ID (id.jobstreet.com). JobsDB: HK (hk.jobsdb.com), TH (th.jobsdb.com).

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

Search terms, one per line, as you would type them into the site's search box: "software engineer", "accountant", "customer service", "nurse". Each keyword is a separate search on every selected country site. With neither keywords nor locations (and no URLs of your own) the Actor returns the newest jobs of each selected site.

## `locations` (type: `array`):

Cities, states or districts, one per line, as the sites understand them: "Kuala Lumpur", "Penang", "Makati City", "Jakarta Raya", "Kowloon", "Bangkok". Each location is searched on every selected country site. The six sites share one SEEK job pool, so a city is found from any site (Kuala Lumpur jobs also come back from the Hong Kong site); pick just the matching country to avoid the extra searches. Duplicates are always removed. Leave empty for the whole country of each site.

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

Only these work types. Leave empty for all.

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

Only jobs with these arrangements. Leave empty for all.

## `remoteOnly` (type: `boolean`):

Shortcut for Work arrangement = Remote.

## `classifications` (type: `array`):

Only jobs in these categories (the sites' own classification list, the same on all six sites). Leave empty for all.

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

Only jobs listed in the last N days, e.g. 1, 3, 7, 14 or 31. Leave empty for any date.

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

The site's own salary filter, in the local currency of each site (MYR, SGD, PHP, IDR, HKD, THB) for the period chosen below, e.g. 5000 per month. Note: the sites also keep ads that hide their salary.

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

Upper end of the salary filter, same currency and period as the minimum. Leave empty for no upper limit.

## `salaryPeriod` (type: `string`):

What the salary filter amounts mean. Most ads in these markets state a monthly salary.

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

Relevance (the sites' default) or newest first.

## `fetchDetails` (type: `boolean`):

Adds `descriptionText` (the whole ad as plain text, e-mail addresses and phone numbers removed), `expiresAt`, `listingStatus` and the company's industry, size and website. One extra request per job; turn it off for the fastest list-level runs.

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

Stop after this many rows in total. Each saved job (status ok) is one billable result. The budget is shared evenly between the searches first, so a multi-country run returns a mix of countries.

## `maxItemsPerSearch` (type: `integer`):

Cap for each search (one site x keyword x location, or one pasted search URL), e.g. 200, so one broad search cannot use the whole budget. Leave empty for no per-search cap.

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

Optional. The Actor calls the sites' public job search over plain HTTP and works from Apify's datacenter IPs without a proxy (tested on all six sites). Enable Apify Proxy (datacenter) only if you see repeated request failures; residential proxies are not needed.

## `query` (type: `string`):

Hidden single-keyword alias of `keywords` for API and agent callers, e.g. "data analyst".

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

Hidden single-location alias of `locations` for API and agent callers, e.g. "Kuala Lumpur".

## Actor input object example

```json
{
  "startUrls": [
    "https://my.jobstreet.com/software-engineer-jobs",
    "https://sg.jobstreet.com/software-engineer-jobs",
    "https://ph.jobstreet.com/software-engineer-jobs",
    "https://hk.jobsdb.com/software-engineer-jobs"
  ],
  "countries": [
    "MY",
    "SG",
    "PH",
    "HK"
  ],
  "salaryPeriod": "month",
  "sortBy": "relevance",
  "fetchDetails": true,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "startUrls": [
        "https://my.jobstreet.com/software-engineer-jobs",
        "https://sg.jobstreet.com/software-engineer-jobs",
        "https://ph.jobstreet.com/software-engineer-jobs",
        "https://hk.jobsdb.com/software-engineer-jobs"
    ],
    "countries": [
        "MY",
        "SG",
        "PH",
        "HK"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("glasswing/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 = {
    "startUrls": [
        "https://my.jobstreet.com/software-engineer-jobs",
        "https://sg.jobstreet.com/software-engineer-jobs",
        "https://ph.jobstreet.com/software-engineer-jobs",
        "https://hk.jobsdb.com/software-engineer-jobs",
    ],
    "countries": [
        "MY",
        "SG",
        "PH",
        "HK",
    ],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("glasswing/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 '{
  "startUrls": [
    "https://my.jobstreet.com/software-engineer-jobs",
    "https://sg.jobstreet.com/software-engineer-jobs",
    "https://ph.jobstreet.com/software-engineer-jobs",
    "https://hk.jobsdb.com/software-engineer-jobs"
  ],
  "countries": [
    "MY",
    "SG",
    "PH",
    "HK"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call glasswing/jobstreet-scraper --silent --output-dataset

```

## MCP server setup

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