# foundit Markets Scraper — compare SEA countries by demand (`entrogix_works/foundit-market-benchmark`) Actor

Pick one role and compare Singapore, Malaysia, Indonesia and Hong Kong on foundit. One row per market: how many postings are native to the board once reposts from other job boards are removed, with a confidence range and the list of source domains. Unofficial; not affiliated with foundit or Monster.

- **URL**: https://apify.com/entrogix\_works/foundit-market-benchmark.md
- **Developed by:** [Entrogix Works](https://apify.com/entrogix_works) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$30.00 / 1,000 market benchmarkeds

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?

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

## SEA Jobs Scraper — compare markets by real demand

Pick **one role** and **two or more Southeast Asian markets**, and get one row per market ranked by a number no other job-board scraper reports: **how much of the board's inventory is actually its own.**

foundit carries a large volume of listings reposted from other job boards. In testing, **19 of 20 Singapore listings for one role were reposts**, pointing at `linkedin.com`, `mycareersfuture.gov.sg` and `careers.shopee.sg`. Count them as Singapore demand and you have counted those boards twice. This Actor separates the two per market and names where the reposts came from.

### What you get per market

| Field | Example |
|---|---|
| `market` | `singapore` |
| `nativeRate` | `0.15` — share that is not reposted from elsewhere |
| `nativeRateRange` | `[0.05, 0.36]` — 95% range for that share |
| `nativeJobs`, `repostedJobs`, `jobs` | `3`, `17`, `20` |
| `repostedFrom` | `[{ "domain": "linkedin.com", "jobs": 14 }, …]` |
| `salaryDisclosureRate` | `0.30` |
| `medianExperienceMinYears` | `3` |
| `uniqueCompanies` | `18` |
| `rank`, `notRankedReason` | `1`, or why the row was left out |

The run summary reports `totalJobs` next to `totalNativeJobs`, so the gap between the headline number and the real one is one line.

### What this Actor refuses to do

**Compare salaries across markets.** Singapore is priced in SGD, Malaysia in MYR. Putting those in one ranking would produce an order that means nothing, so pay is reported per market and never ranked between them. `currenciesSeen` shows what was found.

**Rank by job count.** Every market is sampled the same number of listings, so the count reflects your sample size, not the market. Ranking is by *rate*, with a Wilson confidence range — which stays honest at 0% and 100%, where the textbook formula collapses to zero width.

**Let one recruiter or one board stand in for a market.** `repostedFrom` and `uniqueCompanies` are on every row.

Markets with fewer than 10 listings get `rank: null` rather than a rate that swings on one posting.

### Summary (key-value store, `BENCHMARK_SUMMARY`)

`query`, `markets`, `ranked`, `mostNative`, `mostNativeRate`, **`topTwoTooClose`**, `medianNativeRate`, **`totalJobs`** vs **`totalNativeJobs`**, **`repostedFrom`**, `currenciesSeen`, `notRanked`.

### Input

```json
{
  "query": "data analyst",
  "countries": ["singapore", "malaysia", "hong-kong"],
  "samplePerCountry": 40
}
```

Available markets: `singapore`, `malaysia`, `indonesia`, `hong-kong`. **India is not offered** — it blocked 5 of 6 test requests where the others passed 6 of 6, and a market that fails most of the time would distort a comparison rather than inform it. A single market is rejected: one market is not a comparison. You are charged **per market**, not per job.

### Limits, stated plainly

- "Native" means foundit did not mark the listing as sourced from another board. A company that posts to both foundit and LinkedIn independently counts as native here.
- A residential proxy is required. foundit refused datacenter traffic in every one of 12 test requests.
- Only job listings are read. Nothing about applicants is collected.

Unofficial; not affiliated with foundit or Monster.

# Actor input Schema

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

A single job title, for example 'data analyst'. The same term is used in every market so the comparison stays fair.

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

Two or more foundit markets. India is not offered: it blocks most requests, and a market that fails most of the time would distort the comparison rather than inform it.

## `samplePerCountry` (type: `integer`):

Every market is sampled the same way so the comparison stays fair. A larger sample narrows the reported range. You are charged per market, not per job, so raising this does not cost you more.

## `minIntervalMs` (type: `integer`):

Pacing between page fetches. Do not lower this.

## `useProxy` (type: `boolean`):

Required. foundit refused datacenter traffic in every one of 12 test requests.

## Actor input object example

```json
{
  "query": "data analyst",
  "countries": [
    "singapore",
    "malaysia",
    "hong-kong"
  ],
  "samplePerCountry": 40,
  "minIntervalMs": 3000,
  "useProxy": true
}
```

# Actor output Schema

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

Every row this run produced, as JSON.

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

Which market has the most native demand, whether the top two are separable, how far the headline job count falls once reposts are removed, and which boards those reposts came from.

# 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 = {
    "query": "data analyst",
    "countries": [
        "singapore",
        "malaysia",
        "hong-kong"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("entrogix_works/foundit-market-benchmark").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 = {
    "query": "data analyst",
    "countries": [
        "singapore",
        "malaysia",
        "hong-kong",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("entrogix_works/foundit-market-benchmark").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 '{
  "query": "data analyst",
  "countries": [
    "singapore",
    "malaysia",
    "hong-kong"
  ]
}' |
apify call entrogix_works/foundit-market-benchmark --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,entrogix_works/foundit-market-benchmark"
        }
    }
}

```

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/3kKchHdnf6ER9sC5f/builds/TSjDBSDMffxVfPkDO/openapi.json
