# Glints Job Scraper 🌏 (`unfenced-group/glints-scraper`) Actor

$0.99/1k jobs — Southeast Asia's Glints.com scraper. No proxy, no browser. Indonesia, Singapore, Malaysia, Vietnam, Taiwan. Salaries, skills, geo-coordinates, company data. 90+ categories x 5 countries.

- **URL**: https://apify.com/unfenced-group/glints-scraper.md
- **Developed by:** [Unfenced Group](https://apify.com/unfenced-group) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 12 total users, 3 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 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.
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

## Glints Job Scraper 🌏

![Glints Job Scraper 🌏](https://api.apify.com/v2/key-value-stores/lJlifu6C8YQfZMPKE/records/glints-scraper)

**💰 $0.99 per 1,000 jobs** — Southeast Asia's **only dedicated Glints.com scraper**. No API key required. No proxy. No browser.

Covers all 5 Glints markets: **Indonesia 🇮🇩 · Singapore 🇸🇬 · Malaysia 🇲🇾 · Vietnam 🇻🇳 · Taiwan 🇹🇼**

***

### Why this scraper?

#### 🌏 5-market coverage in one run

Indonesia, Singapore, Malaysia, Vietnam, and Taiwan — all configurable per run. Mix or match countries freely.

#### ⚡ Fast & lightweight

Up to ~23,000 unique job listings per run without a browser. Runs complete in minutes on 256 MB memory.

#### 💼 Rich structured data

Every job includes salary ranges, required skills (with must-have flags), geo-coordinates, company verification status, geo-coordinates and hierarchical job categories.

#### 🔁 Scheduler-ready incremental mode

Run daily and collect only newly posted jobs. State persists between runs — zero duplicate spend.

#### 🎯 Powerful filters

Keyword, job type, work arrangement, education level, salary range, country, last-updated window, and more — all combinable.

#### 📋 Full job descriptions (optional)

Enable `fetchDetails` to retrieve complete plain-text descriptions, benefits, and external apply links.

***

### Input parameters

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `countries` | `string[]` | All 5 | Markets to scrape: `ID` `SG` `MY` `VN` `TW` |
| `keyword` | `string` | — | Keyword search (e.g. `software engineer`) |
| `jobTypes` | `string[]` | — | `FULL_TIME` `PART_TIME` `CONTRACT` `INTERNSHIP` `PROJECT_BASED` |
| `workArrangements` | `string[]` | — | `REMOTE` `HYBRID` `ONSITE` |
| `educationLevels` | `string[]` | — | `HIGH_SCHOOL` `DIPLOMA` `BACHELOR_DEGREE` `MASTER_DEGREE` `DOCTORATE` |
| `lastUpdated` | `string` | — | `PAST_24_HOURS` `PAST_WEEK` `PAST_MONTH` `ANY_TIME` |
| `sortBy` | `string` | `LATEST` | `LATEST` or `RELEVANT` |
| `minSalary` | `number` | — | Minimum salary (requires `salaryCurrency`) |
| `salaryCurrency` | `string` | — | `IDR` `SGD` `MYR` `VND` `TWD` |
| `fetchDetails` | `boolean` | `false` | Fetch full description, benefits, and apply URL |
| `incrementalMode` | `boolean` | `false` | Skip jobs seen in previous runs |
| `stateStoreName` | `string` | `glints-scraper-state` | KV store name for incremental state |
| `maxResults` | `number` | `5` | Stop after N results (0 = unlimited full sweep) |
| `requestsPerSecond` | `number` | `3` | Request rate (1–10) |
| `debug` | `boolean` | `false` | Verbose run logging |

***

### Output schema

#### Always present

| Field | Type | Description |
|-------|------|-------------|
| `id` | `string` | Unique Glints job UUID |
| `title` | `string` | Job title |
| `url` | `string` | Direct link to the job posting |
| `status` | `string` | `OPEN` or `CLOSED` |
| `type` | `string\|null` | `FULL_TIME` `PART_TIME` `CONTRACT` `INTERNSHIP` `PROJECT_BASED` |
| `workArrangement` | `string\|null` | `REMOTE` `HYBRID` `ONSITE` |
| `createdAt` | `string` | ISO 8601 posting date |
| `updatedAt` | `string` | ISO 8601 last update |
| `isHot` | `boolean` | Whether listing is featured/promoted |
| `shouldShowSalary` | `boolean\|null` | Whether salary is publicly shown |
| `educationLevel` | `string\|null` | Minimum education requirement |
| `minYearsOfExperience` | `number\|null` | Minimum years of experience |
| `maxYearsOfExperience` | `number\|null` | Maximum years of experience |
| `source` | `string` | `NATIVE` or `EXTERNAL` |
| `jobSource` | `string` | `EMPLOYER` or `AGENCY` |
| `company.id` | `string` | Company UUID |
| `company.name` | `string` | Company display name (brand name if set) |
| `company.status` | `string` | Verification status |
| `company.isVIP` | `boolean` | VIP/premium employer flag |
| `company.isVerified` | `boolean` | Whether company is verified |
| `company.industry` | `string\|null` | Industry name |
| `company.verificationTier` | `string\|null` | Verification tier (e.g. `LEGAL_DOCUMENTS`) |
| `location.city` | `string\|null` | City / regency (derived from the location hierarchy) |
| `location.citySubDivision` | `string\|null` | District / sub-division (most granular level) |
| `location.formattedLocation` | `string\|null` | Full formatted location string |
| `location.country` | `string\|null` | Country name |
| `location.countryCode` | `string\|null` | ISO country code |
| `location.latitude` | `number\|null` | Geographic latitude |
| `location.longitude` | `number\|null` | Geographic longitude |
| `salary` | `object\|null` | `null` when salary not disclosed |
| `salary.minAmount` | `number\|null` | Minimum salary amount |
| `salary.maxAmount` | `number\|null` | Maximum salary amount |
| `salary.currency` | `string\|null` | Currency code (`IDR` `SGD` `MYR` etc.) |
| `salary.salaryType` | `string\|null` | Pay type (`BASIC` etc.) |
| `salary.salaryMode` | `string\|null` | Pay frequency (`MONTH` `YEAR` etc.) |
| `skills` | `array` | `[{ name, mustHave }]` — required skills |
| `category.id` | `string\|null` | Category UUID |
| `category.name` | `string\|null` | Category name (L2) |
| `category.level` | `number\|null` | Hierarchy level |
| `category.parentName` | `string\|null` | Parent L1 category name |
| `category.parentId` | `string\|null` | Parent L1 category UUID |

#### Only with `fetchDetails: true`

| Field | Type | Description |
|-------|------|-------------|
| `description` | `string\|null` | Full job description in plain text |
| `benefits` | `string[]\|null` | List of offered benefits |
| `externalApplyURL` | `string\|null` | External ATS link if applicable |
| `acceptsForeignApplications` | `boolean\|null` | Whether non-residents can apply |
| `expiryDate` | `string\|null` | Listing expiry date (ISO 8601) |
| `isCoverLetterMandatory` | `boolean\|null` | Whether a cover letter is required |

> All `fetchDetails` fields are `null` when `fetchDetails: false`.

***

#### Example record

```json
{
  "id": "0edbd1d6-752f-4a60-9a40-ebb1a505f81b",
  "title": "Staff Akuntan",
  "url": "https://glints.com/id/opportunities/jobs/staff-akuntan/0edbd1d6-752f-4a60-9a40-ebb1a505f81b",
  "status": "OPEN",
  "type": "FULL_TIME",
  "workArrangement": "ONSITE",
  "createdAt": "2026-06-16T08:12:51.748Z",
  "updatedAt": "2026-06-16T08:12:52.487Z",
  "isHot": false,
  "shouldShowSalary": true,
  "educationLevel": "HIGH_SCHOOL",
  "minYearsOfExperience": 0,
  "maxYearsOfExperience": 50,
  "source": "NATIVE",
  "jobSource": "EMPLOYER",
  "company": {
    "id": "4f67387e-82f9-476f-a5a3-8f7184a6ed6e",
    "name": "Sekolah Tunas Unggul",
    "status": "VERIFIED",
    "isVIP": false,
    "isVerified": true,
    "industry": "Education Management",
    "verificationTier": "LEGAL_DOCUMENTS"
  },
  "location": {
    "city": "Kab. Bandung",
    "citySubDivision": "Kutawaringin",
    "formattedLocation": "Indonesia, Jawa Barat, Kab. Bandung, Kutawaringin",
    "country": "Indonesia",
    "countryCode": "ID",
    "latitude": -6.99972,
    "longitude": 107.50972
  },
  "salary": {
    "minAmount": 2000000,
    "maxAmount": 3000000,
    "currency": "IDR",
    "salaryType": "BASIC",
    "salaryMode": "MONTH"
  },
  "skills": [
    {
      "name": "Accounting",
      "mustHave": true
    },
    {
      "name": "Microsoft Excel",
      "mustHave": true
    },
    {
      "name": "Bookkeeping",
      "mustHave": true
    }
  ],
  "category": {
    "id": "e602d9fb-8a70-4ba7-916d-d0e49c6c5516",
    "name": "Accountant",
    "level": 3,
    "parentName": "Accounting",
    "parentId": "76caa9d7-4cec-4574-9eb4-b5ea9e3de07c"
  },
  "description": null,
  "benefits": null,
  "externalApplyURL": null,
  "acceptsForeignApplications": null,
  "expiryDate": null,
  "isCoverLetterMandatory": null
}
```

### Examples

**Software jobs in Singapore (remote)**

```json
{
  "countries": ["SG"],
  "keyword": "software engineer",
  "workArrangements": ["REMOTE"],
  "jobTypes": ["FULL_TIME"]
}
```

**Full Indonesia + Malaysia sweep**

```json
{
  "countries": ["ID", "MY"],
  "sortBy": "LATEST",
  "maxResults": 10000
}
```

**Daily incremental feed (schedulers)**

```json
{
  "lastUpdated": "PAST_24_HOURS",
  "incrementalMode": true,
  "sortBy": "LATEST"
}
```

**High-paying SG roles with full details**

```json
{
  "countries": ["SG"],
  "jobTypes": ["FULL_TIME"],
  "minSalary": 5000,
  "salaryCurrency": "SGD",
  "fetchDetails": true
}
```

***

### 💰 Pricing

**$0.99 per 1,000 results** — you only pay for successfully retrieved listings. Failed retries are never charged.

| Results | Cost |
|---------|------|
| 100 | ~$0.1 |
| 1,000 | ~$0.99 |
| 10,000 | ~$9.9 |
| 100,000 | ~$99 |

> Flat-rate alternatives typically charge $29–$49/month regardless of usage.

Use the **Max results** cap to control your spend exactly.

***

### Performance

| Run type | Results | Time |
|----------|---------|------|
| Keyword, 1 country | up to 100 | ~10s |
| Full sweep, 1 country | up to 4,600 | ~5 min |
| Full sweep, all 5 countries | up to 23,000 | ~25 min |
| With `fetchDetails: true`, 1,000 results | 1,000 | ~10 min |

***

### Known limitations

- Maximum 100 results per category/keyword per country without authentication (Glints platform limit)
- Salary data is only available when the employer has opted to show it (`shouldShowSalary: true`)
- Vietnam and Taiwan markets have significantly fewer listings than Indonesia and Singapore
- `fetchDetails` roughly doubles run time

***

### Technical details

- **Source:** glints.com — Southeast Asia's leading talent platform
- **Push notifications:** get new results delivered to Telegram, Discord, Slack, WhatsApp or any webhook the moment a scheduled run finds them
- **Memory:** 256 MB
- **Deduplication:** by job UUID within each run
- **Incremental state:** KeyValueStore `glints-scraper-state`, persists between runs
- **Retry:** Automatic retry on network errors with exponential backoff, 3 attempts per request

***

### Related scrapers

Other scrapers in our **Jobs — East & Southeast Asia** collection:

- [MyCareersFuture Singapore Jobs Scraper](https://apify.com/unfenced-group/mcf-sg-scraper)
- [Kalibrr Job Scraper — Philippines](https://apify.com/unfenced-group/kalibrr-scraper)
- [Rikunabi NEXT Scraper](https://apify.com/unfenced-group/rikunabi-scraper)
- [JobTopGun Scraper](https://apify.com/unfenced-group/jobtopgun-scraper)
- [104.com.tw Taiwan Jobs Scraper](https://apify.com/unfenced-group/taiwan104-scraper)

***

### Frequently asked questions

**How do I search for jobs on Glints with this actor?**

Pass your keywords and location, and the actor returns all matching listings — title, company, location, and the apply URL — as one structured dataset.

**How does the data compare to browsing Glints directly?**

Same listings, but the full result set at once instead of page-by-page, structured into typed fields you can filter, sort, or export.

**Can I filter by role or region across Southeast Asia?**

Yes. Pass location and keyword filters and the actor returns only matching listings. Run several searches in one go and they merge into one dataset.

**How do I keep the data current?**

Schedule a daily or weekly run. Each run is timestamped, so new listings are easy to isolate.

***

### Run it on a schedule

This actor is built for repeat use. Set it to run daily, weekly, or hourly, and the data keeps flowing without you touching it.

- **Schedule runs** — open the actor, go to Schedules, and pick a cadence. Each run only charges you for the results it returns.
- **Connect it to your stack** — push results straight to Google Sheets, Slack, a webhook, or your database using Apify Integrations. No glue code needed.
- **Pull results via API** — every run writes a clean dataset you can fetch with one API call, ready for whatever you build on top of it.

Set it once and it runs on its own.

***

### Rate this actor

If this scraper does its job, a short review on the **Reviews** tab helps other users find it. Something not working? Open an issue on the **Issues** tab instead — issues get fixed.

***

### Need a custom scraper?

**[Unfenced Group](https://www.unfencedgroup.nl)** builds Apify actors for any website — for free.

If the site you need isn't in our portfolio yet, just ask. We scope, build, and publish it at no cost to you. You only pay for results — we absorb the compute and proxy costs ourselves. Same pay-per-result pricing, same quality, same standards as every actor in this portfolio.

**Get in touch:** [www.unfencedgroup.nl](https://www.unfencedgroup.nl)

# Actor input Schema

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

Country codes to scrape. ID=Indonesia, SG=Singapore, MY=Malaysia, VN=Vietnam, TW=Taiwan

## `searchQuery` (type: `string`):

Job title keyword (e.g. 'software engineer'). Switches from full category sweep to keyword mode. Faster but returns fewer results.

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

Filter by employment type. Options: FULL\_TIME, PART\_TIME, CONTRACT, INTERNSHIP, PROJECT\_BASED

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

Filter by work location. Options: REMOTE, HYBRID, ONSITE

## `educationLevels` (type: `array`):

Filter by minimum education. Options: HIGH\_SCHOOL, DIPLOMA, BACHELOR\_DEGREE, MASTER\_DEGREE, DOCTORATE

## `lastUpdated` (type: `string`):

Only include jobs updated within this period. Options: PAST\_24\_HOURS, PAST\_WEEK, PAST\_MONTH, ANY\_TIME

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

Result ordering. Options: LATEST (newest first), RELEVANT (best match first)

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

Minimum salary filter. Must be used together with salaryCurrency.

## `salaryCurrency` (type: `string`):

Currency code for salary filter. Options: IDR, SGD, MYR, VND, TWD

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

Fetch full description, benefits list, and external apply URL for each job. Increases CU usage but provides richer data.

## `incrementalMode` (type: `boolean`):

Only output jobs not seen in a previous run. Ideal for scheduled runs – saves costs by skipping known listings. State persists between runs in a Key-Value Store.

## `stateStoreName` (type: `string`):

Name of the Key-Value Store used to persist incremental state. Default: glints-scraper-state

## `maxResults` (type: `integer`):

Stop after collecting this many jobs. 0 = no limit (full sweep).

## `requestsPerSecond` (type: `integer`):

Rate limit for API requests. Higher = faster but more likely to trigger throttling. Recommended: 3–5.

## `debug` (type: `boolean`):

Enable verbose logging. Useful for troubleshooting – logs each category and page fetched.

## `telegramToken` (type: `string`):

Bot token from @BotFather, e.g. '110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw'. Requires Telegram chat ID below.

## `telegramChatId` (type: `string`):

Chat or channel ID the bot posts to, e.g. '-1001234567890'. Get it from @userinfobot.

## `discordWebhookUrl` (type: `string`):

Discord channel webhook, e.g. 'https://discord.com/api/webhooks/…'. Channel settings → Integrations → Webhooks.

## `slackWebhookUrl` (type: `string`):

Slack incoming webhook, e.g. 'https://hooks.slack.com/services/…'.

## `whatsappPhoneNumberId` (type: `string`):

Meta Cloud API phone number ID, e.g. '106540352242922'. Requires access token and recipient below.

## `whatsappAccessToken` (type: `string`):

Meta Cloud API access token for the WhatsApp Business account.

## `whatsappTo` (type: `string`):

Recipient phone number in international format, e.g. '31612345678'.

## `webhookUrl` (type: `string`):

Any HTTPS endpoint. Receives a JSON POST with site, query, result counts and the newest items, e.g. 'https://example.com/hooks/jobs'.

## `webhookHeaders` (type: `object`):

Optional extra HTTP headers for the webhook request, e.g. {"Authorization": "Bearer abc123"}.

## `notificationLimit` (type: `integer`):

Maximum number of results shown in a notification message. Default 10, cap 25.

## `notifyOnlyChanges` (type: `boolean`):

Only send a notification when the run found new or changed items. Applies when incremental tracking is active; full runs with results always notify.

## Actor input object example

```json
{
  "countries": [
    "ID",
    "SG",
    "MY",
    "VN",
    "TW"
  ],
  "sortBy": "LATEST",
  "fetchDetails": false,
  "incrementalMode": false,
  "stateStoreName": "glints-scraper-state",
  "maxResults": 5,
  "requestsPerSecond": 3,
  "debug": false,
  "notificationLimit": 10,
  "notifyOnlyChanges": true
}
```

# 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 = {
    "countries": [
        "ID",
        "SG",
        "MY",
        "VN",
        "TW"
    ],
    "maxResults": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("unfenced-group/glints-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 = {
    "countries": [
        "ID",
        "SG",
        "MY",
        "VN",
        "TW",
    ],
    "maxResults": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("unfenced-group/glints-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "countries": [
    "ID",
    "SG",
    "MY",
    "VN",
    "TW"
  ],
  "maxResults": 5
}' |
apify call unfenced-group/glints-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=unfenced-group/glints-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/V2559Dha4rCEnIDMn/builds/237zzLl5ndhZd7nBG/openapi.json
