JobThai.com Job Scraper avatar

JobThai.com Job Scraper

Pricing

$0.99 / 1,000 result scrapeds

Go to Apify Store
JobThai.com Job Scraper

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

Unfenced Group

Maintained by Community

Actor stats

1

Bookmarked

3

Total users

1

Monthly active users

2 days ago

Last modified

Share

🇹🇭 JobThai Scraper

JobThai.com Job 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/graphql directly; 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)

FieldTypeDescription
jobIdstringNumeric job ID
companyIdstringEmployer company ID
titlestringJob title
companystringEmployer name
provincestringProvince name
provinceIdstringProvince code (e.g. "01" = Bangkok)
districtstringDistrict name
districtIdstringDistrict code
regionstringRegion name (e.g. "Bangkok Area")
regionIdstringRegion ID ("6" = Bangkok Area)
countrystringCountry name — only populated for overseas jobs (province="99"). null for all domestic Thai listings
jobTypestringJob category name
jobTypeIdintegerJob category ID
industrystringIndustrial estate / area name
industryIdstringIndustry ID
salarystringSalary range or description
isUrgentbooleantrue if marked as urgent hiring
isTopCompanybooleantrue if featured company
workLocationstringFree-text work location detail
transitStationsobject[]Nearby BTS/MRT/BRT stations with distance (metres) and type
tagsstring[]Labels: "Hybrid Work", "Online Interview", "Hybrid Working"
datePostedstringISO date (YYYY-MM-DD)
updatedAtstringFull ISO timestamp
jobUrlstringCanonical link: https://www.jobthai.com/jobsearch/job/{id}
scrapedAtstringISO timestamp of extraction

Detail mode (scrapeDetail: true) — adds these fields

FieldTypeDescription
descriptionstringFull job description / responsibilities
benefitstringWelfare and benefits (company-level)
companyBenefitstringBenefit text from company profile
applyMethodstringHow to apply
employmentTypestringFULL_TIME / PART_TIME / CONTRACT
numberOfPositionsstringNumber of open positions
englishApplybooleanWhether English CV is accepted
subJobTypestringSub-category of job type
businessTypestringCompany business category
companyWebsitestringEmployer website
addressstringFull work address
subdistrictstringSub-district (tambon)
industrialAreastringIndustrial estate name
latitudenumberGPS latitude — null if employer did not set location
longitudenumberGPS longitude — null if employer did not set location
contactNamestringHR contact name
contactTelstringHR phone number
contactFaxstringHR fax number
contactEmailsstring[]HR email addresses (trustmail masked)
contactLineIdstringHR Line ID
applyExternalLinkstringExternal application URL (if any)

⚙️ Input

{
"keyword": "python developer",
"province": "01",
"jobtype": "10",
"salarymin": 50000,
"maxItems": 200,
"scrapeDetail": false
}

Input fields

FieldDefaultDescription
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
salarymin0Minimum monthly salary (THB). 0 = no filter
salarymax0Maximum monthly salary (THB). 0 = no filter
hybridworkfalseOnly hybrid-work jobs
wfhfalseOnly fully remote / WFH jobs
onlineInterviewfalseOnly jobs offering online interviews
startPage1Page to start from (20 jobs/page)
maxPages0Max pages (0 = unlimited)
maxItems0Max results (0 = unlimited)
scrapeDetailfalseFetch full detail per job (+15 fields, slower)
language"en""en" or "th"

Province codes

CodeProvinceCodeProvince
01Bangkok28Pathum Thani
02Samut Prakan29Nonthaburi
03Samut Sakhon09Chon Buri
04Nakhon Pathom10Chiang Mai
05Samut Songkhram13Phuket
06Ratchaburi73Udon Thani
07Kanchanaburi74Khon Kaen
08Suphan Buri99Overseas

Job type IDs

IDCategoryIDCategory
1Marketing / PR14Information Technology
2Sales15Accounting
3Customer Service16Human Resources
4Finance17Manufacturing / QC
5Administrative18Purchasing / Supply Chain
7Engineering19Driver / Delivery
10IT / Programming26Secretary
11Architecture28Engineering (Mfg)
12R&D31Overseas

🚀 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

ModeEst. CU cost / 1,000 resultsBilled 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 install
node src/test.js # 25/25 live GraphQL battery
node 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.


Output fields

FieldTypeNotes
titleJob title
companyHiring company
locationLocation
jobTypeJob type
salaryMinMinimum salary
salaryMaxMaximum salary
publishDateDate posted
urlDirect link

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


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.


Need a custom scraper?

Unfenced Group 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