JobThai.com Job Scraper
Pricing
$0.99 / 1,000 result scrapeds
JobThai.com Job Scraper
Scrape job listings from jobthai.com - Thailand's leading job board. GraphQL API, no proxy, no Playwright. PAY_PER_EVENT.
Pricing
$0.99 / 1,000 result scrapeds
Rating
0.0
(0)
Developer
Unfenced Group
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
πΉπ JobThai Scraper
Extract job listings from jobthai.com β Thailand's leading job board with 48,000+ active listings and 1.8 M monthly visitors.
β¨ Key features
- GraphQL API β hits
api.jobthai.com/v1/graphqldirectly; no HTML parsing, no Cheerio, no Playwright - No proxy required β endpoint is publicly accessible from any IP worldwide
- Two query modes β fast list scrape (20 fields) or rich detail scrape (30+ fields)
- Full filter support β keyword, province, job type, region, salary range, hybrid/WFH/online interview flags
- PAY_PER_EVENT pricing β pay per result, not per Compute Unit
π¦ Output fields
List mode (default)
| Field | Type | Description |
|---|---|---|
jobId | string | Numeric job ID |
companyId | string | Employer company ID |
title | string | Job title |
company | string | Employer name |
province | string | Province name |
provinceId | string | Province code (e.g. "01" = Bangkok) |
district | string | District name |
districtId | string | District code |
region | string | Region name (e.g. "Bangkok Area") |
regionId | string | Region ID ("6" = Bangkok Area) |
country | string | Country name β only populated for overseas jobs (province="99"). null for all domestic Thai listings |
jobType | string | Job category name |
jobTypeId | integer | Job category ID |
industry | string | Industrial estate / area name |
industryId | string | Industry ID |
salary | string | Salary range or description |
isUrgent | boolean | true if marked as urgent hiring |
isTopCompany | boolean | true if featured company |
workLocation | string | Free-text work location detail |
transitStations | object[] | Nearby BTS/MRT/BRT stations with distance (metres) and type |
tags | string[] | Labels: "Hybrid Work", "Online Interview", "Hybrid Working" |
datePosted | string | ISO date (YYYY-MM-DD) |
updatedAt | string | Full ISO timestamp |
jobUrl | string | Canonical link: https://www.jobthai.com/jobsearch/job/{id} |
scrapedAt | string | ISO timestamp of extraction |
Detail mode (scrapeDetail: true) β adds these fields
| Field | Type | Description |
|---|---|---|
description | string | Full job description / responsibilities |
benefit | string | Welfare and benefits (company-level) |
companyBenefit | string | Benefit text from company profile |
applyMethod | string | How to apply |
employmentType | string | FULL_TIME / PART_TIME / CONTRACT |
numberOfPositions | string | Number of open positions |
englishApply | boolean | Whether English CV is accepted |
subJobType | string | Sub-category of job type |
businessType | string | Company business category |
companyWebsite | string | Employer website |
address | string | Full work address |
subdistrict | string | Sub-district (tambon) |
industrialArea | string | Industrial estate name |
latitude | number | GPS latitude β null if employer did not set location |
longitude | number | GPS longitude β null if employer did not set location |
contactName | string | HR contact name |
contactTel | string | HR phone number |
contactFax | string | HR fax number |
contactEmails | string[] | HR email addresses (trustmail masked) |
contactLineId | string | HR Line ID |
applyExternalLink | string | External application URL (if any) |
βοΈ Input
{"keyword": "python developer","province": "01","jobtype": "10","salarymin": 50000,"maxItems": 200,"scrapeDetail": false}
Input fields
| Field | Default | Description |
|---|---|---|
keyword | "" | Job title, skill, or free-text keyword |
province | "" | Province code (see table). Blank = all |
jobtype | "" | Job category ID (see table). Blank = all |
region | "" | Region: 1=N 2=NE 3=Central 4=E 5=W 6=S/Bangkok |
salarymin | 0 | Minimum monthly salary (THB). 0 = no filter |
salarymax | 0 | Maximum monthly salary (THB). 0 = no filter |
hybridwork | false | Only hybrid-work jobs |
wfh | false | Only fully remote / WFH jobs |
onlineInterview | false | Only jobs offering online interviews |
startPage | 1 | Page to start from (20 jobs/page) |
maxPages | 0 | Max pages (0 = unlimited) |
maxItems | 0 | Max results (0 = unlimited) |
scrapeDetail | false | Fetch full detail per job (+15 fields, slower) |
language | "en" | "en" or "th" |
Province codes
| Code | Province | Code | Province |
|---|---|---|---|
01 | Bangkok | 28 | Pathum Thani |
02 | Samut Prakan | 29 | Nonthaburi |
03 | Samut Sakhon | 09 | Chon Buri |
04 | Nakhon Pathom | 10 | Chiang Mai |
05 | Samut Songkhram | 13 | Phuket |
06 | Ratchaburi | 73 | Udon Thani |
07 | Kanchanaburi | 74 | Khon Kaen |
08 | Suphan Buri | 99 | Overseas |
Job type IDs
| ID | Category | ID | Category |
|---|---|---|---|
1 | Marketing / PR | 14 | Information Technology |
2 | Sales | 15 | Accounting |
3 | Customer Service | 16 | Human Resources |
4 | Finance | 17 | Manufacturing / QC |
5 | Administrative | 18 | Purchasing / Supply Chain |
7 | Engineering | 19 | Driver / Delivery |
10 | IT / Programming | 26 | Secretary |
11 | Architecture | 28 | Engineering (Mfg) |
12 | R&D | 31 | Overseas |
π Usage examples
Bangkok IT jobs, list only:
{ "province": "01", "jobtype": "10", "maxItems": 500 }
Python developer search with full detail:
{ "keyword": "python developer", "scrapeDetail": true, "maxItems": 100 }
High-salary engineering roles:
{ "jobtype": "7", "salarymin": 80000, "maxItems": 200 }
Hybrid work jobs only:
{ "hybridwork": true, "province": "01", "maxItems": 300 }
Full scrape (all jobs, all provinces):
{ "maxPages": 0, "maxItems": 0 }
π° Pricing
PAY_PER_EVENT: $0.99 / 1,000 results
| Mode | Est. CU cost / 1,000 results | Billed at |
|---|---|---|
| List only | ~$0.02 | $0.99 |
| List + detail | ~$0.05 | $1.49 |
No proxy cost. No Playwright. GraphQL = pure JSON, ~3 KB/request.
π Architecture
InputβββΊ searchJobs(filter, page) POST https://api.jobthai.com/v1/graphqlβββΊ [optional] getJobRawData(id) same endpointβββΊ dataset.pushData()βββΊ Actor.charge() PAY_PER_EVENT
GraphQL queries used
searchJobs β paginated list, 20 jobs per page:
query ($f: JobsSearchFilter, $o: JobOrderBy, $s: StaticDataVersion) {searchJobs(filter: $f, orderBy: $o, staticDataVersion: $s) {data { total data { id jobTitle companyName salary province { id name } ... } }}}
getJobRawData β full detail per job:
query ($id: Int!, $l: Language, $s: StaticDataVersion) {getJobRawData(id: $id, l: $l, staticDataVersion: $s) {data { _id title description benefit employmentType contact { ... } workLocation { latitude longitude ... } }}}
How the endpoint was found
The public www.jobthai.com frontend is a Next.js app. Its __NEXT_DATA__ JSON contains an Apollo state with cached searchJobs results. The commons.js Next.js chunk exposes the runtime config:
externalApiGateway: "https://api.jobthai.com/v1/graphql"
This endpoint accepts requests from any origin β no authentication required.
π§ Local development
npm installnode src/test.js # 25/25 live GraphQL batterynode src/main.js # full run (needs .actor/input.json or APIFY_INPUT env)
All 25 tests hit the real GraphQL API. T21/T25 allow β€2 pagination overlaps β normal with UPDATED_AT_DESC ordering on a high-frequency live feed.
Built by unfenced-group Β· jobthai.com operated by THiNKNET Co., Ltd.