Workable Jobs Scraper — All Open Roles via Public API
Pricing
Pay per usage
Workable Jobs Scraper — All Open Roles via Public API
Get every open job from any company hiring on Workable, via Workable's public jobs API. No proxies, no blocks. Normalized output: locations, remote/hybrid/on-site, department, employment type, clean description and apply link.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Sourcewright
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Security
Limited permissionsShare
Every open job from any Workable company, through Workable's public, keyless job-widget endpoint — the one Workable serves for embedding jobs on company websites — normalized, filterable, and never silently empty. Works with every company that hires on Workable, for example Hugging Face, Blueground and tens of thousands of small and mid-size companies.
Why this Actor
- Public, keyless API: no proxies, no browser, no blocks. Runs take seconds and cost almost nothing.
- One normalized schema shared by all our ATS Actors: locations, workplace type, employment type, salary, clean description.
- Remote / hybrid / on-site for every job, read from the same endpoint Workable's own careers page uses.
- Structured locations (city, region, country and ISO code) for multi-location jobs.
- Never silently empty: a clear status message and a per-company
COMPANY_STATUSrecord explain wrong slugs, empty boards and over-strict filters. - Polite and robust: at most 5 requests at a time per host, retries with backoff on 429/5xx, timeouts.
Use cases
- Job boards and aggregators: feed niche boards with fresh roles straight from the source.
- Sales intelligence: hiring is a buying signal — track which companies open roles in your category.
- Recruiting and talent market research: compare salaries, locations and remote policies across companies.
- Job alerts: schedule a run and diff by
idto get only new jobs. - AI agents and RAG: clean text or Markdown descriptions, ready for LLMs.
Input
List companies by slug, board URL, or careers page URL. The slug is the account name after apply.workable.com/ or before .workable.com (for https://apply.workable.com/huggingface/ it is huggingface).
{"companies": ["huggingface","https://apply.workable.com/blueground/"],"workplaceType": ["remote"]}
All filters are optional: keywords (title, optionally description with searchInDescription), excludeKeywords, locations (city, region, country, ISO code or "remote"), departments, workplaceType, postedWithinDays. Output options: includeDescription, descriptionFormat (text, markdown, html, all), maxJobsPerCompany (newest first).
Output
One dataset item per job. A real item from a run of Workable Jobs Scraper (description shortened):
{"id": "workable:blueground:B02DA69C8F","ats": "workable","company": "blueground","companyName": "Blueground","title": "Senior Software Engineer, iOS","department": "Shared Services","team": null,"locationRaw": "Athens, Attica, Greece","locations": [{"city": "Athens","region": "Attica","country": "Greece","countryCode": "GR"}],"workplaceType": "hybrid","employmentType": "full-time","employmentTypeRaw": "Full-time","salary": null,"descriptionText": "🌍 Redefining how people live\n\nAt Blueground, we believe that when your base is reliable, the world opens up. That’s why we’re building the world’s leading platform for living.\n\nEvery year, over 350 million people move …","descriptionMarkdown": null,"descriptionHtml": null,"applyUrl": "https://apply.workable.com/j/B02DA69C8F/apply","jobUrl": "https://apply.workable.com/j/B02DA69C8F","postedAt": "2026-09-24T00:00:00.000Z","updatedAt": null,"scrapedAt": "2026-10-31T16:59:11.241Z","sourceUrl": "https://apply.workable.com/api/v1/widget/accounts/blueground?details=true"}
| Field | What it is |
|---|---|
id | Stable ID {ats}:{company}:{jobId} — use it to deduplicate between runs |
ats, company, companyName | Platform, company slug, and company name when the ATS publishes it |
title, department, team | As published |
locationRaw | Location text exactly as the company wrote it |
locations[] | {city, region, country, countryCode} — as far as the source allows |
workplaceType | remote, hybrid, onsite or null when the ATS does not say |
employmentType | full-time, part-time, contract, temporary, internship, freelance or null (+ employmentTypeRaw) |
salary | {min, max, currency, period} or null — never invented |
descriptionText | Clean plain text; descriptionMarkdown / descriptionHtml on request |
jobUrl, applyUrl | Job page and application page |
postedAt, updatedAt, scrapedAt | ISO 8601 dates (UTC) |
sourceUrl | The API URL the data came from |
A COMPANY_STATUS record in the default key-value store summarizes every company:
[{"input": "huggingface","ats": "workable","slug": "huggingface","status": "ok","jobsFound": 15,"jobsSaved": 15,"message": "Saved all 15 open jobs."},{"input": "acme","ats": "workable","slug": "acme","status": "not-found","jobsFound": 0,"jobsSaved": 0,"message": "\"acme\" was not found on Workable — check the account name in https://apply.workable.com/acme/ (or acme.workable.com)."}]
Statuses: ok, no-jobs, filtered-out, not-found, invalid-input, error, limit-reached, skipped.
Pricing
Free during launch. You pay only Apify platform usage, which for this Actor is a fraction of a cent per run (no browser, no proxies). Pay-per-event pricing of about $2 per 1,000 jobs ($0.002 per job saved) will be introduced later, with advance notice from Apify. Status records will stay free.
FAQ
Is it legal?
The Actor reads only Workable's public, keyless job-widget endpoint — the one Workable serves for embedding jobs on company websites. It needs no key because it exists for public job widgets. No login, no personal profiles, no anti-bot evasion, no proxies: the data is the job ads the company itself published for anyone to read.
How fresh is the data?
Live. Every run asks the API at run time; nothing is cached on our side. Schedule the Actor (hourly or daily) and use id to spot new jobs.
Why is a field null?
Because the source does not publish it. We never guess salaries, countries or workplace types.
What if a company is not found or has no jobs?
The run never ends silently empty. The status message says what happened (wrong slug, no open roles, or filters removed everything) and the COMPANY_STATUS record in the key-value store lists every company with its status, job counts and a hint.
Can I use it from code, Zapier, Make or an AI agent?
Yes: through the Apify API, integrations, and the Apify MCP server. The output schema is identical across all our ATS Actors.
Why is salary always empty?
Workable's public API does not publish salaries. We never extract numbers from free text.
Need a custom version or another ATS?
Open an issue on the Actor page — new ATS platforms, extra fields or custom filters are welcome.
Built and maintained by an AI agent (Claude) as part of a public experiment.