# Workable Jobs Scraper · Company Job Boards, Roles & Locations (`reapx/workable-jobs-scraper`) Actor

Workable Jobs Scraper (Workable ATS scraper) to extract job postings from Workable career boards. Filter by keyword, location, department, and remote status across company job boards.

- **URL**: https://apify.com/reapx/workable-jobs-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Jobs, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.32 / 1,000 job listing returneds

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

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## Workable Jobs Scraper · Company Job Boards, Roles & Locations

**Workable Jobs Scraper** (Workable ATS job scraper) extracts live job postings from Workable-hosted company career pages and job boards. Search Workable jobs by title, keyword, location, department, workplace type (remote, hybrid, on-site), or scrape all open roles from a named company.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/workable-jobs-scraper/](https://reapx.dev/data/workable-jobs-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/workable-jobs-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/workable-jobs-scraper). Questions: reapxdev@proton.me

Extract job title, company name, department, location, employment type, full job description, and apply URL into CSV, JSON, or Excel. Fast HTTP API extraction with no login or API key required.

### Workable Jobs Scraper features

- **Workable ATS Jobs Scraper**: Extract live hiring data across thousands of Workable-powered company job boards.
- **Company & Global Search**: Scrape by keyword and location or target specific company career pages.
- **Rich Job Details**: Output includes company, department, location, workplace mode, dates, and full text descriptions.

### What you get

One row per job, with a stable `jobId` you can use as a primary key:

| Field | Example |
|---|---|
| `title` | Senior Data Engineer |
| `companyName` / `companyWebsite` | CloudFactory / https://cloudfactory.com |
| `city` / `region` / `country` | Berlin / Berlin / Germany |
| `workplace` / `isRemote` | hybrid / false |
| `employmentType` / `department` | Full-time / Engineering |
| `publishedAt` / `publishedDate` | 2026-07-29T10:12:03Z / 2026-07-29 |
| `description` / `requirements` / `benefits` | full text, HTML stripped |
| `jobUrl` | direct link to the posting |

Four named views ship with the dataset: **Jobs overview**, **Remote roles**, **Companies hiring** and **Full text**.

### Search all Workable job boards

Leave **Company job boards** empty and fill in a keyword, a location, or both. Each location you add is searched separately and the results are merged, so one run can compare several markets.

- **Job title or keyword** - matched against title and description
- **Locations** - country or city names, one per line
- **Remote, hybrid or on-site** - filter by how the job is worked
- **Posted within the last N days** - for a feed that stays fresh on a schedule

### Scrape a single company job board

Put a Workable account name into **Company job boards** to get that company's complete list of open roles. The account name is the last part of the careers URL - `apply.workable.com/blueground` is `blueground`. You can name several, and you can combine this with a search.

### Input configuration

Every field is optional. The prefilled values below are what runs if you press Start without changing anything.

#### What to search for

Workable hosts the careers pages of tens of thousands of companies. This section searches all of them at once.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `searchQuery` | string | free text | Words to match against the job title and description across every Workable company board. Leave empty to browse a whole location without a keyword. Prefilled with `"software engineer"`. |
| `locations` | list | one value per line | Country or city names, one per line. Each is searched separately and the results are merged, so you can compare markets in one run. Examples: Germany, United Kingdom, Berlin, Athens. |
| `workplace` | string | `any`, `remote`, `hybrid`, `on_site` | Filter by how the job is worked. 'Any' returns all three. Prefilled with `"any"`. |
| `postedWithinDays` | integer | 1 to 365 | Return only jobs published in the last N days, recomputed on every run. Use 1 for a daily feed or 7 for a weekly one. Leave empty for no date limit. |

#### Or read a company board directly

Name one or more companies to get their complete list of open roles, including any that the search index has not picked up yet. Can be combined with a search above.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `companyBoards` | list | one value per line | Workable account names, one per line, to pull every open role from directly. The account name is the last part of the careers URL: apply.workable.com/blueground → blueground. |

#### Size and detail

How many rows to return and how much of each job description to carry.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `maxJobs` | integer | 1 to 50000 | Hard stop on how many jobs are returned and charged. Each job returned costs $0.002. 100 jobs finishes in well under a minute. Prefilled with `100`. |
| `includeDescription` | true/false | checkbox | Carry the full description, requirements and benefits text on every row, converted from HTML to plain text. Turn off for a smaller, faster dataset that is just the job facts. Prefilled with `true`. |
| `requestDelaySecs` | integer | 1 to 60 | Seconds to wait between requests to Workable. 1 is the minimum this Actor allows; raise it if you are running several jobs at once. Prefilled with `1`. |

### Pricing

Pay per event. The primary event is **Job listing returned** (`job-listing`), charged at **$0.002 per event** on the free plan, falling to $0.00084 on the highest tier.

Charged once for each Workable job delivered as a complete row: title, hiring company, location, workplace type, department, posting date, apply URL and full description text. Queries that match nothing, sources that are unreachable and blocked requests are never charged.

Other charged events: `apify-actor-start` (Actor Start).

Minimum charge cap per run: $0.005.

Tiered discounts apply automatically on every paid Apify plan. Platform usage is absorbed by the Actor, so the per-event price is the whole price.

### Usage examples

#### The prefilled run, which is what Start does with nothing changed

```json
{
  "searchQuery": "software engineer",
  "workplace": "any",
  "maxJobs": 100,
  "includeDescription": true,
  "requestDelaySecs": 1
}
```

#### Filter by job title or keyword

```json
{
  "searchQuery": "data engineer",
  "workplace": "any",
  "maxJobs": 100,
  "includeDescription": true,
  "requestDelaySecs": 1
}
```

#### Filter by locations

```json
{
  "searchQuery": "software engineer",
  "workplace": "any",
  "maxJobs": 100,
  "includeDescription": true,
  "requestDelaySecs": 1,
  "locations": [
    "Germany",
    "Netherlands"
  ]
}
```

#### Filter by remote, hybrid or on-site

```json
{
  "searchQuery": "software engineer",
  "workplace": "remote",
  "maxJobs": 100,
  "includeDescription": true,
  "requestDelaySecs": 1
}
```

#### Filter by posted within the last n days

```json
{
  "searchQuery": "software engineer",
  "workplace": "any",
  "maxJobs": 100,
  "includeDescription": true,
  "requestDelaySecs": 1,
  "postedWithinDays": 7
}
```

### Output example

One row, exactly as the actor wrote it to the dataset:

```json
{
  "jobId": "97df109d-c25f-439d-92bf-0668d25ce16b",
  "jobUrl": "https://jobs.workable.com/view/jKHw6veRjY9WhtJgPvzkTr/hybrid-applied-mathematician-in-cologne-at-circonomit",
  "title": "Applied Mathematician",
  "companyName": "Circonomit",
  "companyId": "e5c1c9fd-8809-4db4-a456-ae053e8811e5",
  "companyWebsite": "https://www.circonomit.com/",
  "companyBoard": null,
  "department": null,
  "employmentType": "Full-time",
  "workplace": "hybrid",
  "isRemote": false,
  "city": "Cologne",
  "region": "North Rhine-Westphalia",
  "country": "Germany",
  "locations": [
    "Cologne, North Rhine-Westphalia, Germany"
  ],
  "language": "en",
  "isFeatured": false,
  "publishedAt": "2026-08-02T17:20:29.932Z"
}
```

That row carries 27 fields in total; 18 are shown.

#### Fields on every row

| Field | Type | What it is |
| --- | --- | --- |
| `jobId` | string | Stable Workable identifier for this job. A UUID for search results, a short alphanumeric code for company-board results. Unique per job and safe to use as a primary key. |
| `jobUrl` | string | Public page for this job posting. |
| `title` | string | Job title exactly as the employer published it. |
| `companyName` | string | Name of the hiring company. |
| `companyId` | string | Workable identifier for the hiring company. Present on search results; null on company-board results. |
| `companyWebsite` | string | The company's own website, when Workable holds one. |
| `companyBoard` | string | The Workable account name the row came from. Populated only for rows read directly from a named company board. |
| `department` | string | Internal department or team the role sits in. |
| `employmentType` | string | Contract shape of the role as published by the employer. |
| `workplace` | string | Whether the role is remote, hybrid or on-site. |
| `isRemote` | true/false | True when the role is fully remote. |
| `city` | string | Primary city for the role. |
| `region` | string | Region, state or province for the role. |
| `country` | string | Country the role is based in. |
| `locations` | list | Every location the role is offered in, as published. Roles are often open in several cities at once. |
| `language` | string | Language the posting is written in, as an ISO code. |
| `isFeatured` | true/false | True when Workable is promoting this posting in search results. |
| `publishedAt` | string | When the posting first went live, ISO 8601. |
| `publishedDate` | string | Publication date only, YYYY-MM-DD, for grouping and filtering. |
| `updatedAt` | string | When the posting was last changed, ISO 8601. |
| `summary` | string | Short share-card summary of the role, when the employer supplied one. |
| `description` | string | Full job description as plain text, converted from the employer's HTML. Null when 'Include the full job description' is turned off. |
| `requirements` | string | The requirements section as plain text, when the employer published it separately. |
| `benefits` | string | The benefits section as plain text, when the employer published it separately. |
| `sourceType` | string | Which Workable surface the row came from. |
| `sourceQuery` | string | The resolved query that produced this row, so a merged dataset stays traceable. |
| `scrapedAt` | string | When this Actor read the row from Workable, ISO 8601. |

4 named dataset views ship with it: **Jobs overview**, **Remote roles**, **Companies hiring**, **Full text**. They drive the Output tab in Console and the Output block on the Actor's `.md` page.

### FAQ

#### How do I find a company's Workable account name?

Open the company's careers page. If it is hosted by Workable the URL looks like `apply.workable.com/acme` or `acme.workable.com` - `acme` is the account name.

#### Can I scrape only remote jobs?

Yes. Set **Remote, hybrid or on-site** to *Remote only*. Every row also carries an `isRemote` boolean and a `workplace` value.

#### How many jobs can one run return?

Up to 50,000. The search index serves 20 jobs per page and this Actor pages through automatically until it reaches your limit.

#### How fresh is the data?

It is read live on every run. Use **Posted within the last N days** with a scheduled run to build a daily or weekly feed of new postings only.

#### Does it need a Workable login or API key?

No. Only public job board data is read.

#### Can I use this from an AI agent?

Yes. The dataset schema types and documents every field, so the output chains directly into agent workflows through the Apify MCP server.

***

Unofficial - not affiliated with Workable. Collects public data only. reapx. Contact reapxdev@proton.me.

### The full published archive

- **[workable jobs scraper archive](https://reapx.dev/data/workable-jobs-scraper/)** — every entity this Actor has observed
- **[All reapx datasets](https://reapx.dev/data/)** — 20 sources, tens of thousands of pages
- **[llms.txt](https://reapx.dev/llms.txt)** · **[feed.json](https://reapx.dev/feed.json)** ·
  **[feed.xml](https://reapx.dev/feed.xml)** — the machine-readable index, for agents

Each archive page carries Dataset JSON-LD, a canonical URL and the identifiers used, so an agent
can resolve an entity without running anything. Nothing on those pages is estimated or modelled.

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "workplace": "hybrid",
  "includeDescription": true,
  "requestDelaySecs": 1,
  "locations": [
    "Germany",
    "United Kingdom",
    "Netherlands"
  ],
  "maxJobs": 300
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "jobId": "97df109d-c25f-439d-92bf-0668d25ce16b",
  "jobUrl": "https://jobs.workable.com/view/jKHw6veRjY9WhtJgPvzkTr/hybrid-applied-mathematician-in-cologne-at-circonomit",
  "title": "Applied Mathematician",
  "companyName": "Circonomit",
  "companyId": "e5c1c9fd-8809-4db4-a456-ae053e8811e5",
  "companyWebsite": "https://www.circonomit.com/",
  "companyBoard": null,
  "department": null,
  "employmentType": "Full-time",
  "workplace": "hybrid",
  "isRemote": false,
  "city": "Cologne",
  "region": "North Rhine-Westphalia",
  "country": "Germany",
  "locations": [
    "Cologne, North Rhine-Westphalia, Germany"
  ],
  "language": "en",
  "isFeatured": false,
  "publishedAt": "2026-08-02T17:20:29.932Z",
  "updatedAt": "2026-08-02T17:20:29.932Z",
  "publishedDate": "2026-08-02",
  "summary": "We are building the world&#39;s decision infrastructure: the strategic twin of every industrial organization for complex combinatorial problems. We unlocked what wasn&#39;t possible before: mapping reality with its levers and constraints into a compute...",
  "description": "We are building the world's decision infrastructure: the strategic twin of every industrial organization for complex combinatorial problems. We unlocked what wasn't possible before: mapping reality with its levers and constraints into a computer, then running n-dimensional optimization on critical value-chain decisions. We help Europe stay strong and the German Mittelstand make good decisions between market shifts, orders, machines and people.\nFounded by Dana (CEO) and Erik (CTO) from RWTH research, backed by a €2.8M round led by Vorwerk Ventures, with customers live on our optimization models.\nWe move fast. We care. No patience for problems left unsolved.\nYour mission\nHi, I'm Erik, CTO of Circonomit. This ad is specific on purpose: you should be able to tell from it whether this is your job.\nWe build decision infrastructure for industrial companies: our customers model their production, with its capacities, costs and constraints, and we compute the answer to \"what should we do?\" before the decision is made. Our engine turns that model into one artifact that both evaluates like a spreadsheet and optimizes like a solver. It sits between two worlds: the mathematics that makes the answer correct, and the product that has to make it usable by people who are not mathematicians.\nThe mathematics half of that bridge is yours; our engineers own the other. You also model real customer problems on it, because that is how you learn what the engine has to provide next.\nWe will not sugarcoat it: combinatorial search is unpredictable, customer data arrives messy, and some weeks a deadline sets the priority.\nWhat you'll own\nThe mathematics behind the models.  A model means exactly one thing, and it still means that after it reaches a solver. The algebra underneath is yours, and so is the call on what the engine should be able to express next and what it should refuse.\nCustomer models, end to end.  Turn a planning problem, with its capacities, costs, lead times and shift plans, into a model whose answer a plant manager acts on. That includes the data it runs on: ERP and Excel exports, and
```

### How it works

1. You set the filters below, or none at all.
2. The Actor calls the source's own public endpoint and pages through the results.
3. Every row is pushed to the dataset **as it is built**, not buffered to the end — so a
   run that hits its time limit still returns everything it collected up to that point.
4. You are charged per row returned, so the maximum-results field is also your cost cap.

### 💬 Your feedback

Found a bug, or need a field this does not return yet? Open an issue on the Actor's **Issues**
tab, or write to **reapxdev@proton.me**. Bugs get fixed and reasonable field requests get
added.

# Actor input Schema

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

Words to match against the job title and description across every Workable company board. Leave empty to browse a whole location without a keyword.

## `locations` (type: `array`):

Country or city names, one per line. Each is searched separately and the results are merged, so you can compare markets in one run. Examples: Germany, United Kingdom, Berlin, Athens.<br><br>Leave this field empty to include every option.

## `workplace` (type: `string`):

Filter by how the job is worked. 'Any' returns all three.<br><br>Options: <code>any</code>, <code>remote</code>, <code>hybrid</code>, <code>on\_site</code>.

## `postedWithinDays` (type: `integer`):

Return only jobs published in the last N days, recomputed on every run. Use 1 for a daily feed or 7 for a weekly one. Leave empty for no date limit.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `companyBoards` (type: `array`):

Workable account names, one per line, to pull every open role from directly. The account name is the last part of the careers URL: apply.workable.com/blueground → blueground.<br><br>Leave this field empty to include every option.

## `maxJobs` (type: `integer`):

Hard stop on how many jobs are returned and charged. Each job returned costs $0.002. 100 jobs finishes in well under a minute.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `includeDescription` (type: `boolean`):

Carry the full description, requirements and benefits text on every row, converted from HTML to plain text. Turn off for a smaller, faster dataset that is just the job facts.

## `requestDelaySecs` (type: `integer`):

Seconds to wait between requests to Workable. 1 is the minimum this Actor allows; raise it if you are running several jobs at once.

## Actor input object example

```json
{
  "searchQuery": "data engineer",
  "locations": [
    "Germany",
    "Netherlands"
  ],
  "workplace": "remote",
  "postedWithinDays": 7,
  "companyBoards": [
    "blueground",
    "skroutz"
  ],
  "maxJobs": 500,
  "includeDescription": true,
  "requestDelaySecs": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

Role, company, location and date - the columns most runs are read for.

## `remote` (type: `string`):

Every row with its remote flag and location, for filtering distributed hiring.

## `companies` (type: `string`):

Company-level columns, for lead lists and market maps.

## `full` (type: `string`):

Description, requirements and benefits, for analysis and LLM pipelines.

## `results` (type: `string`):

Every record this run produced, with all fields and no view applied. Field-level titles, types, descriptions and examples are declared in the dataset schema.

# 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 = {
    "searchQuery": "software engineer",
    "workplace": "any",
    "maxJobs": 100,
    "includeDescription": true,
    "requestDelaySecs": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/workable-jobs-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 = {
    "searchQuery": "software engineer",
    "workplace": "any",
    "maxJobs": 100,
    "includeDescription": True,
    "requestDelaySecs": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/workable-jobs-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 '{
  "searchQuery": "software engineer",
  "workplace": "any",
  "maxJobs": 100,
  "includeDescription": true,
  "requestDelaySecs": 1
}' |
apify call reapx/workable-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MqR3xNYktTFGL8J9m/builds/eVXwGgVAakup4uHo8/openapi.json
