Workable Jobs Scraper
Pricing
from $0.84 / 1,000 results
Workable Jobs Scraper
Jobs from any company's Workable job board (apply.workable.com/<account>) via the public API: title, departments, location(s), on-site/hybrid/remote, employment type, experience, industry, posted date, apply URL and full description. Search by keyword; filter by department, location, remote.
Pricing
from $0.84 / 1,000 results
Rating
0.0
(0)
Developer
Ibnu Adzim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Every open job on any company's Workable job board — Viva.com, Skroutz,
Blueground and the thousands of others hosted at
apply.workable.com/<account> — through Workable's public apply API:
title, departments, location(s) with country code, on-site / hybrid /
remote, employment type, experience level, function, industry, posted
date, apply URL and the full description (requirements and benefits
inline) as text and HTML.
HTTP only, no login, no key, no browser. The list is walked 10 jobs per page by cursor; one extra request per account brings every description.
What it is for
- Company watchlists — a list of accounts on a schedule, diff by
shortcode. - Keyword search across companies —
searchTermsuses Workable's own search, one walk per account × term, de-duplicated. - Remote / department / city slices —
remoteOnlyis server-side;departmentsandlocationsare local substring filters.
Input
| field | what it does |
|---|---|
accounts | Account slugs (viva) or URLs (apply.workable.com/viva/, a job URL under the account). A bare apply.workable.com/j/<shortcode> link carries no account and is refused. |
searchTerms | Sent to Workable's search; empty = whole board. |
departments, locations, remoteOnly | Filters (see #3 below for why two are local). |
includeDescription | On by default; one widget request per account. |
maxItems, maxConcurrency, minRequestInterval, proxyConfiguration | Limits. |
Each account × term gets a BOARD_SUMMARY with Workable's reported total,
the pages walked, how many rows carry a description, what the filters
dropped, and the board's own department and location vocabularies.
Four things about this API worth knowing before you trust a run
1. A bad or stale cursor restarts the walk from page one — with HTTP 200
token=zzzz answers the first page again, with the same nextPage an
untokened call returns. A walker that loops on nextPage alone never
ends. The Actor remembers every cursor and every page's shortcodes; a
repeat stops the walk with stoppedReason: cursor_loop.
2. The legacy widget duplicates multi-location jobs and mislabels a field
The one-call description source (
www.workable.com/api/accounts/<account> ?details=truestate field is the region name ("Attica"), not
the job state. The Actor uses it only for descriptions and taxonomy, first
row per shortcode, and never reads its state; the v3 list is the record
of what exists.
3. The server-side filters are typed, and a string is a 400
department: ["Direct Sales"] → 400 "department[0]" must be a number;
worktype: ["zzqq"] → 400 does not match any of the allowed types. Only
the free-text query and the boolean remote flag are ever sent;
departments / locations are matched locally against the board's own
words (departmentsOnBoard in the summary is the vocabulary).
4. An account with no public jobs is 200 {"total":0}; an unknown account is a bare 404
hotjar, typeform → total 0 (they exist on Workable). zzqqnotanacct →
404 Not Found. Reported as empty_board (or no_matches under a query)
vs account_not_found.
Other things measured
publishedis midnight UTC — date precision only.createdAtcomes from the widget.employmentType(full/part/contract/temporary) is absent on some rows; the widget's label (Full-time) is kept beside it.- A full last page still carries a
nextPage; the page after it is empty.pagesWalkedcan beceil(total/10) + 1. - No throttling or anti-bot layer seen; a page is ~5 KB, the widget ~5 KB per job.
Output
JOB—jobId,shortcode,title,url,applyUrl,departments,employmentType,employmentTypeLabel,workplace,isRemote,location,locationDetail,locations,language,requisitionCode,published,createdAt,experience,education,function,industry,description,descriptionHtml,account,resultPosition.BOARD_SUMMARY—account,boardUrl,query,totalJobsReported,jobsReturned,pagesWalked,rowsWithDescription,widgetRows,stoppedReason(exhausted,max_items,empty_board,no_matches,cursor_loop,max_pages),filteredOut,departmentsOnBoard,locationsOnBoard.ERROR—invalid_input,account_not_found,descriptions_unavailable(widget failed; JOB rows still shipped),payload_shape_changed,fetch_failed, with detail.
Known limits
- Salary is not a field on either endpoint; it appears only inside descriptions when the company writes it.
searchTermsare Workable's search, not a local match; what it indexes is Workable's choice.- Internal / unlisted postings are not served.